类MemCachedClient的get方法是否存在线程安全问题


最近看一个宕机项目的stack日志时,发现大量线程卡在MemCachedClient的get方法上,如下的日志:

"http-8080-49" daemon prio=10 tid=0x0000000041823000 nid=0x785b runnable [0x00002b2ebf220000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.FileDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:21)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:233)
at sun.nio.ch.IOUtil.read(IOUtil.java:200)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:236)
- locked (a java.lang.Object)
at com.schooner.MemCached.SockInputStream.readFromChannel(Unknown Source)
at com.schooner.MemCached.SockInputStream.read(Unknown Source)
at com.schooner.MemCached.SockInputStream.getLine(Unknown Source)
at com.schooner.MemCached.AscIIClient.get(Unknown Source)
at com.schooner.MemCached.AscIIClient.get(Unknown Source)
at com.schooner.MemCached.AscIIClient.get(Unknown Source)
at com.danga.MemCached.MemCachedClient.get(Unknown Source)
at com.dheaven.mip.service.impl.MemcachedServiceImpl.get(MemcachedServiceImpl.java:294)
at com.dheaven.mip.web.MSC3HttpInteface.doPost(MSC3HttpInteface.java:260)

这是之前一个比较老的项目,所有的mem请求都通过一个工具类进行,但此工具类只使用了一个static的MemCachedClient。
观察mem服务端,有大量的未关闭的socket,和项目中卡在MemCachedClient的get方法的线程数一致。

怀疑是MemCachedClient的get方法线程不安全导致,但是我本地无法重现这个问题。我遗漏了什么东西吗,或者这个问题有其他的原因?

期待您的帮助!

memcached 线程安全

高山玛莉亚 10 years, 7 months ago

建议将mc客户端从文本方式改为二进制试试,文本方式可能有一些特殊字符导致get的id和内容错位,服务端已经响应,但是客户端还一直在等结束符,这种情况一出现就不会释放,因为mc客户端的失败链接回收机制应该是有bug的。

wazze answered 10 years, 7 months ago

Your Answer