同樣的一段代碼,在我的機器上是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 閱讀(4033)
評論(0) 編輯 收藏