Страницы с тегами : Architecture

Host-Named SiteCollections

В SharePoint 2013 без большого шума появилась новая best-practice, рекомендующая использовать так называемые Host-Named SiteCollection (HNSC). Как обычно это вызывает множество вопросов, на которые я попробую ответить.

Краткий экскурс в историю

Во времена x86 процессоров максимальный объем адресного пространства, которое могло занимать приложение – 2гб. Поэтому для масштабирования был выбран подход, когда вся ферма SharePoint разбивается на несколько “веб-приложений”, каждое из которых представляет один или несколько сайтов на IIS. Тем не менее создание сайтов на IIS – дорогое удовольствие. Каждый сайт запускает как минимум один процесс w3wp, который загружает сборки SharePoint и съедает немало памяти. Поэтому даже придумали лимит веб-приложений.

Еще один фактор, который подталкивает плодить веб-приложения в SharePoint – безопасность. Каждое веб-приложение содержит множество коллекций сайтов, все имеют общий hostname. Это значит что javascript из одной коллекции сайтов может обращаться к ресурсам другой коллекции с правами текущего пользователя (Cross-Site Scripting). А для добавления JavaScript достаточно иметь права хотя бы на одно узле.

Таким образом даже появление x64 версий SharePoint не изменило картину – все использовали веб-приложения и отдельные сайты IIS.

HNSC существовали еще в SharePoint 2003 (только назывались не так). Они позволяли иметь коллекции сайтов с разными hostname в рамках одного веб-приложения SharePoint. Но из-за ограничений и сложностей использования не прижились. В SharePoint 2010 произошло улучшение HNSC в первую очередь для Office 365.

В SharePoint 2013 снова улучшили HNSC и появились некоторые возможности\особенности платформы, которые делают HNSC лучшим выбором.

Для чего нужны HNSC

Обязательно нужно запомнить (ибо понять это сложно): Host-Named SiteCollection это альтернатива веб-приложениям, а не обычным коллекциям сайтов. При использовании HNSC обычные коллекции сайтов, официально называемые Path-Based SiteCollection, все так же доступны.

Как я писал выше, HNSC позволяют создавать коллекции сайтов с разными hostname в рамках одного веб-приложения. В SharePoint 2013 HNSC также научлись поддерживать несколько hostname в разных зонах и SSL Termination и разные режимы аутентификации на основе зон.

С точки зрения API обычные коллекции сайтов не отличаются от HNSC. Важно только помнить что SPSite.Url  может не совпадать ни с одним из Url в объекте SPSite.WebApplication.

Применять HNSC нужно по трем причинам:

  1. Экономия ресурсов.
    Все HNSC живут в одном веб-приложении, следовательно в одном процессе w3wp. Это означает, что загружена только одна копия сборок SharePoint, что уменьшает оверхед на пару сотен мегабайт на процесс.
  2. Совместимость с apps.
    Для того чтобы работали apps нужен wildcard-сайт, который принимает запросы на любой hostname, потому что AppWeb создается с уникальным hostname.
    Но AppWeb это все еще сайт SharePoint, поэтому требуется загрузка всех объектов SharePoint в процесс веб-сайта, обсуживающего apps.
    Если все коллекции сайтов находятся в одном сайте IIS, то это также уменьшает оверхед и упрощает, в итоге, настройку IIS.
  3. Новые фичи SharePoint 2013.
    В SharePoint 2013 появилась фича Request Management, позволяющая управлять WFE. Request Management позволяет задать какой WFE будет обрабатывать запросы какого типа. Конфигурация может быть динамической, учитывающей состояние сервера (нагрузка, ресурсы итд). Microsoft говорит что эта фича тестировалась только с HNSC и в будущем новые фичи будут работать в первую очередь с HNSC.

Недостатки HNSC

Увы использовать HNSC не так просто. Central administration сайт не умеет создавать HNSC, поэтому всю работу надо будет делать в PowerShell.

Тем не менее для любителей тикать мышкой есть проект на codeplex: https://hnsc.codeplex.com/https://hnsc.codeplex.com/.

Кроме того HNSC обеспечивают гораздо меньшую изоляцию ресурсов сервера, по сравнению с веб-приложениями. Все HNSC будут иметь общие настройки веб-приложения, такие как throttling, настройки корзины, настройки безопасности и аутентификации, общие managed paths, итд. У всех HNSC будет общий web.config и общий app pool. Это значит что установка приложений будет затрагивать все HNSC.

Как создавать HNSC

