【发布时间】:2014-12-11 13:48:25
【问题描述】:
在使用 Open LDAP 进行身份验证和其他读取请求时遇到并发问题(测试版本为 2.3.43 和 2.4.39)
当发出 100 个并发绑定请求时,测试代码大约需要 150 毫秒。将此增加到 1000 个并发请求会看到所用时间增加到 9303 毫秒。 因此,从 x10 的并发请求中,我们看到所花费的时间增加了 x62。
这是预期的行为吗?还是我们的 OpenLDAP 服务器配置/linux 主机配置中缺少什么?
注意:我们已针对基于 Windows 的 Apache DS 服务器 2.0.0(相同的树结构等)运行此测试代码,以便与该服务器进行比较,性能结果与我们通常预期的一样(即 100 倍需要约 80 毫秒) , 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 个并发线程的处理时间会大大减少。
【问题讨论】:
-
简短的回答是“是”。响应时间与负载之间的关系不是线性的。