JNDI LDAP池式连接

问题描述 投票:0回答:1

我的JNDI连接池似乎没有按照预期工作。当我运行测试时,我看到每次都会创建新的连接。连接成功了(因为我可以对Active Directory进行查询),但它们并没有像我期望的那样进行池化。这里有一些关于我的设置的重要说明。

  1. 连接是通过SSL(即ldaps)进行的

  2. 使用定制插座工厂

  3. 通过 "简单 "的认证方式对AD进行认证

  4. 使用默认的池子配置值(目前)。

下面是相关代码。

TestLdapsPooling.java

public class TestLdapsPooling {

    public static void main(String[] args) throws Exception {
        // needed system properties
        System.setProperty("com.sun.jndi.ldap.connect.pool.protocol", "ssl");
        System.setProperty("com.sun.jndi.ldap.connect.pool.debug", "fine");

        Hashtable<String, String> env = new Hashtable<>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, host);

        // use ssl
        env.put(Context.SECURITY_PROTOCOL, "ssl");

        // authentication info
        env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
        env.put(Context.SECURITY_PRINCIPAL, username); 
        env.put(Context.SECURITY_CREDENTIALS, password); 

        // custom socket factory
        env.put("java.naming.ldap.factory.socket", "ldap.TrustedSocketFactory");

        // Enable connection pooling
        env.put("com.sun.jndi.ldap.connect.pool", "true");

        // Create the initial context
        InitialDirContext context =  new InitialDirContext(env);
        System.out.println("First context created");

        // Create a second context
        InitialDirContext context2 =  new InitialDirContext(env);
        System.out.println("Second context created");

        // close first context
        context.close();
        System.out.println("First context closed");

        // close second context
        context2.close();
        System.out.println("Second context closed");

        // Create a third context - I would expect this to use a connection from the pool
        InitialDirContext context3 =  new InitialDirContext(env);
        System.out.println("Third context created");

        // close third context
        context3.close();
        System.out.println("Third context closed");
    }
}

TrustedSocketFactory.java

public class TrustedSocketFactory extends SSLSocketFactory implements Comparator<SocketFactory> {

    // all the methods required from SSLSocketFactory

    @Override
    public int compare(SocketFactory arg0, SocketFactory arg1) {
        // not really sure what this value should be 
        // is this causing the pooling issue?
        return 0;
    }

}

产量:

Create com.sun.jndi.ldap.LdapClient@3f0ee7cb[testdomain.com:636]
Use com.sun.jndi.ldap.LdapClient@3f0ee7cb
First context created
Create com.sun.jndi.ldap.LdapClient@75bd9247[testdomain.com:636]
Use com.sun.jndi.ldap.LdapClient@75bd9247
Second context created
Release com.sun.jndi.ldap.LdapClient@3f0ee7cb
First context closed
Release com.sun.jndi.ldap.LdapClient@75bd9247
Second context closed
Create com.sun.jndi.ldap.LdapClient@7d417077[testdomain.com:636]
Use com.sun.jndi.ldap.LdapClient@7d417077
Third context created
Release com.sun.jndi.ldap.LdapClient@7d417077
Third context closed

我希望第三个上下文能够重用前两个连接中的一个,但输出看起来像是创建了自己的连接。我需要改变什么才能使连接被重复使用,而不是创建一个新的连接?

java ldap jndi connection-pooling
1个回答
0
投票

基于"什么会被集中起来"的部分 https:/docs.oracle.comjavasejnditutorialldapconnectconfig.html。 可能是自定义套接字工厂禁用了池化连接。

有几个环境属性会自动剥夺Context实例使用池化连接的资格。如果Context实例的 "java.naming.ldap.factory.socket "属性被设置为自定义套接字工厂类,它就不能使用池化连接(...)

© www.soinside.com 2019 - 2024. All rights reserved.