这段时间在重温 java 通讯这块,又重看了一下几个通讯框架,比如 mina,quikserver. whalin memcached,spymemcached 结构不是我的主要研究点.我主要是看他们对通讯那块(具体connet,read,write)的处理!
我在调试spymemcached的时候发现一个奇怪的问题.当使用MemcachedClient 与server建立一个连接,连接代码如下:
MemcachedClient memcachedClient = new MemcachedClient(new InetSocketAddress("192.168.1.111", 11211));
long time = System.currentTimeMillis();
Future<Boolean> future = memcachedClient.set("xwagnquan", 3600, time);
程序启动后,用CurrPorts( http://www.nirsoft.net/utils/cports.html ,windows下一个小工具,用于查看和管理tcp/udp的连接状况,比netstat 方便)查看客户端的连接状况, 如下图:
很明显 ,进程编号为6032,本地端口为24550,远程端口为192.168.1.111:11211的是我与server建立的连接,使用24550语192.168.1.111server通讯。
问题1,剩下的那几个java通道分别连接到111的其他端口,在java nio中这些通道是做什么用的,有什么意义?在基于mina的通讯程序中,我与server建立一个连接后,只发现一个类似6032这的通道!
接着,我关掉一个与24550有关的java通道,发现spymemcache 后台疯狂的打出
2009-04-23 17:40:29.171 INFO net.spy.memcached.MemcachedConnection: sun.nio.ch.SelectionKeyImpl@1884174 has a ready op, handling IO
2009-04-23 17:40:29.171 INFO net.spy.memcached.MemcachedConnection: sun.nio.ch.SelectionKeyImpl@1884174 has 1, interested in 0
2009-04-23 17:40:29.171 INFO net.spy.memcached.MemcachedConnection: sun.nio.ch.SelectionKeyImpl@1884174 has a ready op, handling IO
2009-04-23 17:40:29.171 INFO net.spy.memcached.MemcachedConnection: sun.nio.ch.SelectionKeyImpl@1884174 has 1, interested in 0
2009-04-23 17:40:29.171 INFO net.spy.memcached.MemcachedConnection: sun.nio.ch.SelectionKeyImpl@1884174 has a ready op, handling IO
2009-04-23 17:40:29.171 INFO net.spy.memcached.MemcachedConnection: sun.nio.ch.SelectionKeyImpl@1884174 has 1, interested in 0
2009-04-23 17:40:29.171 INFO net.spy.memcached.MemcachedConnection: sun.nio.ch.SelectionKeyImpl@1884174 has a ready op, handling IO
2009-04-23 17:40:29.171 INFO net.spy.memcached.MemcachedConnection: sun.nio.ch.SelectionKeyImpl@1884174 has 1, interested in 0
这类信息!导致cpu使用很高,后更跟踪sypmemcached源代码发现在MemcachedConnection这个类中的handleIO()方法中有如下逻辑,
if(selectedKeys.isEmpty() && !shutDown) {
getLogger().debug("No selectors ready, interrupted: "
+ Thread.interrupted());
if(++emptySelects > DOUBLE_CHECK_EMPTY) {
for (SelectionKey sk : selector.keys()) {
getLogger().info("%s has %s, interested in %s",
sk, sk.readyOps(), sk.interestOps());
if(sk.readyOps() != 0) {
getLogger().info("%s has a ready op, handling IO", sk);
handleIO(sk);
} else {
lostConnection((MemcachedNode)sk.attachment());
}
}
assert emptySelects < EXCESSIVE_EMPTY
: "Too many empty selects";
}
这块逻辑我没看清楚他的作用!
以上暴漏出一个严重的问题,如果一个java通道被外在因素强制关闭,会导致以上逻辑反复的执行,导致cpu使用率彪到极限,且一直处于最高峰!
是不是这个框架有问题呢? 以后选择memcached java client 是不是要注意一下呢?
请熟悉spymemcached 和java socket 的哥们帮忙解释一下,谢谢!