开发者社区> 问答> 正文

关于netty的线程? 400 报错

关于netty的线程? 400 报错

你好:

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

展开
收起
爱吃鱼的程序员 2020-06-04 14:02:43 656 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

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

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

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

    ######

    引用来自“JavaGG”的答案

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

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

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

    感谢JavaGG的回答 。

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

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

    ######

    谢谢肖冰,leeken的回答。

    我再看看吧。

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

    数据经常给翻没了。

    有时间继续研究netty,

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

    执行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))

    ######难道你们没注意到 channel在handle里不close的话。一个线程根本得不到回收。我要保持长连接阿不能close阿。
    2020-06-04 16:37:59
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
多IO线程优化版 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载