Я не буду писать множество PowerShell команд для создания и настройки HNSC. На MSDN есть прекрасный гайд по HNSC (даже с достойным переводом на русский язык), который описывает разные топологии, а также процесс перехода от Path-based sitecollections к HNSC.

Ссылка на гайд: http://technet.microsoft.com/ru-ru/library/cc424952.aspx.

Дополнительные материалы для тех, кто решит использовать HNSC:

Заключение

Для правильного развертывания SharePoint 2013 уже недостаточно просто воспользоваться визардом. Теперь требуется планирование, анализ требований, вариантов решений которые предлагает SharePoint и оценка всех tradeoffs. А это требует как минимум понимания возможностей SharePoint.



Как работает развертывание решений в SharePoint

Развертывание решений SharePoint - это нескончаемый источник ошибок, слухов и легенд. Причина этому простая – процесс деплоймента (и отката) решений практически никак не документирован. Начиная с SharePoint 2010 ситуация усложнилась появлением sandbox solutions и механизмом апгрейда фич.

Общая схема

(взято отсюда)

По пунктам:

  • WSP пакет сначала попадает в конфигурационную базу
  • При развертывании файлы из пакета попадают на компьютеры фермы, это касается фич, сборок и файлов приложения.
  • При активации фич на основе манифеста в контентной базе создаются записи, которые ссылаются на файлы на диске.

Такая схема была изобретена в ранних версиях SharePoint, чтобы экономить место в базе, если одна и та же функциональность используется на многих сайтах. Кроме того так очень удобно обновлять, достаточно развернуть новую версию пакета и все сайты получат изменения.

На практике такая схема работает плохо...

Проблемы

Когда артефакты (файлы, поля, типы контента, списки) создаются таким образом, как описано выше, они называются ghosted (в SharePoint 2007) или uncustomized (с SharePoint 2010).

Проблемы начинаются тогда, когда файлы\поля\типы\списки изменяются. Когда это происходит в базу записывается схема (XML определение) или сам обновленный файл, а связь с файлом на диске теряется. Это состояние называется unghosted или customized. Дальнейшее обновление путем обновления файлов на диске уже перестает работать.

Ситуация усугубляется тем, что деактивация фич не удаляет списки и файлы и не удаляет типы контента и поля, на которые ссылаются списки. Повторная активация фич, при наличии артефактов в контентной базе, работает совершенно непредсказуемо.

Это кстати одна из базовых ошибок дизайна feature framework, из-за которой весь деплоймент стал невероятно сложным. Если бы деактивация фич удаляла все артефакты и при удалении решения фичи деактивировались, то делать решения стало бы гораздо легче. Но в 2007 году об этом не подумали и сделали выбор в пользу сохранения данных, а не контролируемости развертывания.

Можно, конечно, все артефакты создавать с помощью XML, избегая кода, который вызывает кастомизацию. Но далеко не все решения можно делать таким образом. Многие вещи, вроде таксономии, audience targeting и metadata mavigation в XML описать очень сложно. Но самое главное, что кастомизация может быть вызвана пользователем. А если возможность кастомизации заблокировать, то теряется гибкость, которую дает SharePoint.

Еще одна проблема связана со списками и шаблонами (определениями) списков. Если список создан по шаблону и не кастомизирован, но шаблон отсутствует на диске, то появляется множество непонятных ошибок при использовании API и некоторых стандартных функций.

Из-за этих проблем многие полностью отказались от развертывания артефактов с помощью XML определений и начали делать создание артефактов с помощью кода. Этот подход гораздо более многословен и повышает вероятность ошибок, но при этом дает контролируемость процесса при создании, и самое важное, при обновлении артефактов.

SharePoint 2010 и Sandbox

Естественно в Microsoft обо всех этих проблемах знали и в 2010 версии сделали некоторые изменения, которые должны были улучшить ситуацию.

Первое изменение – добавление флагов Overwrite в определениях полей и типов контента. С этим флагом поля и типы при активации фичи записываются в контентную базу, без создания привязки к файлам на диске. Кроме того стала возможна повторная активация фич при наличии артефактов в контентной базе данных. Это частично решает проблему, но только частично, так как проблема со списками, созданными из шаблонов, не решается.

Второе изменение – добавление возможности апгрейда фич. Теперь можно не удалять решение и не переактивировать фичи для получения новой функциональности.

Третье изменение – появление Sandbox решений, которые не используют файлы в файловой системе и создают все артефакты сразу в контентной базе. При этом откат Sandbox решения вызывает деактивацию всех фич, а для FullTrust такого не происходит.

