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模型
相关文章:
![](https://img-blog.csdnimg.cn/1a1d51311b1045bda3557557873bf6d9.png)
Netty简介
Netty Netty初体验基础概念Reactor模型传统的阻塞IO模型基础Reactor模型多线程Reactor模型 为什么要使用Netty? (NIO的框架,用于解决高并发出现的问题) *BIO:同步且阻塞的IO NIO:同步且非阻塞的IO(不是说线程&#x…...
![](https://www.ngui.cc/images/no-images.jpg)
基于TCP/IP对等模型对计算机网络知识点的整合
目录 前言 应用层 Telnet SSH FTP/TFTP SNMP:简单的网络管理协议 HTTP:超文本传输协议 SMTP:电子邮件传输协议 DNS:域名解析协议 DHCP:动态主机配置协议 NTP:网络时钟协议 传输层 TCP UDP 端…...
![](https://img-blog.csdnimg.cn/30bc732cd41946cb86d2f0082d07933b.gif#pic_center)
【SQL应知应会】表分区(一)• Oracle版
欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习,有基础也有进阶,有MySQL也有Oracle 分区表 • Oracle版 前言一、分区表1.什么是表分区…...
![](https://www.ngui.cc/images/no-images.jpg)
PostgreSQL 常用空间处理函数
1.OGC标准函数 管理函数: 添加几何字段 AddGeometryColumn(, , , , , ) 删除几何字段 DropGeometryColumn(, , ) 检查数据库几何字段并在geometry_columns中归档 Probe_Geometry_Columns() 给几何对象设置空间参考(在通过一个范围做空间查询时常用&…...
![](https://img-blog.csdnimg.cn/9b876cc901834e69b6847979f68c5457.png)
ubuntu初始化/修改root密码
1.登录ubuntu后,使用sudo passwd root命令,进行root密码的初始化/修改,注:这里需要保证两次输入的密码都是同一个,才可成功 ubuntugt-ubuntu22-04-cmd-v1-0-32gb-100m:~/ocr$ sudo passwd root New password: Retype…...
![](https://img-blog.csdnimg.cn/b91cb4468da34417acce03f08c68f4f1.png)
【Linux后端服务器开发】select多路转接IO服务器
目录 一、高级IO 二、fcntl 三、select函数接口 四、select实现多路转接IO服务器 一、高级IO 在介绍五种IO模型之前,我们先讲解一个钓鱼例子。 有一条大河,河里有很多鱼,分布均匀。张三是一个钓鱼新手,他钓鱼的时候很紧张&a…...
![](https://img-blog.csdnimg.cn/fbb73867ba20493d88f21117cf2f5a1b.png)
支持向量机(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…...
![](https://img-blog.csdnimg.cn/f8460fa6496b489b80c66381595a86aa.png)
24考研数据结构-第二章:线性表
目录 第二章:线性表2.1线性表的定义(逻辑结构)2.2 线性表的基本操作(运算)2.3 线性表的物理/存储结构(确定了才确定数据结构)2.3.1 顺序表的定义2.3.1.1 静态分配2.3.1.2 动态分配2.3.1.3 mallo…...
![](https://www.ngui.cc/images/no-images.jpg)
Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述动态 sql 的执行原理不?
OGNL表达式 OGNL,全称为Object-Graph Navigation Language,它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,它旨在提供一个更高的更抽象的层次来对Java对象图进行导航。 OGNL表达式的基本单位是"导航链"&a…...
![](https://www.ngui.cc/images/no-images.jpg)
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…...
![](https://www.learnfk.com/guide/images/wuya.png)
无涯教程-jQuery - Transfer方法函数
Transfer 效果可以与effect()方法一起使用。这会将元素的轮廓转移到另一个元素。尝试可视化两个元素之间的交互时非常有用。 Transfer - 语法 selector.effect( "transfer", {arguments}, speed ); 这是所有参数的描述- className - 传输元素将收到的可选类名。…...
![](https://img-blog.csdnimg.cn/img_convert/66e275769c838bd850b071e4b5440110.jpeg)
openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符
文章目录 openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符24.1 LIKE24.2 SIMILAR TO24.3 POSIX正则表达式 openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符 数据库提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、SIMILAR TO操作符…...
![](https://img-blog.csdnimg.cn/2ea113b8646f4a1f936efad8f67148b2.png)
JAVASE---数据类型与变量
1. 字面常量 常量即程序运行期间,固定不变的量称为常量,比如:一个礼拜七天,一年12个月等。 public class Demo{ public static void main(String[] args){ System.Out.println("hello world!"); System.Out.println(…...
![](https://img-blog.csdnimg.cn/6d6e651230f849d1bbd09b2edc8e225c.png)
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…...
![](https://www.learnfk.com/guide/images/wuya.png)
无涯教程-jQuery - Puff方法函数
吹气效果可以与show/hide/toggle一起使用。通过按比例放大元素并同时隐藏它,可以形成粉扑效果。 Puff - 语法 selector.hide|show|toggle( "puff", {arguments}, speed ); 这是所有参数的描述- model - 效果的模式。可以是"显…...
![](https://img-blog.csdnimg.cn/39da6d7b7191490d9c70a9b979413c59.png#pic_center)
什么叫前后端分离?为什么需要前后端问题?解决了什么问题?
单体架构出现的问题 引出:来看一个单体项目架构的结构 通过上述可以看到单体架构主要存在以下几点问题: 开发人员同时负责前端和后端代码开发,分工不明确开发效率低前后端代码混合在一个工程中,不便于管理对开发人员要求高(既会前…...
![](https://www.ngui.cc/images/no-images.jpg)
Vector<T> 动态数组(随机访问迭代器)(答案)
答案如下 //------下面的代码是用来测试你的代码有没有问题的辅助代码,你无需关注------ #include <algorithm> #include <cstdlib> #include <iostream> #include <vector> #include <utility> using namespace std; struct Record { Record…...
![](https://img-blog.csdnimg.cn/851694ab2a0f4678b24833c732f27bde.png)
Istio 故障注入与重试的实验
故障注入 Istio流量治理有故障注入的功能,在接收到用户请求程序的流量时,注入故障现象,例如注入HTTP请求错误,当有流量进入Sidecar时,直接返回一个500的错误请求代码。 通过故障注入可以用来测试整个应用程序的故障恢…...
![](https://www.ngui.cc/images/no-images.jpg)
Java设计模式-中介者模式
中介者模式 1.中介者模式含义 中介者模式,就是用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地互相引用,从而使其耦合松散,而且可以独立的改变它们之间的交互。 其实中介者模式很简单的,就像它的名字一样&a…...
![](https://img-blog.csdnimg.cn/50bab17e9aa14575a1f5262f5116401e.png)
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格…...
![](https://img-blog.csdnimg.cn/img_convert/751e3d2775d3c0ac4eb4a11058dd1edf.png)
JMeter 怎么查看 TPS 数据教程,简单易懂
TPS 是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。在 JMeter 中,我们可以使用以下方法查看 T…...
![](https://img-blog.csdnimg.cn/9c3da8a40ace4dbda5be871c58b09377.jpeg#pic_center)
2023年的深度学习入门指南(19) - LLaMA 2源码解析
2023年的深度学习入门指南(19) - LLaMA 2源码解析 上一节我们学习了LLaMA 2的补全和聊天两种API的使用方法。本节我们来看看LLaMA 2的源码。 补全函数text_completion源码解析 上一节我们讲了LLaMA 2的编程方法。我们来复习一下: generator Llama.build(ckpt_di…...
![](https://www.ngui.cc/images/no-images.jpg)
慕课网Go-2.数组、slice、map、list
数组 package mainimport "fmt"func main() {var course1 [3]stringcourse1[0] "go"course1[1] "grpc"course1[2] "gin"for _, value : range course1 {fmt.Println(value)}course2 : [3]string{2: "grpc"}fmt.Println(…...
![](https://www.ngui.cc/images/no-images.jpg)
Django的Rest framework搭建自定义授权登录
系列文章目录 提示:阅读本章之前,请先阅读目录 文章目录 系列文章目录一、前言User模型User的viewsUser的serializersutils的md5加密自定义认证方法配置路由总路由分路由rest的配置 一、前言 之前的文章有写过通过jwt认证的文章,今天这一篇是…...
![](https://img-blog.csdnimg.cn/9d660f4827474d0eacc655c7f1ade7e6.png)
01 矩阵(力扣)多源广度优先搜索 JAVA
给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 输入:mat [[0,0,0],[0,1,0],[0,0,0]] 输出:[[0,0,0],[0,1,0],[0,0,0]] 输入…...
![](https://img-blog.csdnimg.cn/7daef9861075445baad7236f956efc61.png)
怎么绘制简爱思维导图?用这个工具绘制很简单
怎么绘制简爱思维导图?绘制思维导图是一项非常有用的技能,有助于梳理思路、整理知识、更好地理解和记忆信息。因此,无论你是学生、教师、工程师、项目经理或者只是想要更好地组织自己的想法,学会绘制思维导图都是非常有益的。下面…...
![](https://img-blog.csdnimg.cn/5ab219b0f78e477eb26735d39c1c92f2.png)
EC200U-CN学习(三)
EC200U系列内置丰富的网络协议,集成多个工业标准接口,并支持多种驱动和软件功能(适用于Windows 7/8/8.1/10、Linux和Android等操作系统下的USB驱动),极大地拓展了其在M2M领域的应用范围,如POS、POC、ETC、共…...
![](https://img-blog.csdnimg.cn/8c2b7d45d31d4b5199f56548c05dd697.png)
【windows】连接共享打印机提示:0x0000011B
【问题现象】 添加共享打印机的时候, 提示错误:0x0000011B。 【解决方法】 按winr键,在运行输入regedit 然后在注册表中找到路径: 计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print 打开后,在右侧…...
![](https://img-blog.csdnimg.cn/img_convert/526a580aad687ec3af395611e0a6701b.webp?x-oss-process=image/format,png)
基于“RWEQ+”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践应用及SCI论文撰写
【查看原文】基于“RWEQ”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践应用及SCI论文撰写 土壤风蚀是一个全球性的环境问题。中国是世界上受土壤风蚀危害最严重的国家之一,土壤风蚀是中国干旱、半干旱及部分湿润地区土地荒漠化的首要过程。中国风…...
![](https://img-blog.csdnimg.cn/9c60a86576bd4be29cb5b94afd9786f0.png#pic_center)
Flutter-基础Widget
Flutter页面-基础Widget 文章目录 Flutter页面-基础WidgetWidgetStateless WidgetStateful WidgetState生命周期 基础widget文本显示TextRichTextDefaultTextStyle 图片显示FlutterLogoIconImageIamge.assetImage.fileImage.networkImage.memory CircleAvatarFadeInImage 按钮R…...
![](/images/no-images.jpg)
书籍网站建设的目的/企业培训课程清单
case:Spark向kafka中写入数据 对于每个partition的每条记录,我们都需要创建KafkaProducer,然后利用producer进行输出操作,注意这里我们并不能将KafkaProducer的新建任务放在foreachPartition外边,因为KafkaProducer是不可序列化的…...
![](/images/no-images.jpg)
建设银行官方网站打不开/googleseo优化
参考:https://blog.csdn.net/maweifei/article/details/51221259 # 示例: img_ cv::Mat::zeros(pic_height_, pic_width_, CV_8UC1);Mat不但是一个非常有用的图像容器类,同时也是一个通用的矩阵类。 Mat矩阵(图像容器)创建时CV_8UC1、CV_8U…...
![](/images/no-images.jpg)
培训网站模板/百度搜索榜
hdu_2242 题目大意:求将一张无向图(n个点,m条边)移除一条边分为不连通两部分,使得两部分的点权和最接近,若无法分为两部分,则输出impossible。 题解:拿到题面还算清晰,就…...
四川南充房产网/宁波百度seo点击软件
Insatll (安装)//> 使用composer直接安装composer require graham-campbell/markdown//> 或在composer.json文件require中添加如下:"require": {"graham-campbell/markdown": "^7.0"}//> 使用下面命令更新composer.json依赖…...
![](/images/no-images.jpg)
微信分销网站建设比较好/2023网站推广入口
2008年的年末到2009年的初始,翻过C的书、VC的教程,看过VC的视频,试图编写过VC的程序;安装过Delphi 7的程序,翻过Diphi的基础教程;甚至下载过Java的视频教程。而VB6的程序,几乎一个没写ÿ…...
![](/images/no-images.jpg)
get attached file wordpress/重庆seo网络推广优化
获取元素DOM对象有很多种方法,以前一直在用getElementById和getElementsByTagName等,现在对这些方法和querySelector做一个总结. 常见的获取元素的方法有3种,分别是通过元素ID、通过标签名字和通过类名字来获取。 DOM提供了一个名…...