Netty简介
Netty
- Netty初体验
- 基础概念
- Reactor模型
- 传统的阻塞IO模型
- 基础Reactor模型
- 多线程Reactor模型
为什么要使用Netty?
(NIO的框架,用于解决高并发出现的问题)

*BIO:同步且阻塞的IO
NIO:同步且非阻塞的IO(不是说线程)
AIO:异步且非阻塞的IO
还没有实现业务,光写整个流程就非常繁琐。NIO除了实现起来复杂之外,还存在一些需要解决的棘手问题,比如客户端断线重连如何实现,心跳处理(客户端在一定的时间内,不断的向服务器发送信息告诉服务器还在)、半包读写处理等等一些列问题,此时需要有这么一个框架,用于解决和优化NIO存在的问题,它就是Netty。
目的:客户端越来越多,随着客户端的增多,代码的复杂程度就变高,netty帮我们降低了编写nio的代码复杂程度*
Netty初体验
第一步:引入依赖
<dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.35.Final</version></dependency>
</dependencies>
服务器端
public class NettyServer {public static void main(String[] args) throws Exception {//创建只处理连接请求的线程组EventLoopGroup bossGroup = new NioEventLoopGroup(10);//创建只处理客户端读写业务的线程组EventLoopGroup workGroup = new NioEventLoopGroup(10);//创建服务端启动对象ServerBootstrap bootstrap = new ServerBootstrap();//配置参数bootstrap.group(bossGroup,workGroup)//使用NioServerSocketChannel作为服务器的通道实现.channel(NioServerSocketChannel.class)//配置用于存放因没有空闲线程导致连接请求被暂存放到队列中的队列长度.option(ChannelOption.SO_BACKLOG,1024)//创建通道初始化的对象并配置该对象,向该对象中添加处理器来实现具体的业务.childHandler(new ChannelInitializer<SocketChannel>() {//初始化通道@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//添加处理器,处理器里面是真正处理业务的ch.pipeline().addLast(new NettyServerHandler());}});//配置groupSystem.out.println("Netty服务器启动了");//同步阻塞地启动服务器ChannelFuture channelFuture = bootstrap.bind(9090).sync();//只要服务没关闭,该方法会一直阻塞channelFuture.channel().closeFuture().sync();System.out.println("================a");bossGroup.shutdownGracefully();workGroup.shutdownGracefully();}
}
public class NettyServerHandler extends ChannelInboundHandlerAdapter {//当有客户端发送数据来的时候该方法就会被调用@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf = (ByteBuf) msg;System.out.println("客户端发送的数据:"+buf.toString(StandardCharsets.UTF_8));}//读完数据之后调用的方法:发送数据给客户端@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {//创建携带的ByteBuf对象ByteBuf buf = Unpooled.copiedBuffer("hello client".getBytes(StandardCharsets.UTF_8));ctx.writeAndFlush(buf);}//异常捕获@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {System.out.println(cause.getMessage());ctx.close();}
}
客户端
public class NettyClient {public static void main(String[] args) throws Exception {//创建一个线程组用于事件循环EventLoopGroup eventLoopGroup = new NioEventLoopGroup();//创建客户端启动对象Bootstrap bootstrap = new Bootstrap();//设置相关参数bootstrap.group(eventLoopGroup)//使用NioSocketChannel作为客户端的通道实现.channel(NioSocketChannel.class)//创建通道初始化对象并设置handler业务处理器.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//添加处理器,处理器里面是实现具体业务的ch.pipeline().addLast(new NettyClientHandler());}});System.out.println("Netty客户端启动了");//告知客户端的服务器的地址,并启动客户端ChannelFuture channelFuture = bootstrap.connect("127.0.0.1",9090).sync();channelFuture.channel().closeFuture().sync();//阻塞等待完成操作后关闭通道eventLoopGroup.shutdownGracefully();}
}
public class NettyClientHandler extends ChannelInboundHandlerAdapter {//当客户端完成连接服务器后调用该方法@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {ByteBuf buf = Unpooled.copiedBuffer("hello server".getBytes(StandardCharsets.UTF_8));ctx.writeAndFlush(buf);}//当通道有读事件发生时调用的方法:读取服务器返回的数据@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf = (ByteBuf) msg;System.out.println("来自服务器"+ctx.channel().remoteAddress()+"的消息"+buf.toString(StandardCharsets.UTF_8));}
}
基础概念
NIO中实现多路复用的核心类是Selector,当多路复用器Selector调用select方法时,将会查找发生事件的
channel,问题是,该如何在多个注册到selector上的channel中找到哪些channel发生了事件,此时NIO不同的版本有不同的做法。
epoll函数
poll函数
select函数

Reactor模型
不同的线程决定了程序的性能,多线程是为了充分利用CPU
传统的阻塞IO模型

客户端连接服务端之后,会等客户端输入完之后,最后响应给客户端,才能紧接着为其它的客户端执行任务,因为等待会耗费大量时间,所以并没有把CPU用到极致
基础Reactor模型

可以执行完连接之后,让别的客户端来拿来处理自己的任务,各个操作之间是独立的,充分利用服务端之间的性能(可能是连接的,也可以是读的,也可以是写的)
多线程Reactor模型

相关文章:
Netty简介
Netty Netty初体验基础概念Reactor模型传统的阻塞IO模型基础Reactor模型多线程Reactor模型 为什么要使用Netty? (NIO的框架,用于解决高并发出现的问题) *BIO:同步且阻塞的IO NIO:同步且非阻塞的IO(不是说线程&#x…...
基于TCP/IP对等模型对计算机网络知识点的整合
目录 前言 应用层 Telnet SSH FTP/TFTP SNMP:简单的网络管理协议 HTTP:超文本传输协议 SMTP:电子邮件传输协议 DNS:域名解析协议 DHCP:动态主机配置协议 NTP:网络时钟协议 传输层 TCP UDP 端…...
【SQL应知应会】表分区(一)• Oracle版
欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习,有基础也有进阶,有MySQL也有Oracle 分区表 • Oracle版 前言一、分区表1.什么是表分区…...
PostgreSQL 常用空间处理函数
1.OGC标准函数 管理函数: 添加几何字段 AddGeometryColumn(, , , , , ) 删除几何字段 DropGeometryColumn(, , ) 检查数据库几何字段并在geometry_columns中归档 Probe_Geometry_Columns() 给几何对象设置空间参考(在通过一个范围做空间查询时常用&…...
ubuntu初始化/修改root密码
1.登录ubuntu后,使用sudo passwd root命令,进行root密码的初始化/修改,注:这里需要保证两次输入的密码都是同一个,才可成功 ubuntugt-ubuntu22-04-cmd-v1-0-32gb-100m:~/ocr$ sudo passwd root New password: Retype…...
【Linux后端服务器开发】select多路转接IO服务器
目录 一、高级IO 二、fcntl 三、select函数接口 四、select实现多路转接IO服务器 一、高级IO 在介绍五种IO模型之前,我们先讲解一个钓鱼例子。 有一条大河,河里有很多鱼,分布均匀。张三是一个钓鱼新手,他钓鱼的时候很紧张&a…...
支持向量机(iris)
代码: import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn import svm import numpy as np# 定义每一列的属性 colnames [sepal-length, sepal-width, petal-length, petal-width, class] # 读取数据 iris pd.read_csv(data\\i…...
24考研数据结构-第二章:线性表
目录 第二章:线性表2.1线性表的定义(逻辑结构)2.2 线性表的基本操作(运算)2.3 线性表的物理/存储结构(确定了才确定数据结构)2.3.1 顺序表的定义2.3.1.1 静态分配2.3.1.2 动态分配2.3.1.3 mallo…...
Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述动态 sql 的执行原理不?
OGNL表达式 OGNL,全称为Object-Graph Navigation Language,它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,它旨在提供一个更高的更抽象的层次来对Java对象图进行导航。 OGNL表达式的基本单位是"导航链"&a…...
250_C++_typedef std::function<int(std::vector<int> vtBits)> fnChkSstStt
假设我们需要定义一个函数类型来表示一个能够计算整数向量中所有元素之和的函数。 首先,我们定义一个函数,它的参数是一个 std::vector 类型的整数向量,返回值是 int 类型,表示所有元素之和: int sumVectorElements(std::vector<int> vt) {int sum = 0;for (int n…...
无涯教程-jQuery - Transfer方法函数
Transfer 效果可以与effect()方法一起使用。这会将元素的轮廓转移到另一个元素。尝试可视化两个元素之间的交互时非常有用。 Transfer - 语法 selector.effect( "transfer", {arguments}, speed ); 这是所有参数的描述- className - 传输元素将收到的可选类名。…...
openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符
文章目录 openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符24.1 LIKE24.2 SIMILAR TO24.3 POSIX正则表达式 openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符 数据库提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、SIMILAR TO操作符…...
JAVASE---数据类型与变量
1. 字面常量 常量即程序运行期间,固定不变的量称为常量,比如:一个礼拜七天,一年12个月等。 public class Demo{ public static void main(String[] args){ System.Out.println("hello world!"); System.Out.println(…...
IDEA Groovy 脚本一键生成实体类<mybatisplus>
配置数据库(mysql) 一键生成(右键点击table) 配置自己的groovy脚本 import com.intellij.database.model.DasTable import com.intellij.database.util.Case import com.intellij.database.util.DasUtil import com.intellij.data…...
无涯教程-jQuery - Puff方法函数
吹气效果可以与show/hide/toggle一起使用。通过按比例放大元素并同时隐藏它,可以形成粉扑效果。 Puff - 语法 selector.hide|show|toggle( "puff", {arguments}, speed ); 这是所有参数的描述- model - 效果的模式。可以是"显…...
什么叫前后端分离?为什么需要前后端问题?解决了什么问题?
单体架构出现的问题 引出:来看一个单体项目架构的结构 通过上述可以看到单体架构主要存在以下几点问题: 开发人员同时负责前端和后端代码开发,分工不明确开发效率低前后端代码混合在一个工程中,不便于管理对开发人员要求高(既会前…...
Vector<T> 动态数组(随机访问迭代器)(答案)
答案如下 //------下面的代码是用来测试你的代码有没有问题的辅助代码,你无需关注------ #include <algorithm> #include <cstdlib> #include <iostream> #include <vector> #include <utility> using namespace std; struct Record { Record…...
Istio 故障注入与重试的实验
故障注入 Istio流量治理有故障注入的功能,在接收到用户请求程序的流量时,注入故障现象,例如注入HTTP请求错误,当有流量进入Sidecar时,直接返回一个500的错误请求代码。 通过故障注入可以用来测试整个应用程序的故障恢…...
Java设计模式-中介者模式
中介者模式 1.中介者模式含义 中介者模式,就是用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地互相引用,从而使其耦合松散,而且可以独立的改变它们之间的交互。 其实中介者模式很简单的,就像它的名字一样&a…...
OpenCV实现高斯模糊加水印
# coding:utf-8 # Email: wangguisendonews.com # Time: 2023/4/21 10:07 # File: utils.pyimport cv2 import PIL from PIL import Image import numpy as np from watermarker.marker import add_mark, im_add_mark import matplotlib.pyplot as plt# PIL Image转换成OpenCV格…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
