Медленная синхронизация группы AD

Мы пишем программный инструмент, который позволяет использовать механизм аутентификации Active Directory. Он периодически синхронизирует группы пользователей между AD и инструментом. Некоторые из наших клиентов заметили, что во время операции синхронизации высока нагрузка на ЦП на серверах AD.

Я искал возможные причины, которые могут вызвать проблему. Одна из них - вложенные группы.

Также я обнаружил в Интернете, что у других людей тоже были такие проблемы, и когда они сменили порт AD, проблема исчезла. Я хотел бы знать, реалистичен ли последний сценарий (для меня немного странно, что изменение порта AD может решить проблему) и есть ли другие распространенные причины, которые могут вызвать проблему.

Мы используем следующий запрос для sync:

(&(memberof:1.2.840.113556.1.4.1941:=group_DN)(objectclass=u‌​ser)(!(objectclass=c‌​omputer))
0
задан 3 May 2017 в 15:59
2 ответа

Не используйте переходную оценку правила соответствия LDAP для рекурсивного членства в группах. Оно пресловуто медленное, особенно при большом количестве каталогов/групп. членства.

https://stackoverflow.com/questions/40024425/1-2-840-113556-1-4-1941-ldap-matching-rule-in-chain-has-performance-problems

http://dunnry.com/blog/TransitiveLinkValueFilterEvaluation.aspx

https://stackoverflow.com/questions/9534669/improving-recursive-active-directory-function

2
ответ дан 4 December 2019 в 13:32

Так получилось выяснилось, что проблема действительно была во вложенных группах. Я «перенес» логику рекурсии на клиентскую сторону, и это сократило время выполнения примерно в 10 раз. Я не знаю, насколько увеличится сетевой трафик. В любом случае, вот фрагмент кода, который я использовал, на тот случай, если кому-то интересно:

public Set<String> getUsersInGroup(String groupDN) throws NamingException {
    Set<String> ret = new HashSet<>();
    Queue<String> bfsQueue = new LinkedList<>();
    bfsQueue.add(groupDN);
    Set<String> visitedGroups = new HashSet<>();
    LdapContext ctx = getLdapContext(MAX_SEARCH_TIME, false);
    String[] attrIDs = getUserReturnAttrs().toArray(new String[0]);
    while (!bfsQueue.isEmpty()) {
        String current = bfsQueue.element();
        bfsQueue.remove();
        visitedGroups.add(current);

        String userFilter = "(&(objectclass=user)(!(objectclass=computer)))";
        String groupFilter = "(&(objectclass=group)(!(objectclass=computer)))";
        String memberOfFilter = String.format("(memberof=%s)", current);
        String userQuery = String.format("(&%s%s)", memberOfFilter, userFilter);
        String groupQuery = String.format("(&%s%s)", memberOfFilter, groupFilter);

        Set<SearchResult> groups = search(ctx, getSearchBase(), groupQuery, SearchControls.SUBTREE_SCOPE,
                new String[] { "distinguishedName" }, NO_COUNT_LIMIT);
        for (SearchResult g : groups) {
            Attributes attrs = g.getAttributes();
            String gDN = parseAttribute(attrs, "distinguishedName");
            if (!visitedGroups.contains(gDN)) bfsQueue.add(gDN);
        }

        Set<SearchResult> users = search(ctx, getSearchBase(), userQuery, SearchControls.SUBTREE_SCOPE,
                attrIDs, NO_COUNT_LIMIT);
        for (SearchResult u : users) {
            Attributes attrs = u.getAttributes();
            String uDN = parseAttribute(attrs, "userPrincipalName");
            ret.add(uDN);
        }

    }
    return ret;
}
0
ответ дан 4 December 2019 в 13:32

Теги

Похожие вопросы