netty还在学习中,资料说一般业务逻辑处理都自定义线程池来处理,防止nio线程得阻塞。现在是这样做的的,但是因为多线程并发问题,在很多业务逻辑处理的方法上都加了synchronized锁住,出现了问题:
如果自定义多个业务逻辑处理线程,线程的阻塞情况就比较严重(nio线程接收到的消息压入消息处理队列,业务逻辑线程池从队列中取消息进行处理,这个消息队列每次在改变,读取的时候都是同步的,再加上后续业务处理的很多方法也是同步(synchronized)的,测试4000并发时,不仅自定义的业务逻辑处理线程,nio线程阻塞情况也比较严重)最终导致不能正确的完成用户的一些处理...
后来只定义的一个业务逻辑处理线程,即单线程来处理业务逻辑,情况就好多了,但又出现新问题:就是在并发4000的样子,单线程处理一轮的用户请求可能忙不过来,服务器针对用户的每个请求都有一个超时时间,所以单线程的时候后台的离线检测会检测到很多玩家响应超时了(但其实玩家是即时响应了的,只不过单业务现象线程还没来得及处理)...最终导致一部分用户并未按照用户自己发送的数据进行,而是检测到为离线后的默认操作...
不会到大家在对基于netty服务器开发时,自定义的业务逻辑处理线程是怎样的?
Netty
这里的业务处理类现在是如何实现的?按你的说法,单线程和多线程 在这个类中都试验过,并且都没能解决问题,由此来看 可以得出2个结论:(1)需要再努力优化业务处理过程以节省处理时间;(2)提升服务器硬件性能。
1 netty本身的 worker线程的个数是根据CPU来的,直接在 worker线程里做业务逻辑处理不好么?
2 如果不想并发,修改源码,让worker线程个数为1,就没有并发了,这一点跟redis一样的,redis单线程的处理能力貌似也够用了,redis的作者是这么说的。
3 为啥要自定义多个业务逻辑线程?netty本身的worker线程拿到消息后就可以处理了啊
你现在的问题跟Netty没有关系,主要是你的业务处理速度跟不上你所要求的请求速度,单线程也好,多线程也好,都没有关系。
处理不过来,
1,要不把超时的改掉或做优化处理
2,增强处理速度:找到瓶颈优化或者做请求分发到不同服务器处理
单机环境调优讲一种方法吧。
1. 明确你的优化目标(优化是永无止境的,但必须适可而止)
2. 分析你的硬件瓶颈(归根到底,还是你的硬件在执行软件代码), 比如你的核,内存,带宽(本例中注意下你的带宽拥挤是否延迟你的消息返回)
3. 根据你的目标调整Netty的BoosEventLoop, WorkEvnetLoop,Buffer大小。
4. 优化你的消息包,尽量在一个MTU大小,优化你的编解码工具类,比如使用Protobuffer(传输小,解码快)代替Json. 另外,特别注意Bytebuf转Message后,是否有被ReferenceCountUtil.release()
5. 消息的返回注意 chanel的write跟writeAndFlush的区别。一个是等缓冲区满了才返回,一个是立刻返回。
上面做完了,就跟netty没啥关系了。
针对你的 编解码Loop线程组 与 工作线程组 的优化
Netty WorkEvnetGroup = M, BusinessWorkerGroup = N ( M, N >1)
这种情况就是一个生产消费模型,M, N之间有一个ArrayBlockingQueue(必需限制上限)做消息缓存。
1. 为了减少锁竞争,可以使用 无锁队列 Disruptor代替 java的 ArrayBlockingQueue, 据说效率是后者的10倍
2.工作任务代码优化,可以全内存操作以及算法优化。
业务服务是否可以分析出单独微服务啊