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格…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
