Compartilhar via


Sondagem para alterações usando USNChanged

O controle DirSync é poderoso e eficiente, mas tem duas limitações significativas:

  • Somente para aplicativos altamente privilegiados: para usar o controle DirSync, um aplicativo deve ser executado em uma conta que tenha o privilégio SE_SYNC_AGENT_NAME no controlador de domínio. Poucas contas são tão altamente privilegiadas, portanto, um aplicativo que usa o controle DirSync não pode ser executado por usuários comuns.
  • Sem escopo de subárvore: O controle DirSync retorna todas as alterações que ocorrem em um contexto de nomenclatura. Um aplicativo interessado apenas em alterações que ocorrem em uma pequena subárvore de um contexto de nomenclatura deve passar por muitas alterações irrelevantes, o que é ineficiente tanto para o aplicativo quanto para o controlador de domínio.

As alterações do Active Directory também podem ser obtidas consultando o atributo uSNChanged , que evita as limitações do controle DirSync. Essa alternativa não é melhor do que o controle DirSync em todos os aspectos, pois envolve a transmissão de todos os atributos quando qualquer atributo é alterado e requer mais trabalho do desenvolvedor do aplicativo para lidar com determinados cenários de falha corretamente. É, atualmente, a melhor maneira de escrever certos aplicativos de controle de alterações.

Quando um controlador de domínio modifica um objeto, ele define o atributo uSNChanged desse objeto como um valor maior que o valor anterior do atributo uSNChanged para esse objeto e maior que o valor atual do atributo uSNChanged para todos os outros objetos mantidos nesse controlador de domínio. Como consequência, um aplicativo pode localizar o objeto alterado mais recentemente em um controlador de domínio localizando o objeto com o maior valor uSNChanged . O segundo objeto alterado mais recentemente em um controlador de domínio terá o segundo maior valor uSNChanged e assim por diante.

O atributo uSNChanged não é replicado, portanto, a leitura do atributo uSNChanged de um objeto em dois controladores de domínio diferentes normalmente fornecerá valores diferentes.

Por exemplo, o atributo uSNChanged pode ser usado para controlar alterações em uma subárvore S. Primeiro, execute uma "sincronização completa" da subárvore S. Suponha que o maior valor uSNChanged para qualquer objeto em S seja U. Consulte periodicamente todos os objetos na subárvore S cujo valor uSNChanged seja maior que U. A consulta retornará todos os objetos que foram alterados desde a sincronização completa. Defina você como o maior uSNChanged entre esses objetos alterados e você estará pronto para sondar novamente.

