Spring LdapTemplate 连接 LDAP 服务器缓慢的问题

Spring LdapTemplate 连接 LDAP 服务器缓慢的问题

同样的一段代码,在我的机器上是OK的,在测试环境也是OK的。就是到了新来的同事机器上,那叫一个慢啊。输入用户名口令,登录,需要等待1分钟……

初步判断肯定是LdapTemplate做操作的时候花费了很长的时间。LdapTemplate的配置如下:

<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
        <property name="url" value="ldap://192.168.1.77:389/dc=cn,dc=earth"/>
        <property name="userDn" value="cn=root"/>
        <property name="password" value="tjmc123"/>
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
        <property name="contextSource" ref="contextSource"/>
</bean>    
 

但是还是看不出问题。实在是百思不得其解了,只好查看Thread dump了,在这里花费了很长的时间:

"qtp22172629-23" prio=5 tid=0x1741d1d0 nid=0x1760 runnable [0x17f9e000..0x17f9fd68]
        at java.net.Inet4AddressImpl.getHostByAddr(Native Method)
        at java.net.InetAddress$1.getHostByAddr(InetAddress.java:842)
        at java.net.InetAddress.getHostFromNameService(InetAddress.java:532)
        at java.net.InetAddress.getHostName(InetAddress.java:475)
        at java.net.InetAddress.getHostName(InetAddress.java:447)
        at java.net.InetSocketAddress.getHostName(InetSocketAddress.java:210)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:341)
        at java.net.Socket.connect(Socket.java:507)
        at java.net.Socket.connect(Socket.java:457)
        at java.net.Socket.(Socket.java:365)
        at java.net.Socket.(Socket.java:178)
        at com.sun.jndi.ldap.Connection.createSocket(Connection.java:346)
......

看起来,是在尝试解析主机域名/地址信息。可是我配置的是IP地址啊,为啥还去解析?先不管这些了,先在本地hosts文件中配置一下LDAP服务器的别名吧。配置完本地hosts文件之后,测试,一切OK了。

回想起来,因为我的机器和测试环境应用主机上都有LDAP服务器的别名配置,所以没有出现连接慢的问题,而新来的同事的hosts文件是干干净净的,所以,杯具了……

//------------------------------------

分析了Spring-ldap的代码以及关键的类InetSocketAddress,过程大概是这样的:

spring-ldap的LdapContextSource会把设置的属性url的值中,ldap://和端口之间的字符串当做主机名(注意,是当做主机名,是String对象,不是地址)传入给LdapClient去建立和LDAP服务器之间的连接。而LdapClient通过层层调用之后,最终通过构造器InetSocketAddress(String hostname, int port) 创建了InetSocketAddress对象。

在JDK的文档上关于InetSocketAddress(String hostname, int port)有如下描述:

Creates a socket address from a hostname and a port number.
An attempt will be made to resolve the hostname into an InetAddress. If that attempt fails, the address will be flagged as unresolved.

无需再解释什么了……

回头想想,介绍spring-ldap的文章也好,示例代码也好,基本上都是在url上写域名,很少见写地址的,看来,spring-ldap是鄙视IP地址的方式访问LDAP服务器的了。

环境列表:

Sun HotSpot JDK 1.5.0_05

Spring-ldap: 1.3.0

Spring: 3.0.4

 

Technorati 标签: Spring, LdapTemplate, LDAP

你可能感兴趣的:(Spring LdapTemplate 连接 LDAP 服务器缓慢的问题)