Казалось бы теперь можно сделать то что нужно, используя правильные возможности. Но вышла еще одна промашка – все изменения почти никак не документированы и процесс развертывания стал еще более непредсказуемый и вообще сложилась ситуация когда никто не знает как делать правильно.

В SharePoint 2013 кстати тоже произошли небольшие улучшения, но снова почти не документированные.

Что же делать

Вариант первый – делать все кодом. К сожалению кода получается очень много и писать его очень муторно. Некоторые вещи сделать кодом сложно, некоторые вообще невозможно.

Вариант второй – делать развертывание в XML, не деактивировать фичи (особенно если ведет к потерям данных или к нарушению работоспособности), не откатывать решение, использовать feature upgrade. Это тоже требует написания кода, но в гораздо меньшем объеме.

Кстати использовать активацию фич для поставки функционала пользователю – тоже не лучший вариант. Гораздо лучше:

  1. Создание сайтов по шаблону.
  2. Создание списков по шаблону.
  3. Дополнительными пунктами в меню администрирования (для сайтов, списков, типов контента).
  4. Расширением существующего функционала.

Сам фичи лучше всего делать скрытыми, активировать их автоматически при развертывании решения или скриптом установки.

Если же делаете фичу видимой, то нужно всегда тестировать возможность её многократной активации\деактивации, в том числе на разных сайтах и коллекциях сайтов.

Заключение

Если вы работаете с SharePoint, то вам в любом случае необходимо знать как работает развертывание артефактов. Узнать это можно типовым для SharePoint способом – ковырянием сборок в ILSpy или Reflector. Большую часть из того, что я описал в этом посте я узнал именно из сборки Microsoft.SharePoint.

В следующий раз расскажу как пользоваться работает feature upgrade и как быстро создавать решения в SharePoint.



Блеск и нищета Task Parallel Library

Task Parallel Library (пространство имен System.Threading.Tasks) появилась еще в .NET 4, но большой популярностью не пользовалась. На подходе компилятор C# 5, который поддерживает конструкцию async\await. В скомпилированом коде async метод превращается в метод возвращающий Task\Task<T>.  Поэтому в скором времени использование TPL станет повсеместным.

Task Parallel Library – имеет очень мощные механизмы: вложенные (nested) задачи, локальные очереди для потоков, чтобы уменьшить латентность, work-stealing алгоритмы для работы, кучи опций запуска задач и продолжений, различные планировщики. Все создано в лучших традициях оптимизации асинхронного кода.

Но, TPL создавался до мозга костей практиками и цели сделать библиотеку удобной для потребителей даже не ставилось судя по всему.

  1. Как это не смешно, то в стандартной библиотеке нету метода, позволяющего обернуть значение T в Task<T>. (Только в .NET 4.5 появился Task.FromResult)
  2. Сам объект Task представляет из себя “задачу”, которая может быть как еще не запущена, так и уже выполняться.  Поэтому работа с разными Task_ами будет осуществляться по-разному.
  3. Task не является immutable объектом, метод ContinueWith изменяет саму задачу.
  4. Функция ContinueWith срабатывает при любом завершении задачи, в том числе отмене или ошибке. Необходимо каждый раз указывать флаги.
  5. Исключения внутри задач собираются в один объект, что затрудняет структурированную их обработку.
  6. Метод ContinueWith принимает Func<Task, T>, а не Func<Task, Task>. Это значит что единственный способ связать две задачи – создать вложенную (nested), что может привести к переполнению стека при завершении цепочки вложенных задач.

Последний пункт особенно актуален.  Даже был сделан extension-метод Unwrap, который позволяет писать код в виде:

var task = SomeFuncReturningTask(...)
                .ContinueWith(t => SomeOtherFuncReturningTask(t.Result))
                .Unwrap().ContinueWith(...)
                .Unwrap().ContinueWith(...);


Layered Architecture

Что такое “слоеная” архитектура многие себе представляют. Вкратце – все компоненты разделяем на некоторые логические слои, уменьшая связность между слоями. Но вот мало кто может сказать по какому принципу разделять слои и строить между ними взаимодействие.

У меня давно зрел принцип разделения на слои, который я не мог выразить словами. Прочитав вот этот пост я нашел правильную формулировку:

Никакие правки верхнего слоя никак не могут повлиять на нижний.

То есть если вам понадобилось в UI добавить новую форму или сделать в списке настраиваемую сортировку, то это никак не должно повлиять на слои логики и доступа к данным. ( вопрос в зал: ваши приложения соответствуют этому принципу?)