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格…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
 
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
 
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
 
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
 
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
 
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
