directory-api mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Berg, R. van den (Robin)" <Robin.van.den.B...@ing.nl.INVALID>
Subject RE: LDAP API - Too much ldap connections with LdapConnectionPool
Date Fri, 19 May 2017 14:29:10 GMT
Hi,

Nevermind, I found the issue. 
I'll respond so you don't waste your time on this, and perhaps others find use to my comment.
The documentation is also a bit ambiguous.

The problem was that I specifically did an 'unbind'. I thought that would be safe.. before
doing a 'bind' with another user on the same connection.
However, this is something you should specifically NOT do.
The unbind operation sets the 'connected' flag on false:
[1864]LDAPNetworkConnection: connected.set( false );
Therefore, the connection closes, and will be probably 4 min in TIME_WAIT. 
A new one will be made by the next 'bind' operation.

The docs tells us this:
(http://directory.apache.org/api/user-guide/2.2-binding-unbinding.html) 
"Once the user has finished interacting with the server, they can unbind, destroying the session
held on the server. This operation does not close the connection, because, again bind != connection!"
However, this is not entirely true because a bit further down in the same documentation-page
the docs tell:
" This is a trivial operation : you just send an UnbindRequest to the server, which will invalidate
your session.
It's important to know that when you issue an Unbind, the connection is dropped"

Kind Regards,
Robin

-----Original Message-----
From: Berg, R. van den (Robin) [mailto:Robin.van.den.Berg@ing.nl.INVALID] 
Sent: Friday, May 19, 2017 3:23 PM
To: api@directory.apache.org
Subject: LDAP API - Too much ldap connections with LdapConnectionPool 

Hi!

I stumbled on a problem regarding connectionpooling.
What I would like to do is have a particular connectionpool that does NOT exceed, let's say
2 connections for this example.
If they are all occupied, I want to wait for a particular timeout before throwing an exception.
'whenExhaustedAction  WHEN_EXHAUSTED_BLOCK<http://grepcode.com/file/repo1.maven.org/maven2/commons-pool/commons-pool/1.6/org/apache/commons/pool/impl/GenericObjectPool.java#GenericObjectPool.0WHEN_EXHAUSTED_BLOCK>'

The only thing I want to do with these connections is perform a 'bind' operation to check
username/password.
I specifically do not want to close the connection to prevent this overhead.

I started off with the developer guide/introduction.
I noticed that I got a LOT of open connections on my machine, even though I set maxIdle =
maxActive = 2.
I don't know if I did something wrong in configuring this, or if this is some kind of bug.
I made a piece of code that uses a pool to get a connection and do 20 'bind'-operations in
parallel (different threads) I ended up with 22 connections that were open even after my jvm
closed.
The weird thing, for every factory.getConnection() a connection has been made, but was not
used!

Does somebody have a clue what I did wrong, or is this a bug?

Thanks in advance!
Kind Regards,
Robin
====code===
public class TestApacheLDAP {
    public static void main(String[] args) throws Exception {
        LdapConnectionConfig config = new LdapConnectionConfig();
        config.setLdapHost("secretldapserver");
        config.setLdapPort(389);

        DefaultLdapConnectionFactory factory = new DefaultLdapConnectionFactory(config);
        factory.setTimeOut(1000L);

        GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
        poolConfig.lifo = true;
        poolConfig.maxActive = 2;
        poolConfig.maxIdle = 2;
        poolConfig.maxWait = -1L;
        poolConfig.minEvictableIdleTimeMillis = 1000L * 2L;
        poolConfig.minIdle = 0;
        poolConfig.numTestsPerEvictionRun = 3;
        poolConfig.softMinEvictableIdleTimeMillis = -1L;
        poolConfig.testOnBorrow = false;
        poolConfig.testOnReturn = false;
        poolConfig.testWhileIdle = false;
        poolConfig.timeBetweenEvictionRunsMillis = -1L;
        poolConfig.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;

        LdapConnectionPool pool = new LdapConnectionPool(
                new DefaultPoolableLdapConnectionFactory(factory), poolConfig);

        final ExecutorService executorService = Executors.newCachedThreadPool();

        final AtomicInteger failures = new AtomicInteger();
        final AtomicInteger success = new AtomicInteger();
        final List<String> connectionHashes = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            executorService.submit(() -> {
                try {
                    LdapConnection connection = pool.getConnection();
                    connection.unBind();
                    connection.bind("uid=xxxxxxx,ou=xxxx,o=xxxxx,c=xx", "mycorrectpassword");
                    if (connection.isAuthenticated()) {
                        success.getAndIncrement();
                    }
                    connectionHashes.add(String.valueOf(connection.hashCode()));
                    pool.releaseConnection(connection);
                } catch (LdapException e) {
                    failures.getAndIncrement();
                    e.printStackTrace();
                }
            });
        }

        Thread.sleep(10_000);

        System.out.println("=====================================");
        System.out.println(" failures: " + failures + " success: " + success);
        System.out.println(" used connections: " + connectionHashes);
        final Map<String, Long> count = connectionHashes.stream().collect(Collectors.groupingBy(e
-> e, Collectors.counting()));
        count.forEach((s, aLong) -> System.out.println("connection " + s + ", times used:"
+ aLong));
        System.out.println("=====================================");

        System.exit(0);
    }
}
Output:
=====================================
failures: 0 success: 20
used connections: [509471061, 1713606446, 1713606446, 509471061, 1713606446, 509471061, 1713606446,
509471061, 1713606446, 509471061, 1713606446, 509471061, 1713606446, 1713606446, 509471061,
1713606446, 509471061, 1713606446, 509471061, 1713606446] connection 509471061, times used:
9 connection 1713606446, times used: 11 netstat -anp | grep ":389\|:636"
tcp6       0      0 10.0.2.15:46648         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46658         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46670         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46688         ipfromldap:389        ESTABLISHED 15532/java
tcp6       0      0 10.0.2.15:46676         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46668         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46654         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46666         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46650         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46660         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46664         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46656         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46686         ipfromldap:389        ESTABLISHED 15532/java
tcp6       0      0 10.0.2.15:46678         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46672         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46682         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46662         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46680         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46652         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46674         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46684         ipfromldap:389        TIME_WAIT   -

----------------------------------------------------------------
ATTENTION:
The information in this e-mail is confidential and only meant for the intended recipient.
If you are not the intended recipient, don't use or disclose it in any way. Please let the
sender know and delete the message immediately.
------------------------------------------------------------------------------------------------------

----------------------------------------------------------------
ATTENTION:
The information in this e-mail is confidential and only meant for the intended recipient.
If you are not the intended recipient, don't use or disclose it in any way. Please let the
sender know and delete the message immediately.
------------------------------------------------------------------------------------------------------

Mime
View raw message