前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Netty 线程模型

Netty 线程模型

作者头像
java404
发布2019-03-04 11:00:38
8000
发布2019-03-04 11:00:38
举报
文章被收录于专栏:java 成神之路java 成神之路

Reactor模型

Netty中的Reactor模型主要由多路复用器(Acceptor)、事件分发器(Dispatcher)、事件处理器(Handler)组成,可以分为三种。

常见的Reactor线程模型有三种,分别如下:

  • Reactor单线程模型
  • Reactor多线程模型
  • 主从Reactor多线程模型

Reactor 模式可以参考:Reactor模式详解+源码实现

1、单线程模型

所有I/O操作都由一个线程完成,即多路复用、事件分发和处理都是在一个Reactor线程上完成的,一个 Reactor 线程就是一个 NIO 线程。

Reactor 单线程模型使用的是一个 NIO 线程, NIO 使用的是非阻塞 I/O,所有的 I/O 操作都不会阻塞,所以一个线程可以处理多个 TCP 连接请求。

对于一些小容量应用场景,可以使用单线程模型,但是对于高负载、大并发的应用却不合适,主要原因如下:

  • 一个NIO线程同时处理成百上千的链路,性能上无法支撑。即便NIO线程的CPU负荷达到100%,也无法满足海量消息的编码、解码、读取和发送;
  • 当NIO线程负载过重之后,处理速度将变慢,这会导致大量客户端连接超时,超时之后往往进行重发,这更加重了NIO线程的负载,最终导致大量消息积压和处理超时,NIO线程会成为系统的性能瓶颈;
  • 可靠性问题。一旦NIO线程意外跑飞,或者进入死循环,会导致整个系统通讯模块不可用,不能接收和处理外部信息,造成节点故障。

2、Reactor多线程模型

Reactor多线程模型与单线程模型最大区别就是有一组 NIO 线程处理 I/O 操作,它的特点如下:

  • 有一个专门的 NIO 线程用于监听服务端,接收客户端的TCP连接请求;
  • 网络I/O读、写操作等由一个NIO线程池负责,线程池可以采用标准的 JDK 线程池实现(Netty 扩展了 JDK 线程池),它包含一个任务队列和N个可用的线程,由这些 NIO 线程负责消息的读取、解码、编码和发送;
  • 1 个 NIO 线程可以同时处理 N 条链路,但是 1 个链路只对应 1 个 NIO 线程,防止发生并发操作问题。

在绝大多数场景下,Reactor多线程模型都可以满足性能需求;但是,在极特殊应用场景中,一个NIO线程负责监听和处理所有的客户端连接可能会存在性能问题。例如百万客户端并发连接,或者服务端需要对客户端的握手信息进行安全认证,认证本身非常损耗性能。这类场景下,单独一个Acceptor线程可能会存在性能不足问题,为了解决性能问题,产生了第三种Reactor线程模型--主从Reactor多线程模型。

3、主从Reactor多线程模型

服务端用于接收客户端连接的不再是1个单独的NIO线程,而是一个独立的NIO线程池。Acceptor接收到客户端TCP连接请求处理完成后(可能包含接入认证等),将新创建的SocketChannel注册到I/O线程池(sub reactor线程池)的某个I/O线程上,由它负责SocketChannel的读写和编解码工作。

Acceptor线程池只用于客户端的登录、握手和安全认证,一旦链路建立成功,就将链路注册到后端subReactor线程池的I/O线程上,有I/O线程负责后续的I/O操作。

Netty 多线程模型

Netty 的线程模型并不是一成不变的,它实际取决于启动参数配置。通过设置不同的启动参数来支持 Reactor 不同的线程模型。Netty 支持 Reactor 单线程模型、多线程模型、主从多线程模型。

Netty 启动示例
代码语言:javascript
复制
    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .handler(new LoggingHandler(LogLevel.INFO))
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) {
                     ChannelPipeline p = ch.pipeline();
                     p.addLast(new DiscardServerHandler());
                 }
             });
            ChannelFuture f = b.bind(PORT).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

这里的是 示例是 Netty 服务端demo。

每一个 EventLoopGroup 都是 Reactor 的线程池。ServerBootstrap.group 需要接受两个参数 EventLoopGroup 参数。 一个是处理接收客户端的 TCP 连接(NIO 的 SelectionKey.OP_CONNECT),另一个是处理 I/O 相关的操作(NIO 的 SelectionKey.OP_READ, SelectionKey.OP_WRITE)。

Netty单线程模型
代码语言:javascript
复制
    EventLoopGroup group = new NioEventLoopGroup(1);
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(group, group);
        //或者 b.group(group);
        ......

创建只有一个线程的 Reactor 线程池。把处理接收客户端 TCP 连接的 Reactor 线程池和处理I/O相关操作的 Reactor 线程池都是使用这个只有一个线程的 Reactor 线程池。

Netty 多线程模型
代码语言:javascript
复制
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
        ......

创建两个 Reactor 线程池,处理客户端 TCP 连接的线程池只有1个线程,而处理 I/O 的Reactor 线程池有多个线程处理。不知道线程数则默认是 2* CPU 个数。

Netty 主从多线程模型
代码语言:javascript
复制
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
        ......

创建两个 Reactor 线程池,处理客户端 TCP 连接的线程池和处理 I/O 操作的线程池都是多个线程处理。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.02.12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Reactor模型
  • 1、单线程模型
  • 2、Reactor多线程模型
  • 3、主从Reactor多线程模型
  • Netty 多线程模型
    • Netty 启动示例
      • Netty单线程模型
        • Netty 多线程模型
          • Netty 主从多线程模型
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档