前言

我们在使用Netty进行服务端开发的时候,一般来说会定义两个NioEventLoopGroup线程池,一个"bossGroup"线程池去负责处理客户端连接,一个"workGroup"线程池去负责处理读写操作。那么,我们为什么要这么做呢?这样做的好处是什么呢?能不能只使用一个NioEventLoopGroup呢?这就是我们今天要讨论的主题——Netty的线程模型

Reactor线程模型

实际上Netty线程模型就是Reactor模式的一个实现,而Reactor模式又是什么呢?

Reactor模式是基于事件驱动开发的,核心组成部分包括Reactor和线程池,其中Reactor负责监听和分配事件,线程池负责处理事件,而根据Reactor的数量和线程池的数量,又将Reactor分为三种模型:

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

单线程模型

  • Reactor内部通过selector 监控连接事件,收到事件后通过dispatch进行分发,如果是连接建立的事件,则由Acceptor处理,Acceptor通过accept接受连接,并创建一个Handler来处理连接后续的各种事件,如果是读写事件,直接调用连接对应的Handler来处理
  • Handler完成read->(decode->compute->encode)->send的业务流程
  • 这种模型好处是简单,坏处却很明显,当某个Handler阻塞时,会导致其他客户端的handler和accpetor都得不到执行,无法做到高性能,只适用于业务处理非常快速的场景

多线程模型

  • 主线程中,Reactor对象通过selector监控连接事件,收到事件后通过dispatch进行分发,如果是连接建立事件,则由Acceptor处理,Acceptor通过accept接收连接,并创建一个Handler来处理后续事件,而Handler只负责响应事件,不进行业务操作,也就是只进行read读取数据和write写出数据,业务处理交给一个线程池进行处理
  • 线程池分配一个线程完成真正的业务处理,然后将响应结果交给主进程的Handler处理,Handler将结果send给client (下面是核心代码)

单Reactor承当所有事件的监听和响应,而当我们的服务端遇到大量的客户端同时进行连接,或者在请求连接时执行一些耗时操作,比如身份认证,权限检查等,这种瞬时的高并发就容易成为性能瓶颈

主从多线程模型 (最流行)

  • 存在多个Reactor,每个Reactor都有自己的selector选择器,线程和dispatch
  • 主线程中的mainReactor通过自己的selector监控连接建立事件,收到事件后通过Accpetor接收,将新的连接分配给某个子线程
  • 子线程中的subReactor将mainReactor分配的连接加入连接队列中通过自己的selector进行监听,并创建一个Handler用于处理后续事件
  • Handler完成read->业务处理->send的完整业务流程

一、Netty线程模型

/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.study.hc.net.netty; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.GenericFutureListener; /**
* Echoes back any received data from a client.
*/
public final class EchoServer {
static final int PORT = Integer.parseInt(System.getProperty("port", "8080")); public static void main(String[] args) throws Exception {
// Configure the server.
// 创建EventLoopGroup accept线程组 NioEventLoop
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
// 创建EventLoopGroup I/O线程组
EventLoopGroup workerGroup2 = new NioEventLoopGroup(1);
try {
// 服务端启动引导工具类
ServerBootstrap b = new ServerBootstrap();
// 配置服务端处理的reactor线程组以及服务端的其他配置
b.group(bossGroup, workerGroup2).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.DEBUG)).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(new EchoServerHandler());
}
});
// 通过bind启动服务
ChannelFuture f = b.bind(PORT).sync();
// 阻塞主线程,知道网络服务被关闭
f.channel().closeFuture().sync();
} finally {
// 关闭线程组
bossGroup.shutdownGracefully();
workerGroup2.shutdownGracefully();
}
}
}

