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

    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)设置

     
     
  • 相关阅读:
    ipmitool常用命令
    linux系统/var/log目录下的信息详解
    查看vnc server的日志
    Hp服务器 iLO3 使用方法
    phalcon builder 用法
    cobbler pxe-menu
    几种session存储方式比较
    parse arguments in bash
    No breeds found in the signature, a signature update is recommended
    Mybatis-plus使用分页进行分页查询
  • 原文地址:https://www.cnblogs.com/tiancai/p/9959342.html
Copyright © 2011-2022 走看看