标签:
我们看看ReadTimeoutHandler下面这个初始化方法,在初始化的时候做的一些事情,Netty的2个改进点我认为都在这里可以体现出来(下面红体):
private void initialize(ChannelHandlerContext ctx) {
// Avoid the case where destroy() is called before scheduling timeouts.
// See: https://github.com/netty/netty/issues/143
switch (state) {
case 1:
case 2:
return;
}
state = 1;
lastReadTime = System.currentTimeMillis();
if (timeoutMillis > 0) {
timeout = ctx.executor().schedule(
new ReadTimeoutTask(ctx),
timeoutMillis, TimeUnit.MILLISECONDS);
}
}
一个过于频繁的调用System.currentTimeMillis();这个调用要从操作系统取得超时时间,这个是需要消耗一定资源的。然而我们可以看到这个类里面,该方法被反复的调用。假如有10000个channel,那么就有10000个这个handler,System.currentTimeMillis();被调用的频率就会非常高,而这么高的调用频率其实是没什么意义的。两次调用之间可能相差连1ms都不到,请问在这种情况下,如此精确意义何在呢?
更好的做法可能是在主循环里面取得一次时间,然后在所有handler里面用同一个时间。(关于主循环的位置后面再说)
另外一处就是这个ctx.executor().schedule方法的调用了,为了处理channel过期,我们往主循环里面提交了一个过期处理任务(关于主循环的位置后面再说),同样,如果1万个channel,那么就有1万个runnable被执行。这里同样,如果在1个runnable里面处理这1万个channel是否效率会更高?
主循环就是NioEventLoop的run方法,这里是,读,flush所有异步IO操作的发起点。
我们可以在run方法里面获取1个系统时间,然后在后面的handler里面统一使用这个NioEventLoop级别的时间。
同样,我们也可以在NioEventLoop里面维护一个过期任务,处理所有的channel。
综上,由于netty里面把过期处理放到了channel hanlder级别,而不是nioeventloop级别,导致效率上值得商榷。
标签:
原文地址:http://my.oschina.net/HaFoLuoKe/blog/491102