As sutilezas da implementação de um aplicativo de sincronização uSNChanged incluem:

  • Use o atributo highestCommittedUSN do rootDSE para vincular seus filtros uSNChanged . Ou seja, antes de iniciar uma sincronização completa, leia o highestCommittedUSN do seu controlador de domínio afiliado. Em seguida, execute uma consulta de sincronização completa (usando resultados paginados) para inicializar o banco de dados. Quando isso for concluído, armazene o valor CommittedUSN mais alto lido antes da consulta de sincronização completa, para usar como os limites inferiores do atributo uSNChanged para a próxima sincronização. Posteriormente, para executar uma sincronização incremental, releia o atributo rootDSE highestCommittedUSN . Em seguida, consulte objetos relevantes, usando resultados paginados, cujo uSNChanged é maior que os limites inferiores do valor do atributo uSNChanged salvo da sincronização anterior. Atualize o banco de dados usando essas informações. Quando concluído, atualize os limites inferiores do atributo uSNChanged do valor mais altoCommittedUSN lido antes da consulta de sincronização incremental. Sempre armazene os limites inferiores do valor do atributo uSNChanged no mesmo armazenamento que o aplicativo está sincronizando com o conteúdo do controlador de domínio.

    Seguir esse procedimento, em vez daquele baseado em valores uSNChanged em objetos recuperados, evita fazer com que o servidor reexamine objetos atualizados que estão fora do conjunto aplicável ao aplicativo.

  • Como uSNChanged é um atributo não replicado, o aplicativo deve se vincular ao mesmo controlador de domínio sempre que for executado. Se ele não puder se vincular a esse controlador de domínio, ele deverá aguardar até que possa fazer isso ou se afiliar a algum novo controlador de domínio e executar uma sincronização completa com esse controlador de domínio. Quando o aplicativo se afilia a um controlador de domínio, ele registra o nome DNS desse controlador de domínio no armazenamento estável, que é o mesmo armazenamento que ele está mantendo consistente com o conteúdo do controlador de domínio. Em seguida, ele usa o nome DNS armazenado para vincular ao mesmo controlador de domínio para sincronizações subsequentes.

  • O aplicativo deve detectar quando o controlador de domínio ao qual ele está afiliado no momento foi restaurado a partir do backup, pois isso pode causar inconsistência. Quando o aplicativo se afilia a um controlador de domínio, ele armazena em cache a "ID de invocação" desse controlador de domínio no armazenamento estável, ou seja, o mesmo armazenamento que ele está mantendo consistente com o conteúdo do controlador de domínio. A "id de invocação" de um controlador de domínio é um GUID armazenado no atributo invocationID do objeto de serviço do controlador de domínio. Para obter o nome distinto do objeto de serviço de um controlador de domínio, leia o atributo dsServiceName do rootDSE.

    Lembre-se de que, quando o armazenamento estável do aplicativo é restaurado a partir do backup, não há problemas de consistência porque o nome do controlador de domínio, a ID de invocação e os limites inferiores do valor do atributo uSNChanged são armazenados com os dados sincronizados com o conteúdo do controlador de domínio.

  • Use a paginação ao consultar o servidor, sincronizações completas e incrementais, para evitar a possibilidade de recuperar grandes conjuntos de resultados simultaneamente. Para obter mais informações, confira Especificar outras opções de pesquisa.

  • Execute consultas baseadas em índice para evitar forçar o servidor a armazenar grandes resultados intermediários ao usar resultados paginados. Para obter mais informações, confira Atributos indexados.

  • Em geral, não use a classificação do lado do servidor dos resultados da pesquisa, o que pode forçar o servidor a armazenar e classificar resultados intermediários grandes. Isso se aplica a sincronizações completas e incrementais. Para obter mais informações, confira Especificar outras opções de pesquisa.

  • Não lide com nenhuma condição pai normalmente. O aplicativo pode reconhecer um objeto antes de reconhecer seu pai. Dependendo do aplicativo, isso pode ou não ser um problema. O aplicativo sempre pode ler o estado atual do pai a partir do diretório.

  • Para manipular objetos movidos ou excluídos, armazene o atributo objectGUID de cada objeto controlado. O atributo objectGUID de um objeto permanece inalterado, independentemente de onde ele é movido por toda a floresta.

  • Para manipular objetos movidos, execute sincronizações completas periódicas ou aumente o escopo da pesquisa e filtre alterações desinteressantes no final do cliente.

  • Para manipular objetos excluídos, execute sincronizações completas periódicas ou execute uma pesquisa separada para objetos excluídos ao executar uma sincronização incremental. Ao consultar objetos excluídos, recupere o objectGUID dos objetos excluídos para determinar os objetos a serem excluídos do banco de dados. Para obter mais informações, consulte Recuperando objetos excluídos.

  • Lembre-se de que os resultados da pesquisa incluem apenas os objetos e atributos que o chamador tem permissão para ler (com base nos descritores de segurança e DACLs nos vários objetos). Para obter mais informações, consulte Efeitos da segurança em consultas.

Para obter mais informações e um exemplo de código que mostra as noções básicas de um aplicativo de sincronização USNChanged, consulte Código de exemplo para recuperar alterações usando USNChanged.