Поделиться через


Опрос изменений с помощью USNChanged

Элемент управления DirSync является мощным и эффективным, но имеет два существенных ограничения:

  • Только для приложений с высоким уровнем привилегий. Чтобы использовать элемент управления DirSync, приложение должно выполняться под учетной записью, которая имеет права SE_SYNC_AGENT_NAME на контроллере домена. Немногие учетные записи настолько привилегированны, поэтому приложение, использующее элемент управления DirSync, не может выполняться обычными пользователями.
  • Нет области поддерев: элемент управления DirSync возвращает все изменения, происходящие в контексте именования. Приложение, интересующееся только изменениями, которые происходят в небольшом поддереве контекста именования, должны пройти через множество неуместных изменений, которые неэффективны как для приложения, так и для контроллера домена.

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

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

Атрибут uSNChanged не реплика, поэтому чтение атрибута uSNChanged объекта на двух разных контроллерах домена обычно дает разные значения.

Например, атрибут uSNChanged можно использовать для отслеживания изменений в поддереве S. Сначала выполните полную синхронизацию поддерев S. Предположим, что наибольшее значение uSNChanged для любого объекта в S. Периодически запрашивает все объекты в поддереве S, значение uSNChanged больше U. Запрос вернет все объекты, которые изменились с момента полной синхронизации. Задайте для вас наибольшее значение uSNChanged среди этих измененных объектов, и вы готовы повторно провести опрос.

Ниже представлены тонкости реализации приложения синхронизации uSNChanged:

  • Используйте атрибут rootDSE для привязки фильтров uSNChanged с помощью атрибута highestCommittedUSN. То есть перед началом полной синхронизации считывание самого высокого уровняUSN связанного контроллера домена. Затем выполните полный запрос синхронизации (с помощью страничных результатов), чтобы инициализировать базу данных. По завершении сохраните значение самого высокого значенияCommittedUSN до полного запроса синхронизации; чтобы использовать в качестве нижних границ атрибута uSNChanged для следующей синхронизации. Позже, чтобы выполнить добавочную синхронизацию, перечитайте атрибут rootDSE самого высокого уровняCommittedUSN . Затем запросите соответствующие объекты с помощью страничных результатов, результаты которого uSNChanged больше нижней границы значения атрибута uSNChanged, сохраненного из предыдущей синхронизации. Обновите базу данных с помощью этих сведений. По завершении обновите нижние границы атрибута uSNChanged из значения самого высокого значенияCommittedUSN перед добавочным запросом синхронизации. Всегда храните нижние границы значения атрибута uSNChanged в том же хранилище, что приложение синхронизируется с содержимым контроллера домена.

    Следуя этой процедуре, а не на основе значений uSNChanged на извлеченных объектах, избегайте повторного получения обновленных объектов сервера, которые выходят за пределы набора, применимого к приложению.

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

  • Приложение должно определить, когда контроллер домена в настоящее время связан с резервным копированием, так как это может привести к несоответствию. Если приложение является филиалом с контроллером домена, он кэширует идентификатор вызова этого контроллера домена в стабильном хранилище, то есть то же хранилище, что и в соответствии с содержимым контроллера домена. Идентификатор вызова контроллера домена — это GUID, хранящийся в атрибуте invocationID объекта службы контроллера домена. Чтобы получить различающееся имя объекта службы контроллера домена, ознакомьтесь с атрибутом dsServiceName rootDSE.

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

  • Используйте разбиение на разбиение по страницам при запросе сервера, как полных, так и добавочных синхронизаций, чтобы избежать возможности одновременного получения больших результирующих наборов. Дополнительные сведения см. в разделе "Указание других параметров поиска".

  • Выполните запросы на основе индекса, чтобы избежать принудительного хранения сервера больших промежуточных результатов при использовании страничных результатов. Дополнительные сведения см. в разделе "Индексированные атрибуты".

  • Как правило, не используйте сортировку результатов поиска на стороне сервера, что может принудительно хранить и сортировать большие промежуточные результаты. Это относится как к полным, так и добавочным синхронизациям. Дополнительные сведения см. в разделе "Указание других параметров поиска".

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

  • Для обработки перемещаемых или удаленных объектов сохраните атрибут objectGUID каждого отслеживаемого объекта. Атрибут objectGUID объекта остается неизменным независимо от того, где он перемещается по лесу.

  • Для обработки перемещаемых объектов выполните периодические полные синхронизации или увеличьте область поиска и отфильтруйте неинтересные изменения в конце клиента.

  • Чтобы обрабатывать удаленные объекты, периодически выполняйте полную синхронизацию или выполняйте отдельный поиск удаленных объектов при добавочной синхронизации. При запросе удаленных объектов извлеките объект objectGUID удаленных объектов, чтобы определить объекты для удаления из базы данных. Дополнительные сведения см. в разделе "Извлечение удаленных объектов".

  • Помните, что результаты поиска включают только объекты и атрибуты, которые вызывающий объект имеет разрешение на чтение (на основе дескрипторов безопасности и списков DACLs на различных объектах). Дополнительные сведения см. в разделе "Влияние безопасности на запросы".

Дополнительные сведения и пример кода, показывающий основы приложения синхронизации USNChanged, см. в примере кода для извлечения изменений с помощью USNChanged.