Netty多线程处理机制
技术点描述
本文主要研究NioServerSocketChannelFactory类和NioDatagramChannelFactory类,
以及这两个类的各自作用。
由于基于pipelineFactory的线程池的配置已在前一节(Netty中execution包功能详解 )中做了详细说明,而channelFactory中的线程池的配置并未做说明,本文档重点阐述channelFactory的线程池配置。NioServerSocketChannelFactory主要应用于TCP协议的数据处理,NioDatagramChannelFactory主要应用于UDP协议的数据处理。
实现方案
简单介绍一下实现该功能,使用了哪些技术或知识点
参考源码包
以下是对这两个类的具体说明以及相关类,重要的常用的方法的说明
NioServerSocketChannelFactory
此类常用于创建TCP的ServerBootstrap时作为构造方法的参数使用。
调用方式及设置如下:
ChannelFactory TCPCHANNEL_FACTORY = new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ServerBootstrap TCPSERVER_BOOTSTRAP = new ServerBootstrap(TCPCHANNEL_FACTORY);
基于NIO的用于创建服务器端channel的channelFactory,这个类利用非阻塞I/O模式引入NIO,这样可以有效地向多个并发连接提供Channel
线程的工作模式:
在此类中,有两种类型的线程,一种是boss线程,另一种是worker线程
Boss线程:
每个server服务器都会有一个boss线程,每绑定一个InetSocketAddress都会产生一个boss线程,比如:我们开启了两个服务器端口80和443,则我们会有两个boss线程。一个boss线程在端口绑定后,会接收传进来的连接,一旦连接接收成功,boss线程会指派一个worker线程处理连接。
Worker线程:
一个NioServerSocketChannelFactory会有一个或者多个worker线程。一个worker线程在非阻塞模式下为一个或多个Channels提供非阻塞 读或写
线程的生命周期和优雅的关闭
在NioServerSocketChannelFactory被创建的时候,所有的线程都会从指定的Executors中获取。Boss线程从bossExecutor中获取,worker线程从workerExecutor中获取。因此,我们应该准确的指定Executors可以提供足够数量的线程,最好的选择就是指定一个cached线程池(It is the best bet to specify a cached thread pool)。
此处发现所有源码中的例子(example)中均设置为Executors.newCachedThreadPool()
Boss线程和worker线程都是懒加载,没有程序使用的时候要释放掉。当boss线程和worker线程释放掉的时候,所有的相关资源如Selector也要释放掉。因此,如果想要优雅的关闭一个服务,需要做一下事情:
- 对factory创建的channels执行解绑(unbind)操作
- 关闭所有的由解绑的channels处理的子channels(这两步目前通常通过ChannelGroup.close()来操作)
- 调用releaseExternalResources()方法
请确保在所有的channels都关闭前不要关闭executor,否则,会报RejectedExecutionException异常而且相关资源可能不会被释放掉。
在此类中,最关键的构造方法:
public NioServerSocketChannelFactory(
Executor bossExecutor, WorkerPool<NioWorker> workerPool) {
if (bossExecutor == null) {
throw new NullPointerException("bossExecutor");
}
if (workerPool == null) {
throw new NullPointerException("workerPool");
}
this.bossExecutor = bossExecutor;
this.workerPool = workerPool;
sink = new NioServerSocketPipelineSink(workerPool);
}
参数说明:
bossExecutor:默认推荐设置为Executors.newCachedThreadPool()
workerPool:可通过new NioWorkerPool(workerExecutor, workerCount, true)创建,workerExecutor默认推荐设置为Executors.newCachedThreadPool(),workerCount可设置为Runtime.getRuntime().availableProcessors() * 2(默认)
关于其中的NioWorkerPool类和NioServerSocketPipelineSink类,将在下文给予说明。
NioWorkerPool
此类的关键方法是super的AbstractNioWorkerPool,
构造方法:
AbstractNioWorkerPool(Executor workerExecutor, int workerCount, boolean allowShutDownOnIdle) {
…
}
参数说明:
workerExecutor:worker线程的Executor
workerCount:最多创建的worker线程数
allowShutDownOnldle:空闲时是否关闭线程
NioServerSocketPipelineSink
内部组件,传输服务的一个实现类,大多数情况下,不对用户开放。
NioDatagramChannelFactory
此类常用于创建UDP的ServerBootstrap时作为构造方法的参数使用。
调用方式及设置如下:
ChannelFactory UDPCHANNEL_FACTORY = new NioDatagramChannelFactory() ConnectionlessBootstrap UDPSERVER_BOOTSTRAP = new ConnectionlessBootstrap(UDPCHANNEL_FACTORY);
这个类利用非阻塞I/O模式引入NIO,这样可以有效地向多个并发连接提供Channel
此类仅有一种线程类型:worker线程。一个NioDatagramChannelFactory可创建一个或多个worker线程,一个worker线程在非阻塞模式下为一个或多个Channels提供非阻塞 读或写
在NioDatagramChannelFactory被创建的时候,所有的线程都会从指定的Executors中获取
因此,我们应该准确的指定Executors可以提供足够数量的线程,最好的选择就是指定一个cached线程池(It is the best bet to specify a cached thread pool)。
所有的worker线程都是懒加载,没有程序使用的时候要释放掉。当worker线程释放掉的时候,所有的相关资源如Selector也要释放掉。因此,如果想要优雅的关闭一个服务,需要做一下事情:
通常通过ChannelGroup.close()来关闭所有的由此factory创建的channels
调用releaseExternalResources()方法
请确保在所有的channels都关闭前不要关闭executor,否则,会报RejectedExecutionException异常而且相关资源可能不会被释放掉。
不支持多播模式,如果需要多播模式支持,采用OioDatagramChannelFactory替代
以下是此类中的最重要的构造方法:
public NioDatagramChannelFactory(WorkerPool<NioDatagramWorker> workerPool, InternetProtocolFamily family) {
…
}
参数说明:
workerPool:参考NioServerSocketChannelFactory
family:网络协议系列,这个参数是为了UDP的多播模式的,此参数只在java7+版本才有效。默认为null,可通过StandardProtocolFamily.INET(Ipv4)或者StandardProtocolFamily.INET6(Ipv6)设置
Netty多线程处理机制的更多相关文章
- Netty 超时机制及心跳程序实现
Netty 超时机制的介绍 Netty 的超时类型 IdleState 主要分为: ALL_IDLE : 一段时间内没有数据接收或者发送 READER_IDLE : 一段时间内没有数据接收 WRITE ...
- netty心跳机制测试
netty中有比较完善的心跳机制,(在基础server版本基础上[netty基础--基本收发])添加少量代码即可实现对心跳的监测和处理. 1 server端channel中加入心跳处理机制 // Id ...
- 连接管理 与 Netty 心跳机制
一.前言 踏踏实实,动手去做,talk is cheap, show me the code.先介绍下基础知识,然后做个心跳机制的Demo. 二.连接 长连接:在整个通讯过程,客户端和服务端只用一个S ...
- Netty心跳机制
一.概念介绍网络中的接收和发送数据都是使用操作系统中的SOCKET进行实现.但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题.可是如何判断这个套接字是否还可以使用呢?这个就需要在系统 ...
- NETTY 心跳机制
最近工作比较忙,但闲暇之余还是看了阿里的冯家春(fengjiachun)的github上的开源代码Jupiter,写的RPC框架让我感叹人外有人,废话不多说,下面的代码全部截取自Jupiter,写了一 ...
- 数据库的设计:深入理解 Realm 的多线程处理机制
你已经阅读过 Realm 关于线程的基础知识.你已经知道了在处理多线程的时候你不需要关心太多东西了,因为强大的 Realm 会帮你处理好这些,但是你还是很想知道更多细节…… 你想知道在 Realm 的 ...
- 浅谈利用PLSQL的多线程处理机制,加快处理大数据表的效率
我们在处理大数据表的时候经常会感觉的处理速度不够快,效率不够高,那么今天下面我就来简单实现下PLSQL的多线程编程处理数据: 我模拟一个简单的场景,把某一张表中的数据(当然这张表的数据非常大)同步到目 ...
- netty心跳机制和断线重连(四)
心跳是为了保证客户端和服务端的通信可用.因为各种原因客户端和服务端不能及时响应和接收信息.比如网络断开,停电 或者是客户端/服务端 高负载. 所以每隔一段时间 客户端发送心跳包到客户端 服务端做出心 ...
- netty心跳机制解决
直接看别个的源码:https://blog.csdn.net/xt8469/article/details/84827443>>https://blog.csdn.net/xt8469/a ...
随机推荐
- RESTful 服务架构风格 * .NET的RESTful框架 OpenRasta
REST 的约束采用的就是掌控 Web 的基本原则.这些原则是: 用户代理与资源交互,任何可命名和表达的事物都可称为资源.每项资源都有一个唯一的统一资源标识符 (URI). 与资源的交互(通过其唯一的 ...
- 有道单词本添加js实现自动阅读单词
个人比较习惯使用有道,使用了一段时间,背单词的时候很不方便 而有道单词客户Duan没有自动阅读的功能, 本菜用强大的js实现了简单的自动下一个单词的功能, 方法:第一步打开有道路径下的" ...
- SVN之文件同步更新
在SVN的实际使用上,我有这样的一个需求,同一份保存在SVN库的文件,要求取出在不同的地方,并且仍然要保持同步.根据这样的需求,可以具体分为以下两种情况,下面以库文件A,副本文件A1和副本文件A2,来 ...
- xamarin android——数据绑定到控件(三)
如果当前活动中,只存在一个listview视图,可以借助ListActivity快速的实现一个列表,即当前Activity继承ListActivity.在OnCreate方法中简单的两行代码,就可以创 ...
- Nginx日志按天分割
核心思想:使用crontab在每日23:59执行日志分割. 1.配置nginx日志信息,vim /etc/logrotate.d/nginx /var/log/nginx/*.log { nocomp ...
- html的3要素
在HTML标记语言中可以将每个网页源码分成3部分: 1.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" &q ...
- div嵌套引起的margin-top不起作用(转)
嵌套div中margin-top转移问题的解决办法在这两个浏览器中,有两个嵌套关系的div,如果外层div的父元素padding值为0,那么内层div的margin-top或者margin-botto ...
- Cookie和Seesion的区别
一.Cookie对象: 1.Cookie是由网络服务器发送出来,存在在浏览器上,它是个存储在浏览器目录中的文本文件.当浏览该cookie对应的站点时,cookie作为http头部文件的一部分在浏览器和 ...
- KnockoutJS(4)-控制文本和外观绑定
控制文本和外观绑定 依赖关系:除了Knockout核心库之外,无依赖关系. 类别 目的 Visible绑定 Visible绑定通过绑定一个值来确定DOM元素显示或隐藏 Text绑定 Text绑定主要是 ...
- PHPExcel导出excel文件
今天园子刚开,先来个货顶下,后续园丁qing我会再慢慢种园子的,希望大家多来园子逛逛. PHPExcel导出excel文件,先说下重要的参数要记住的东西 impUser() 导入方法 exportEx ...