netty线程调度定制

1、netty的线程调度问题

在netty的TCP调度中,线程的调度封装在NioEventLoopGroup中,线程执行则封装在NioEventLoop中。
线程调度规则封装在MultithreadEventExecutorGroup的next方法中,这个方法又封装了EventExecutorChooserFactory(实现在DefaultEventExecutorChooserFactory)的next方法。
结果就是轮换着用线程。
在这里插入图片描述
如果我们在2个线程上按顺序发送了三个http请求:请求1、请求2、请求3.
其中请求1耗时较长,请求2很快处理完成,我们就希望请求3能由线程2处理,而不是在请求1后面排队。但实际上netty把请求3分配给了线程1:
在这里插入图片描述

2、解决方法

为了解决请求被netty线程阻塞的问题,要么定制EventExecutorChooserFactory要么定制NioEventLoopGroup。由于定制EventExecutorChooserFactory入参较复杂,所以我们选择定制NioEventLoopGroup,定制的对象名为CustomEventLoopGroup,代码如下:

/*用来判断线程状态,有的请求响应耗时较长,netty默认的next实现是无脑轮换,
* 那么 有空闲线程也可能选择到正在执行任务的线程  导致原本可以快速返回的请求在慢请求后面等待
* 优先选择空闲线程  如果没有空闲线程则按照原来netty逻辑选择
* 但是客户端应该尽量不同业务使用不同的长连接 */
public class CustomEventLoopGroup extends NioEventLoopGroup {static final Logger logger = Logger.getLogger(CustomEventLoopGroup.class);public CustomEventLoopGroup(int nThreads, Executor executor) {super(nThreads, executor);}@Overridepublic EventLoop next() {EventLoop elNext = null;EventLoop el = super.next();    elNext = el;do {          if (elNext instanceof NioEventLoop nioEvent) {logger.debug("pendingTasks: " + nioEvent.pendingTasks());ThreadProperties threadInfo = nioEvent.threadProperties();logger.debug("[" + threadInfo.id() + "] threadInfo.state: " + threadInfo.state());if (threadInfo.state() == Thread.State.RUNNABLE) {return elNext;}}elNext = super.next();if (elNext == null) {return el;}if (elNext.equals(el)) {return el;}} while (true);}
}

服务器使用CustomEventLoopGroup代码如下:

public NettyServerHttp1(int portIn) {port = portIn;EventLoopGroup bossGroup = new NioEventLoopGroup(1);ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);EventLoopGroup workerGroup = new CustomEventLoopGroup(2, executor);try {ServerBootstrap b = new ServerBootstrap();b.option(ChannelOption.SO_BACKLOG, 1024);b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.DEBUG)).childHandler(new NettyServerInitializer(null));Channel ch = b.bind(port).sync().channel();ch.closeFuture().sync();} catch (InterruptedException e) {logger.error("Server start err: " + e);logger.error(e.getStackTrace());} finally {logger.info("Server Shutdown!");bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/289108.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql:查看服务端没有睡眠的线程数量

使用命令show global status like Threads_running;可以查看服务端没有睡眠的线程数量。 例如:

【华为OD机试真题2023CD卷 JAVAJS】加密算法

华为OD2023(C&D卷)机试题库全覆盖,刷题指南点这里 加密算法 知识点DFS搜索 题目描述: 有一种特殊的加密算法,明文为一段数字串,经过密码本查找转换,生成另一段密文数字串。规则如下: 1. 明文为一段数字串由0~9组成 2. 密码本为数字0~9组成的二维数组 3. 需要…

Swift 周报 第四十期

文章目录 前言新闻和社区53.5亿美元!传苹果今明两年或将采购 2.3 万台 AI 服务器!TestFlight 让管理测试员变得更加简单推送通知控制面板现已推出新交付指标Apple Vision Pro 开发者实验室现已扩展到纽约市和悉尼 提案正在审查的提案 Swift论坛推荐博文话…

vue打包内存问题解决办法<--- Last few GCs ---><--- JS stacktrace --->

**<— Last few GCs —> [18484:0000026763669610] 106760 ms: Mark-sweep 4016.0 <— JS stacktrace —> FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory** 解决办法&#xff1a; set NODE_OPTION…

Android 架构 - 组件化

一、概念 组件化是对单个功能进行开发&#xff0c;使得功能可以复用。将多个功能组合起来就是一个业务模块&#xff0c;因此去除了模块间的耦合&#xff0c;使得按业务划分的模块成了可单独运行的业务组件。&#xff08;一定程度上的独立&#xff0c;还是依附于整个项目中&…

watermark-dom 水印不显示

引入watermark-dom 之后&#xff0c;代码也按照文档写好了&#xff0c;也有水印的元素了&#xff0c;但是就是不显示水印 查看元素&#xff0c;发现shadow-root 里面啥也没有 查看源代码发现 shadowRoot 添加水印的这行代码根本没执行 接着往上查&#xff0c;发现没有进入这个…

迪文屏开发保姆级教程——页面键盘

迪文屏页面键盘保姆级教程。 本篇文章主要介绍了在DGBUS平台上使用页面键盘的步骤。 迪文屏官方开发指南PDF&#xff1a;&#xff08;不方便下载的私聊我发给你&#xff09; https://download.csdn.net/download/qq_21370051/88647174?spm1001.2014.3001.5503https://downloa…

redis基本用法学习(字符串类型基本操作)

字符串类型是redis支持的最简单的数据类型&#xff0c;同时最简单的键值对类型也是key和value都是单个字符串&#xff0c;本质上就是字符串之间的相互映射&#xff0c;redis官网String类型简介页面提到可以用于缓存HTML片段或页面内容。   redis支持设置/获取单个键值对&…

聚类算法及可视化方法的实践与探索

簇内平方和表示数据点到其簇内质心的距离的平方和&#xff0c;公式如下&#xff1a; 其中&#xff0c; 是k簇数&#xff0c; ni是第 i 个簇的样本数&#xff0c; xij是第 i个簇中的第 j 个样本。 import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sk…

带你深入解析 Compose 的 Modifier 原理 -- Modifier、CombinedModifier

Modifier 的含义 实际开发过程中&#xff0c;随处可见各种 Modifier&#xff0c;比如&#xff1a; Modifier.size() // 尺寸Modifier.width() // 宽度Modifier.height() // 高度Modifier.padding() // 间距Modifier.background() // 背景Modifier.…

Go项目快速集成Swagger UI

swag Swag将Go的注释转换为Swagger2.0文档。我们为流行的 Go Web Framework 创建了各种插件&#xff0c;这样可以与现有Go项目快速集成&#xff08;使用Swagger UI&#xff09;。 目录 快速开始支持的Web框架如何与Gin集成格式化说明开发现状声明式注释格式 通用API信息API操…

[Angular] 笔记 3:ngIf

ngIf 是 Angular 的行为指令。 基本写法&#xff1a;<div *ngIf"hero" class"name">{{ hero.name }} </div> 当 ngIf 表达式求值为 truthy 时&#xff0c;Angular会渲染在then子句中提供的模板&#xff1b;当为falsy 时&#xff0c;Angular会…