zoukankan      html  css  js  c++  java
  • Netty多线程处理机制

    技术点描述

    本文主要研究NioServerSocketChannelFactory类和NioDatagramChannelFactory类,

    以及这两个类的各自作用。

        由于基于pipelineFactory的线程池的配置已在前一节(Netty中execution包功能详解 )中做了详细说明,而channelFactory中的线程池的配置并未做说明,本文档重点阐述channelFactory的线程池配置。NioServerSocketChannelFactory主要应用于TCP协议的数据处理,NioDatagramChannelFactory主要应用于UDP协议的数据处理。

    实现方案

    简单介绍一下实现该功能,使用了哪些技术或知识点

    参考源码包

    以下是对这两个类的具体说明以及相关类,重要的常用的方法的说明

    1. NioServerSocketChannelFactory

    此类常用于创建TCP的ServerBootstrap时作为构造方法的参数使用。

    调用方式及设置如下:

    1 ChannelFactory TCPCHANNEL_FACTORY = new NioServerSocketChannelFactory(
    2 
    3 Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
    4 
    5 ServerBootstrap TCPSERVER_BOOTSTRAP = new ServerBootstrap(TCPCHANNEL_FACTORY);

    基于NIO的用于创建服务器端channelchannelFactory,这个类利用非阻塞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也要释放掉。因此,如果想要优雅的关闭一个服务,需要做一下事情:

    1. factory创建的channels执行解绑(unbind)操作
    2. 关闭所有的由解绑的channels处理的子channels(这两步目前通常通过ChannelGroup.close()来操作)
    3. 调用releaseExternalResources()方法

    请确保在所有的channels都关闭前不要关闭executor,否则,会报RejectedExecutionException异常而且相关资源可能不会被释放掉。

    在此类中,最关键的构造方法:

     1 public NioServerSocketChannelFactory(
     2 
     3 Executor bossExecutor, WorkerPool<NioWorker> workerPool) {
     4 
     5 if (bossExecutor == null) {
     6 
     7 throw new NullPointerException("bossExecutor");
     8 
     9 }
    10 
    11 if (workerPool == null) {
    12 
    13 throw new NullPointerException("workerPool");
    14 
    15 }
    16 
    17  
    18 
    19 this.bossExecutor = bossExecutor;
    20 
    21 this.workerPool = workerPool;
    22 
    23 sink = new NioServerSocketPipelineSink(workerPool);
    24 
    25 }

    参数说明:

    bossExecutor:默认推荐设置为Executors.newCachedThreadPool()

    workerPool:可通过new NioWorkerPool(workerExecutor, workerCount, true)创建,workerExecutor默认推荐设置为Executors.newCachedThreadPool()workerCount可设置为Runtime.getRuntime().availableProcessors() * 2(默认)

    关于其中的NioWorkerPool类和NioServerSocketPipelineSink类,将在下文给予说明。

    1. NioWorkerPool

    此类的关键方法是super的AbstractNioWorkerPool,

    构造方法:

    1 AbstractNioWorkerPool(Executor workerExecutor, int workerCount, boolean allowShutDownOnIdle) {
    2 
    3 4 
    5 }

    参数说明:

    workerExecutor:worker线程的Executor

    workerCount:最多创建的worker线程数

    allowShutDownOnldle:空闲时是否关闭线程

    1. NioServerSocketPipelineSink

    内部组件,传输服务的一个实现类,大多数情况下,不对用户开放。

    1. NioDatagramChannelFactory

    此类常用于创建UDP的ServerBootstrap时作为构造方法的参数使用。

    调用方式及设置如下:

    1 ChannelFactory UDPCHANNEL_FACTORY = new NioDatagramChannelFactory()
    2 
    3 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)设置

  • 相关阅读:
    Saltstack module apache 详解
    Saltstack module ip 详解
    Saltstack module iosconfig 详解
    Saltstack module introspect 详解
    Saltstack module inspector 详解
    Saltstack module ini 详解
    Saltstack module incron 详解
    Modbus 指令 RS485指令规则
    停车系统对接第三方在线支付平台(二)
    停车系统对接第三方在线支付平台
  • 原文地址:https://www.cnblogs.com/wq920/p/3711237.html
Copyright © 2011-2022 走看看