前言

我们在使用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 Global启动大会圆满举办

    近日,由星盟全球投资公司.灵石团队联合主办的NGK Global全球生态启动大会圆满开幕.大会汇集区块链领域.金融领域.密码学领域.智能算法领域等众多大咖,和NGK Global全球价值共识者共聚一堂 ...

  2. JDK源码阅读-Reference

    本文转载自JDK源码阅读-Reference 导语 Java最初只有普通的强引用,只有对象存在引用,则对象就不会被回收,即使内存不足,也是如此,JVM会爆出OOME,也不会去回收存在引用的对象. 如果 ...

  3. 开源OA办公系统的“应用市场”,能够为协同办公开拓什么样的“前路”?

    在我们的日常生活中,应用市场这个词,总是与智能手机划上等号,不管使用的是iPhone还是安卓,总会接触到手机上的APP应用市场,我们可以在应用市场中,选择自己所需要的APP应用软件,下载使用后,可以让 ...

  4. Vue学习笔记-基于CDN引入方式简单前后端分离项目学习(Vue+Element+Axios)

    一  使用环境 开发系统: windows 后端IDE: PyCharm 前端IDE: VSCode 数据库: msyql,navicat 编程语言: python3.7  (Windows x86- ...

  5. SpringBoot读取配置文件的内容

    1.@Value读取 在springboot项目中,如果要读取配置文件application.properties或application.yml文件的内容,可以使用自带的注解@Value.以prop ...

  6. DRF 三大认证的配置及使用方法

    目录 三大认证 一.身份认证 1.身份认证配置 1.1 全局配置身份认证模块 1.2 局部配置身份认证模块 2.drf提供的身份认证类(了解) 3.rf-jwt提供的身份认证类(常用) 4.自定义身份 ...

  7. dpi dp px 换算关系

    getResources().getDisplayMetrics().densityDpi 就是屏幕密度.getResources().getDisplayMetrics().density 也可以理 ...

  8. Linux没有ens33解决方案

    一.前言 运行环境:window10+VMware14+Centos7 博主最近遇到一个比较郁闷的问题,在虚拟机上操作Linux系统查看IP的时候,发现没有ens33或者eth0了,试了很多办法都没有 ...

  9. Markdown(1)介绍

    一.简介 ​ Markdown 是一种轻量级标记语言,通过简单的标记语法使纯文本内容具有一定格式,使用户可以用易读易写的纯文本格式编写文档. ​ Markdown 语言在 2004 由约翰·格鲁伯(英 ...

  10. CentOS rpm常用功能记录

    CentOS7主要有rpm和yum这两种包软件的管理.两者有功能上的区别,其中主要区别是:yum使用简单但需要联网,yum会去网上包源去获取所需要的软件包.而rpm的需要做的事情就更细一些,比如我们需 ...