同样的一段代码,在我的机器上是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
posted on 2012-02-29 16:41
YODA 阅读(4007)
评论(0) 编辑 收藏