关于netty的线程

guxuede 发布于 2011/11/25 10:36
阅读 5K+
收藏 2

你好

我看过你的关于netty的帖子。现在我关于netty线程的问题很头大。netty一个连接就是一个work线程。我要做长连接的话,那么就岂不是很多线程。Executors.newCachedThreadPool(),是可伸缩的线程池。如果一个连接过来,不close,保持长连接那么他就会占用一个work线程。其他的请求连接会从线程池拿出一个新的线程来work。这样有多少请求就会多少连接。换成Executors.newSingleThreadExecutor()线程池的话,那么netty只能为一个连接工作了。
mina一个线程就能hold住很多连接。netty如何设置?求指点阿。大哥,抑或是我对
Executors.newCachedThreadPool()理解不够。

加载中
0
JavaGG
JavaGG

。。。一样的道理,mina是nio和,netty也是基本nio,所以他长连接并不会hold住线程

nio的工作方式是把一个socket的上载的数据放到一个bytebuffer上,再把这个buffer发送给你工作的线程

之后他再读取下一个的数据

0
guxuede
guxuede

引用来自“JavaGG”的答案

。。。一样的道理,mina是nio和,netty也是基本nio,所以他长连接并不会hold住线程

nio的工作方式是把一个socket的上载的数据放到一个bytebuffer上,再把这个buffer发送给你工作的线程

之后他再读取下一个的数据

感谢JavaGG的回答 。

但是解释不了用Executors.newSingleThreadExecutor()设置线程池,channel不close的,整个线程都会阻塞,其他连接都不搭理的情况。

0
guxuede
guxuede
我现在想避免一个长连接占用一个worker线程(避免线程间切换性能的消耗)。甚至一个线程handle所有连接(不是用于http服务器)。
mina和cindy都能很好的配置acceptor thread和processor thread在单线程下或线程池下工作。
但是netty一个连接不关闭的话,就会蛋疼的阻塞了。那么后续的连接就会从线程池里取(或创建)。那么这和用普通的socket编写网络程序。没有什么优势可言了。。。
0
肖冰
肖冰
worker线程处理到 messageReceive 后 就被回收活继续接受新的请求,handlers 的请求会被另外一个线程处理, 和 epool 模型一样。
0
leeken
leeken
" 但是netty一个连接不关闭的话,就会蛋疼的阻塞了" 怎么会阻塞呢? 一个数据收发请求处理完了(即handler处理结束了),不close该chanel就可以了,处理完毕后本worker线程和本chanel就没有关系。本worker线程就会回到idle状态,下次有请求时可能是处理本chanel的收发请求,也可能是处理其他chanel的请求。

0
guxuede
guxuede

谢谢肖冰,leeken的回答。

我再看看吧。

我现在用mina了,mina的IoBuffer没有netty的ChannelBuffer方便,要翻过来翻过去的,

数据经常给翻没了。

有时间继续研究netty,

0
谢远熙
我也遇到跟楼主一样的问题,我使用了固定的 线程池,一样会阻塞在那里
0
天下朋友
天下朋友
ServerBootstrap初始的threadPoolExecutor只是accept的线程池, 一般做法是在业务处理开始加线程处理(org.jboss.netty.handler.execution.ExecutionHandler), 如果pipeline的hander不加ExecutionHanlder, accept只能在处理完一个完全的流程后才返回,read data那边肯定会等待和阻塞
0
石头哥哥
石头哥哥

执行ChannelHandler链的整个过程是同步的,如果业务逻辑的耗时较长,会将导致Work线程长时间被占用得不到释放,从而影响了整个服务器的并发处理能力。

所以,为了提高并发数,一般通过ExecutionHandler线程池来异步处理ChannelHandler链(worker线程在经过ExecutionHandler后就结束了,它会被ChannelFactory的worker线程池所回收)

在Netty中,只需要增加一行代码:

public ChannelPipeline getPipeline() {

         return Channels.pipeline(

                 new DatabaseGatewayProtocolEncoder(),

                 new DatabaseGatewayProtocolDecoder(),

                 executionHandler, // Must be shared

                 new DatabaseQueryingHandler());

}

例如:

ExecutionHandler executionHandler = new ExecutionHandler(

             new OrderedMemoryAwareThreadPoolExecutor(16, 1048576, 1048576))

0
guxuede
guxuede
难道你们没注意到 channel在handle里不close的话。一个线程根本得不到回收。我要保持长连接阿不能close阿。
返回顶部
顶部