上文《Netty框架入门》说到:如果业务处理handler耗时长,将严重影响可支持的并发数。
针对这一问题,经过学习,发现了可以使用ExecutionHandler来优化。
先来回顾一下没有使用ExecutionHandler优化的流程:
    1)Boss线程(接收到客户端连接)->生成Channel->交给Worker线程池处理。
    2)某个被分配到任务的Worker线程->读完已接收的数据到ChannelBuffer->触发ChannelPipeline中的ChannelHandler链来处理业务逻辑。
    注意:执行ChannelHandler链的整个过程是同步的,如果业务逻辑的耗时较长,会将导致Work线程长时间被占用得不到释放,从而影响了整个服务器的并发处理能力。
 
一、引入ExecutionHandler优化
//HttpServerPipelineFactory.java
private final ExecutionHandler executionHandler = new ExecutionHandler(
new OrderedMemoryAwareThreadPoolExecutor(16, 1048576, 1048576));
public class HttpServerPipelineFactory implements ChannelPipelineFactory {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("encoder", new HttpResponseEncoder());
pipeline.addLast("execution", executionHandler);
pipeline.addLast("handler", new HttpServerHandler());
return pipeline;
}
}
    当我们引入ExecutionHandler后,原本同步的ChannelHandler链在经过 ExecutionHandler后就结束了,它会被ChannelFactory的worker线程池所回收,而剩下的ChannelHandler链将由ExecutionHandler的线程池接手处理。
    对于ExecutionHandler需要的线程池模型,Netty提供了两种可选:
        1) MemoryAwareThreadPoolExecutor 通过对线程池内存的使用控制,可控制Executor中待处理任务的上限(超过上限时,后续进来的任务将被阻塞),并可控制单个Channel待处理任务的上限,防止内存溢出错误。但是它不维持同一Channel的ChannelEvents秩序,当经过ExecutionHandler后的ChannelHandler链中有不止一个Handler时,这些事件驱动存在混乱的可能。例如:
 ----------------------------------------> Timeline ------------------------------------->
Thread X: --- Channel A (Event 2) --- Channel A (Event 1) ----------------------------->
Thread Y: --- Channel A (Event 3) --- Channel B (Event 2) --- Channel B (Event 3) --->
Thread Z: --- Channel B (Event 1) --- Channel B (Event 4) --- Channel A (Event 4) --->
        2) OrderedMemoryAwareThreadPoolExecutor 是 MemoryAwareThreadPoolExecutor 的子类。除了MemoryAwareThreadPoolExecutor 的功能之外,它还可以保证同一Channel中处理的事件流的顺序性(不同Channel使用不同的key保持事件顺序),这主要是控制事件在异步处理模式下可能出现的错误事件顺序,但它并不保证同一 Channel中的事件都在一个线程中执行(通常也没必要)。例如:

----------------------------------------> Timeline ---------------------------------------->
Thread X: --- Channel A (Event 1) --. .-- Channel B (Event 2) --- Channel B (Event 3) --->
\ /
X
/ \
Thread Y: --- Channel B (Event 1) --' '-- Channel A (Event 2) --- Channel A (Event 3) --->
二、具有可伸缩性的OrderedMemoryAwareThreadPoolExecutor使用策略
    在大多数情况下,我们会使用OrderedMemoryAwareThreadPoolExecutor,它的构造函数要求我们提供线程池的大小,在上面的代码中,我们使用了16这个具体的值,是一种很不好的写法,通常情况下,我们会使用配置文件使之可变,但是在实际部署时,并不能保证实施人员能很好的去调整,故提供如下的一种写法:
double coefficient = 0.8;  //系数
int numberOfCores = Runtime.getRuntime().availableProcessors();
int poolSize = (int)(numberOfCores / (1 - coefficient));

我们可以使用poolSize取代OrderedMemoryAwareThreadPoolExecutor(16, 1048576, 1048576)中的那个16,因为当一个系统被开发出来后,它是CPU密集型还是IO密集型是可评估的,通过评估其密集型,调整系数即可:CPU密集型接近0,IO密集型接近1。

