Java 为数百万用户搜索/导航LDAP

Java 为数百万用户搜索/导航LDAP,java,performance,ldap,ldap-query,Java,Performance,Ldap,Ldap Query,我们安装了LDAP(目录服务器),拥有数百万用户。当一个新用户选择用户名时,我们需要在LDAP中验证用户名,这需要一分半钟的时间,这非常慢。同样,当我们创建一个新用户时,它也会同时发生。我用java编写了代码,在5-10000个用户中运行良好。因此,任何关于缩短搜索时间的想法都会有所帮助 问题是所有用户都在同一个树中-没有组或组织,这是要求,我们无法更改它。我尝试在命令行中使用ldapsearch,结果立即返回。我曾经 "ldapsearch -D "" -w "" -h -p -b "ou

我们安装了LDAP(目录服务器),拥有数百万用户。当一个新用户选择用户名时,我们需要在LDAP中验证用户名,这需要一分半钟的时间,这非常慢。同样,当我们创建一个新用户时,它也会同时发生。我用java编写了代码,在5-10000个用户中运行良好。因此,任何关于缩短搜索时间的想法都会有所帮助

问题是所有用户都在同一个树中-没有组或组织,这是要求,我们无法更改它。我尝试在命令行中使用ldapsearch,结果立即返回。我曾经

"ldapsearch -D "" -w "" -h  -p  -b "ou=company,dc=abc,dc=com" uid=user1"
代码如下:

public String userCheck(String name){
        String text = "";


        Hashtable<String, String> environment = new Hashtable<String, String>();

        environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
        environment.put(Context.PROVIDER_URL, "ldap://xxxxxxxxxx:1389");
        environment.put(Context.SECURITY_AUTHENTICATION, ""); ////////these values are all defined
        environment.put(Context.SECURITY_PRINCIPAL, "" ); 
        environment.put(Context.SECURITY_CREDENTIALS, "");
        try
        {
            //DirContext context = new InitialDirContext(environment);

            String searchBase = "ou=company,dc=abc,dc=com"; ////////////////////////This is where all the 2 million users are stored
            String FILTER = "(uid="+name+")";
            SearchControls ctls = new SearchControls();
            ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            NamingEnumeration<SearchResult> answer = context.search(searchBase, FILTER, ctls);
            SearchResult result = answer.next();
            javax.naming.directory.Attribute email = result.getAttributes().get("mail");
            javax.naming.directory.Attribute cn = result.getAttributes().get("cn");
            text = "Taken" ;
            context.close();
        }
        catch (Exception a)
        {
            text = "available" ;

        }

        return text;

    }
公共字符串用户检查(字符串名称){
字符串文本=”;
Hashtable环境=新的Hashtable();
put(Context.INITIAL\u Context\u工厂,“com.sun.jndi.ldap.LdapCtxFactory”);
environment.put(Context.PROVIDER\u URL,“ldap://xxxxxxxxxx:1389");
environment.put(Context.SECURITY\u AUTHENTICATION,”);//这些值都已定义
environment.put(Context.SECURITY_PRINCIPAL,“”);
environment.put(Context.SECURITY_凭据“”);
尝试
{
//DirContext context=新的初始DirContext(环境);
String searchBase=“ou=company,dc=abc,dc=com”;//这是存储所有200万用户的地方
字符串筛选器=“(uid=“+name+”);
SearchControls ctls=新的SearchControls();
ctls.setSearchScope(SearchControls.SUBTREE_范围);
namingumerationanswer=context.search(searchBase、FILTER、ctls);
SearchResult=answer.next();
javax.naming.directory.Attribute email=result.getAttributes().get(“邮件”);
javax.naming.directory.Attribute cn=result.getAttributes().get(“cn”);
text=“take”;
context.close();
}
捕获(例外a)
{
text=“可用”;
}
返回文本;
}
谢谢


编辑:我能更快地得到它。我重新创建了索引并重新生成了它们,现在一切正常。再次感谢您的帮助。

无论如何,您都做错了。在创建用户之前,搜索目录以查看是否使用UID没有任何用处。这可能会在之后立即改变。如果已经获取了UID,您应该尝试插入用户并处理失败。如果你首先正确分配UID,即。通过UUID类,它们永远不会被接受。并不是说@EJP在插入和处理失败方面是错误的,但是搜索应该在几毫秒后返回。uid索引了吗?但不确定UUID类如何用于生成“正确”的uid值。EJP,你能解释一下吗?谢谢你的回复。LDAP用户是与另一个同步的应用程序用户创建的,因此我们不能先插入并检查,我们需要先检查用户是否存在。而且,即使插入它也需要同样的时间。我没有对uid做任何索引。我将检查如何为LDAP列编制索引。谢谢但正如我提到的,当我通过命令行运行ldapsearch时,它很快返回结果。但我仍然会尝试索引和检查。谢谢。看起来ldap有额外的索引,uid是其中一个额外的索引,默认情况下它在那里。所以我不确定我还能补充什么。谢谢