For the same pair of client & server principal, invocation of
acceptSecContext() at a high rate leads to serious performance problem.
The main problem is with the clean-up right after adding the authentication
timestamp in the LinkedList<AuthTimeWithHash>. See the AuthList put method
which is invoked from sun.security.krb5.internal.rcache.MemoryCache
synchronized void checkAndStore(KerberosTime currTime, AuthTimeWithHash time)
method. Removing last entry from a LinkedList one by one in a synchronized
block is not good for performance.
From JFR Hot Methods:
#233 daemon prio=5 os_prio=0 tid=0x0000000000c26000 nid=0x956 runnable
[0x00007f6c75d0f000]
java.lang.Thread.State: RUNNABLE
at java.util.LinkedList.indexOf(LinkedList.java:604)
at sun.security.krb5.internal.rcache.AuthList.put(AuthList.java:116)
at
sun.security.krb5.internal.rcache.MemoryCache.checkAndStore(MemoryCache.java:7
1)
- locked <0x00000000b09603f0> (a
sun.security.krb5.internal.rcache.MemoryCache)
at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:323)
at sun.security.krb5.KrbApReq.<init>(KrbApReq.java:149)
at
sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.java:108
)
What we see at the server side when the same client principal sends high rate
requests in multiple threads is as below:
#229 daemon prio=5 os_prio=0 tid=0x000000000136b000 nid=0x952 runnable
[0x00007f6c765b3000]
java.lang.Thread.State: RUNNABLE
at
sun.security.krb5.internal.rcache.MemoryCache.checkAndStore(MemoryCache.java:7
1)
- locked <0x00000000b09ab380> (a
sun.security.krb5.internal.rcache.MemoryCache)
at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:323)
#231 daemon prio=5 os_prio=0 tid=0x0000000000c24000 nid=0x954 waiting for
monitor entry [0x00007f6c7456b000]
java.lang.Thread.State: BLOCKED (on object monitor)
at
sun.security.krb5.internal.rcache.MemoryCache.checkAndStore(MemoryCache.java:5
6)
- waiting to lock <0x00000000b09ab380> (a
sun.security.krb5.internal.rcache.MemoryCache)
at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:323)
Instead of LinkedList, a better suited Collection should be used, therefore a
specific implementation for this purpose might be needed.
If the service is not kerberised, normally the server can respond pretty fast
around 1 ms.