Netty并发优化之ExecutionHandler的更多相关文章

  1. Nginx 之六: Nginx十万并发优化

    操作 操作 Nginx 之六: Nginx十万并发优化

  2. 性能调优之MYSQL高并发优化

    性能调优之MYSQL高并发优化   一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之 ...

  3. 【JAVA】高并发优化细节点

    高并发优化细节点: 微服务化 如何发现系统瓶颈?   如何高效利用有限内存: 使用基本类型 使用数组,不用集合 自定义map与数据结构   Integer—>int, Set<Intege ...

  4. LNMP环境并发优化

    LNMP环境并发优化 服务器 8核32Gx3 如图是一条http请求的生命周期,共经过nginx,php-fpm,PHP三个模块 所以我们可以从nginx,php-fpm,PHP三个维度去优化 一.p ...

  5. Tomcat并发优化和缓存优化

    Tomcat并发优化 1.调整连接器connector的并发处理能力 在Tomcat 配置文件 server.xml 中的 <Connector ... /> 配置中 1.参数说明 max ...

  6. Java高并发秒杀API之高并发优化

    ---恢复内容开始--- 第1章 秒杀系统高并发优化分析   1.为什么要单独获得系统时间 访问cdn这些静态资源不用请求系统服务器 而CDN上没有系统时间,需要单独获取,获取系统时间不用优化,只是n ...

  7. SSM实战——秒杀系统之高并发优化

    一:高并发点 高并发出现在秒杀详情页,主要可能出现高并发问题的地方有:秒杀地址暴露.执行秒杀操作. 二:静态资源访问(页面)优化——CDN CDN,内容分发网络.我们把静态的资源(html/css/j ...

  8. netty 并发访问测试配置

    linux – 1.查看有关的选项 /sbin/sysctl -a|grep net.ipv4.tcp_tw     net.ipv4.tcp_tw_reuse = 0     #表示开启重用.允许将 ...

  9. Java 进阶7 并发优化 5 并发控制板方法

    Java 进阶7 并发优化 5 并发控制板方法 20131114 前言:          Java 中多线程并发程序中存在线程安全的问题,之前学习 Java的同步机制,掌握的同步方法只有一种就是使用 ...

随机推荐

  1. Eclipse 保存代码时,不自动换行设置

    Eclipse在保存代码时,总是自动换行.尤其是注释,换行后的注释读起来就很混乱.后来发现是在保存文件时设置了自动格式化代码的原因. 关闭自动格式代码设置: windows-->Preferen ...

  2. 利用JavaFX访问MySQL数据库

    1. 创建数据库表 create table Course( courseId char(5), subjectId char(4) not null, courseNumber integer, t ...

  3. 洛谷 P1013 进制位 【搜索 + 进制运算】

    题目描述 著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字. 例如: + L K V E L L K V E K K V E KL V V E KL KK E E ...

  4. 【CodeChef】ForbiddenSum

    Portal --> CC ForbiddenSum Solution 场上想到了\(O(NM)\)的做法..然而并没有什么用 首先考虑比较简单的一个问题,给定一个数组\(A\),问这些数不能凑 ...

  5. Flash平台的分析与RIA的趋势

    10月3号,Flash Player 11 和 AIR 3.0正式提供下载,一片安静.最近这两年来,关于Flash的新闻一向是以负面为主,先是 Silverlight 的挑战,然后是 iphone和i ...

  6. phpstorm 自定义属性没语法提示的问题

    在右侧Options勾选上Custom HTML tag attributes,并且在下面的输入框输入自定义属性列表,逗号分隔.

  7. [DeeplearningAI笔记]序列模型3.6Bleu得分/机器翻译得分指标

    5.3序列模型与注意力机制 觉得有用的话,欢迎一起讨论相互学习~Follow Me 3.6Bleu得分 在机器翻译中往往对应有多种翻译,而且同样好,此时怎样评估一个机器翻译系统是一个难题. 常见的解决 ...

  8. [线索二叉树] [LeetCode] 不需要栈或者别的辅助空间,完成二叉树的中序遍历。题:Recover Binary Search Tree,Binary Tree Inorder Traversal

    既上篇关于二叉搜索树的文章后,这篇文章介绍一种针对二叉树的新的中序遍历方式,它的特点是不需要递归或者使用栈,而是纯粹使用循环的方式,完成中序遍历. 线索二叉树介绍 首先我们引入“线索二叉树”的概念: ...

  9. React读取Excel——js-xlsx 插件的使用

    介绍 SheetJS js-xlsx 是一款能够读写多种格式表格的插件,浏览器支持良好,并且能在多个语言平台上使用,目前在 github 上有 12602 个 star, 刚好项目中遇到了前端解析 e ...

  10. CF767 B. The Queue 贪心+细节

    LINK 题意:一个业务开始时间为s,结束时间为f,一个人办护照的时间需要m分(如果在x时开始服务,且x+m==f那么还是合法的),你可以选择任意时间到达,但如果你和其他人同时到达,你要排在他的后面. ...