使用Open LDAP进行身份验证和其他读取请求时遇到并发问题(版本测试2.3.43和2.4.39)
当发出100个并发绑定请求时,测试代码大约需要150毫秒。将此值增加到1000个并发请求会将时间增加到9303毫秒。 因此,从x10并发请求中我们看到时间增加了x62。
这是预期的行为吗?或者我们的OpenLDAP服务器配置/ linux主机配置中缺少什么?
注意:我们已经针对基于Windows的Apache DS服务器2.0.0(相同的树结构等)运行此测试代码以进行比较和针对该服务器,性能结果在我们通常期望的情况下(即100x需要~80ms) ,1000x需要~400ms,10,000x需要~2700ms)
slapd.conf中的设置:
cachesize 100000
idlcachesize 300000
database bdb
suffix "dc=company,dc=com"
rootdn "uid=admin,ou=system"
rootpw secret
directory /var/lib/ldap
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
index uidNumber,gidNumber,loginShell eq,pres
index uid,memberUid eq,pres,sub
index nisMapName,nisMapEntry eq,pres,sub
sizelimit 100000
loglevel 256
测试代码:
import java.util.ArrayList;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
public class DirectoryServiceMain {
public static void main(String[] args) {
int concurrentThreadCount = 100;
LdapContextSource ctx = new LdapContextSource();
ctx.setUrls(new String [] { "ldap://ldap1.dev.company.com:389/", "ldap://ldap1.dev.company.com:389/" });
ctx.setBase("dc=company,dc=com");
ctx.setUserDn("uid=admin,ou=system");
ctx.setPassword("secret");
ctx.setPooled(true);
ctx.setCacheEnvironmentProperties(false);
LdapTemplate template = new LdapTemplate();
template.setContextSource(ctx);
long startTime = System.currentTimeMillis();
ArrayList<Thread> threads = new ArrayList<>();
for(int i = 0; i < concurrentThreadCount; i++) {
Thread t = new Thread(
() -> {
DirContext context = template.getContextSource().getContext("uid=username,dc=users,uid=office,dc=suborganisations,uid=ABC,dc=organisations,dc=company,dc=com",
"password");
try {
context.close();
} catch(NamingException e) {}
});
t.start();
threads.add(t);
}
boolean alive = true;
while(alive) {
alive = false;
for(Thread t : threads) {
if(t.isAlive()) {
alive = true;
try {Thread.sleep(10);} catch(InterruptedException e) {}
}
}
}
long endTime = System.currentTimeMillis();
System.out.println("Total time: " + (endTime - startTime));
}
}
ulimit -n 131072
*更新* 如果在每个t.start()之后添加了一点延迟(例如Thread.sleep(1)),那么n个并发线程的处理时间会大大减少。
答案 0 :(得分:3)
更长的答案是,如果您使用BDB作为数据库,那么您可能会看到超过一定数量的并发请求的线性扩展问题。 BDB有自己的db_config文件,您可以配置该文件以提供更好的性能特征。您还可以考虑更改为专门为open ldap编写的MDB,并使用最少的配置进行更好的线性扩展。
您还应该考虑通过将jndi ldap连接池大小设置为LDAPContextSource来限制并发连接的数量:
Map<String, Object> map = new HashMap<>();
map.put("com.sun.jndi.ldap.connect.pool.initsize", 2);
map.put("com.sun.jndi.ldap.connect.pool.maxsize", 2);
map.put("com.sun.jndi.ldap.connect.pool.prefsize", 2);
ctx.setBaseEnvironmentProperties(map);