SPRING LDAP 间歇性需要 2.10 分钟
SPRING LDAP takes 2.10 minutes intermittently
我正在使用 spring-security-ldap-3.2.9,spring-ldap-core-1.3.2。
我们间歇性地遇到 ldap 挂起,它需要超过 2 分钟。在没有 spring 框架的情况下实施没有问题。
这是已知问题还是我遗漏了某些配置。
听起来像是连接池的问题。假设您的服务有一个使用持久连接的专用主体(例如用于用户查找),那么它可能会尝试在失效连接上执行查询。如果池未配置为定期验证这些连接,则它可能仅依赖超时来确定需要重新建立连接。
Spring LDAP 支持具有内置连接验证和维护配置选项的 Apache Commons Pool(参见 section 9.1 in the reference docs). Enabling the testOnBorrow
and testWhileIdle
options on the pooled ContextSource tend to do a good job of evicting stale connections with minimal configuration. If you are using pooling then consider updating to spring ldap 2.1+ if possible, which introduces support for Apache Commons Pool 2。
LDAP 服务器也将有自己的超时设置,它会在一定的空闲时间后断开连接。您的服务创建的任何连接的空闲超时都应小于 LDAP 服务器端的空闲超时。这将在达到 LDAP 服务器超时之前先发制人地丢弃空闲连接,从而在下次相应主体需要与 LDAP 服务器通信时强制建立新连接。
我真的找不到背后的原因,因为这是在框架内发生的,我无法编辑任何代码。
最后,我将我的实现切换回使用 Java 而不使用 spring 的普通 LDAP 实现,到目前为止它运行良好。
我几乎完全遇到过这个问题。解决方案是从 LdapContextSource 中删除 referral follow。修复了 XML 配置显示在答案末尾的问题。
在 VisualVM 中观察代码,大部分执行时间都花在了 AbstractLdapNamingEnumeration.hasMore() 中。这让我找到了 NamingEnumeration hasMoreElements method takes a lot of time when returning false for LDAP,我意识到它正在尝试关注推荐,但我不需要那样做。关闭它可以消除暂停。
<bean id="ldapContextSource"
class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="$ad{ldap.protocol}://$ad{ldap.server}:$ad{ldap.port}" />
<property name="base" value="${ldap.base}" />
<property name="userDn" value="$ldap{user}" />
<property name="password" value="$ldap{password}"/>
<!-- <property name="referral" value="follow" /> -->
<property name="baseEnvironmentProperties">
<map>
<entry key="java.naming.ldap.attributes.binary">
<value>objectSid</value>
</entry>
</map>
</property>
</bean>
我正在使用 spring-security-ldap-3.2.9,spring-ldap-core-1.3.2。
我们间歇性地遇到 ldap 挂起,它需要超过 2 分钟。在没有 spring 框架的情况下实施没有问题。
这是已知问题还是我遗漏了某些配置。
听起来像是连接池的问题。假设您的服务有一个使用持久连接的专用主体(例如用于用户查找),那么它可能会尝试在失效连接上执行查询。如果池未配置为定期验证这些连接,则它可能仅依赖超时来确定需要重新建立连接。
Spring LDAP 支持具有内置连接验证和维护配置选项的 Apache Commons Pool(参见 section 9.1 in the reference docs). Enabling the testOnBorrow
and testWhileIdle
options on the pooled ContextSource tend to do a good job of evicting stale connections with minimal configuration. If you are using pooling then consider updating to spring ldap 2.1+ if possible, which introduces support for Apache Commons Pool 2。
LDAP 服务器也将有自己的超时设置,它会在一定的空闲时间后断开连接。您的服务创建的任何连接的空闲超时都应小于 LDAP 服务器端的空闲超时。这将在达到 LDAP 服务器超时之前先发制人地丢弃空闲连接,从而在下次相应主体需要与 LDAP 服务器通信时强制建立新连接。
我真的找不到背后的原因,因为这是在框架内发生的,我无法编辑任何代码。
最后,我将我的实现切换回使用 Java 而不使用 spring 的普通 LDAP 实现,到目前为止它运行良好。
我几乎完全遇到过这个问题。解决方案是从 LdapContextSource 中删除 referral follow。修复了 XML 配置显示在答案末尾的问题。
在 VisualVM 中观察代码,大部分执行时间都花在了 AbstractLdapNamingEnumeration.hasMore() 中。这让我找到了 NamingEnumeration hasMoreElements method takes a lot of time when returning false for LDAP,我意识到它正在尝试关注推荐,但我不需要那样做。关闭它可以消除暂停。
<bean id="ldapContextSource"
class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="$ad{ldap.protocol}://$ad{ldap.server}:$ad{ldap.port}" />
<property name="base" value="${ldap.base}" />
<property name="userDn" value="$ldap{user}" />
<property name="password" value="$ldap{password}"/>
<!-- <property name="referral" value="follow" /> -->
<property name="baseEnvironmentProperties">
<map>
<entry key="java.naming.ldap.attributes.binary">
<value>objectSid</value>
</entry>
</map>
</property>
</bean>