Java后端进阶-网络编程(Netty线程模型)的更多相关文章

  1. Java后端进阶-网络编程(Netty零拷贝机制)

    package com.study.hc.net.netty.demo; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled ...

  2. Java后端进阶-网络编程(NIO/BIO)

    Socket编程 BIO网络编程 BIO Server package com.study.hc.net.bio; import java.io.BufferedReader; import java ...

  3. Java后端进阶-网络编程(Netty责任链Pipeline)

    设计模式-责任链模式 一个责任链模拟demo package com.study.hc.net.netty.demo; // -----链表形式调用------netty就是类似的这种形式 publi ...

  4. eventloop & actor模式 & Java线程模型演进 & Netty线程模型 总结

    eventloop的基本概念可以参考:http://www.ruanyifeng.com/blog/2013/10/event_loop.html Eventloop指的是独立于主线程的一条线程,专门 ...

  5. Java高并发网络编程(四)Netty

    在网络应用开发的过程中,直接使用JDK提供的NIO的API,比较繁琐,而且想要进行性能提升,还需要结合多线程技术. 由于网络编程本身的复杂性,以及JDK API开发的使用难度较高,所以在开源社区中,涌 ...

  6. Java网络编程 -- Netty入门

    Netty简介 Netty是一个高性能,高可扩展性的异步事件驱动的网络应用程序框架,它极大的简化了TCP和UDP客户端和服务器端网络开发.它是一个NIO框架,对Java NIO进行了良好的封装.作为一 ...

  7. Netty系列之Netty线程模型

    Reference: http://www.infoq.com/cn/articles/netty-threading-model 1. 背景 1.1. Java线程模型的演进 1.1.1. 单线程 ...

  8. Java学习之网络编程实例

    转自:http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html 多谢分享 网络编程 网络编程对于很多的初学者来说,都是很向往的一 ...

  9. 彻底搞懂 netty 线程模型

    编者注:Netty是Java领域有名的开源网络库,特点是高性能和高扩展性,因此很多流行的框架都是基于它来构建的,比如我们熟知的Dubbo.Rocketmq.Hadoop等.本文就netty线程模型展开 ...

随机推荐

  1. NGK项目八大板块是什么?

    公链项目生态各板块中,应用生态繁荣与实体经济联系作为密切,也被看做公链平台追求的终极目标,NGK公链以实体企业粘合客户,致力于重塑金融体系,构建全球区块链生态. NGK让经济权益上链发行,目前已有八大 ...

  2. [Python] Matplotlib 图表的绘制和美化技巧

    目录 在一张画布中绘制多个图表 加图表元素 气泡图 组合图 直方图 雷达图 树状图 箱形图 玫瑰图 在一张画布中绘制多个图表 Matplotlib模块在绘制图表时,默认先建立一张画布,然后在画布中显示 ...

  3. Tawk.to一键给自己的网站增加在线客服功能

    Tawk.to一键给自己的网站增加在线客服功能 很多外贸网站只有contact页面,留下邮箱.电话等联系方式,而在国际贸易当中能够及时在线交流沟通,能给客户留下更好的印象.接下来,就让我们一起来了解一 ...

  4. mybatis 一对多和多对一 简单案例笔记

    以案例说明(以下案例代码都敲过验证过) 多对一(多个学生对一个老师  即学生集合中都存一个老师对象) Mybatis多对一实现方式1: //定义Student 和 Teacher 实体 @Data p ...

  5. 详细探秘Linux 和 Window 双系统访问Windows 磁盘需要输入密码问题解决过程分析

    将要讲很多的内容真正产生作用的配置就只有下面这一句而已.如果你只是想要解决问题看这一句就行了,后面都没有必要在看下去了. 将allow-active标签中的auth_admin_keep 改为 yes ...

  6. SpringBoot使用谷歌方式生成图片验证码

    1.新建一个springboot的项目 2.导入坐标 <dependency> <groupId>com.github.penggle</groupId> < ...

  7. PHP Webshell List

    目录 基础类 编码替换 无关键字函数类型 躲避检测记录 MySQL写入一句话 基础类 很容易被扫描.检测出来 <?php @eval($_GET['phpcode']);?> <?p ...

  8. h5返回上一页ios页面不刷新

    var isPage=false; window.addEventListener('pageshow', function () {         if (isPage) { window.loc ...

  9. 剑指 Offer 59 - I. 滑动窗口的最大值 + 双指针 + 双端队列

    剑指 Offer 59 - I. 滑动窗口的最大值 Offer_59_1 题目详情 方法一:暴力方法+双指针 package com.walegarrett.offer; /** * @Author ...

  10. Java 读取Word文本框中的文本/图片/表格

    Word可插入文本框,文本框中可嵌入文本.图片.表格等内容.对文档中的已有文本框,也可以读取其中的内容.本文以Java程序代码来展示如何读取文本框,包括读取文本框中的文本.图片以及表格等. [程序环境 ...