Netty入门学习和技术实践

Netty入门学习和技术实践

  • Netty
    • 1.Netty简介
    • 2.IO模型
    • 3.Netty框架介绍
    • 4. Netty实战项目学习
    • 5. Netty实际应用场景
    • 6.扩展

Netty

在这里插入图片描述

1.Netty简介

Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。
“快速”和“简单”并不用产生维护性或性能上的问题。Netty 是一个吸收了多种协议(包括FTP、SMTP、HTTP等各种二进制文本协议)的实现经验,并经过相当精心设计的项目。最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
git地址链接: 
来源:百度百科

2.IO模型

Unix中定义了五种I/O模型:阻塞I/O非阻塞I/OI/O复用(select、poll、linux 2.6种改进的epoll)信号驱动IOSIGIO)异步I/OPOSIX的aio_系列函数)
Java共支持3种网络编程模型/IO模式:BIONIOAIO

BIO:

同步阻塞模式,进行IO操作时,程序会处于阻塞状态,直到IO操作完成。这意味着当程序进行网络操作或者文件操作时,如果操作耗时很长,程序会一直等待,无法进行其他任务。虽然BIO的编程模型比较简单,但是它的并发处理能力相对较弱。因为当有多个IO请求时,线程会被阻塞,CPU无法充分利用。对于高并发场景下的服务器应用来说,BIO的性能表现并不理想。

BIO原理图:在这里插入图片描述

AIO:

     Java 7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型,异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

AIO原理图:
在这里插入图片描述
NIO:

     Java 7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型,异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。非阻塞IO虽然相对于阻塞IO大幅提升了性能,其依然存在性能问题,频繁的轮询导致频繁的系统调用,会耗费大量的CPU资源。当并发很高时,假设有1000个并发,那么单位时间循环内将会有1000次系统调用去轮询执行结果,而实际上可能只有2个请求结果执行完毕,这就会有998次无效的系统调用,造成严重的性能浪费。NIO问题的本质就是频繁轮询导致的无效系统调用

NIO原理图:
在这里插入图片描述
IO多路复用

  NIO的升级解决方案,减少系统无效的调用线程首先发起 select调用,询问内核数据是否准备就绪,等内核把数据准备好了,用户线程再发起read调用。read调用的过程(数据从内核空间->用户空间)还是阻塞的。目前支持 IO 多路复用的系统调用,有 select,epoll 等。select 系统调用,是目前几乎在所有的操作系统上都有支持select调用,内核提供的系统调用,它支持一次查询多个系统调用的可用状态。几乎所有的操作系统都支持。epoll调用:linux 2.6 内核,属于 select调用的增强版本,优化了 IO 的执行效率。Netty 的非阻塞 I/O 的实现关键是基于 I/O 复用模型

IO多路复用原理图
在这里插入图片描述

总结:

为什么会分为这五种情况,是因为应用程序和操作系统分为用户态和内核态,应用程序对操作系统的内核发起IO调用(系统调用),操作系统负责的内核执行具体的IO操作。也就是说,我们的应用程序实际上只是发起了IO操作的调用而已,具体 IO 的执行是由操作系统的内核来完成的。
应用程序发起的一次IO操作实际包含两个阶段:
IO调用阶段:应用程序进程向内核发起系统调用
IO执行阶段:内核执行IO操作并返回2.1. 准备数据阶段:内核等待I/O设备准备好数据2.2. 拷贝数据阶段:将数据从内核缓冲区拷贝到用户空间缓冲区

增进理解:

 - 同步阻塞:你到饭馆点餐,然后在那等着,还要一边喊:好了没啊!- 同步非阻塞:在饭馆点完餐,就去遛狗了。不过溜一会儿,就回饭馆喊一声:好了没啊!- 异步阻塞:遛狗的时候,接到饭馆电话,说饭做好了,让您亲自去拿。- 异步非阻塞:饭馆打电话说,我们知道您的位置,一会给你送过来,安心遛狗就可以了。

3.Netty框架介绍

Netty 的工作架构图
在这里插入图片描述

Server端包含 1Boss NioEventLoopGroup1Worker NioEventLoopGroupBoss 专门负责接收客户端的连接, Worker专门负责网络的读写;
NioEventLoopGroup:相当于 1 个事件循环组,这个组里包含多个事件循环 NioEventLoop,每个 NioEventLoop 包含 1Selector1 个事件循环线程。
 Boss NioEventLoop 循环执行的任务包含 3 步:1.轮询 Accept 事件。2.处理 Accept I/O 事件,与 Client 建立连接,生成 NioSocketChannel,并将 NioSocketChannel 注册到某个 Worker NioEventLoopSelector 上。
3.处理任务队列中的任务,runAllTasks。任务队列中的任务包括用户调用 eventloop.execute 或 schedule 执行的任务,或者其他线程提交到该 eventloop 的任务。
 Worker NioEventLoop 循环执行的任务包含 3 步:1.轮询 ReadWrite 事件。2.处理 I/O 事件,即 ReadWrite 事件,在 NioSocketChannel 可读、可写事件发生时进行处理。
3.处理任务队列中的任务,runAllTasks。

Selector 选择器原理
在这里插入图片描述

netty几大核心概念
拆包/粘包

应用A 通过网络发送数据向应用B 发送消息,大概会经过如下阶段:阶段一:应用A 把流数据发送到 TCP发送缓冲区。阶段二:TCP发送缓冲区把数据发送到达 B服务器 TCP接收缓冲区。阶段三:应用BTCP接收缓冲区读取流数据。

在这里插入图片描述

  假设客户端向服务端连续发送了两个数据包,分别用ABCDEF来表示,那么服务端收到的数据可以分为以下三种情况:情况1:接收端正常收到两个数据包,即没有发生拆包和粘包的现象。

在这里插入图片描述

 情况2:接收端只收到一个数据包,这一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。

在这里插入图片描述

 情况3:接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包。

在这里插入图片描述

TCP发送数据原由:1.因为TCP本身传输的数据包大小就有限制,所以应用发出的消息包过大,TCP会把应用消息包拆分为多个TCP数据包发送出去。2.Negal算法的优化,当应用发送数据包太小,TCP为了减少网络请求次数的开销,它会等待多个消息包一起,打成一个TCP数据包一次发送出去。
TCP接收方的原由:1.TCP缓冲区里的数据都是字符流的形式,没有明确的边界,因为数据没边界,所以应用从TCP缓冲区中读取数据时就没办法指定一个或几个消息一起读,而只能选择一次读取多大的数据流,而这个数据流中就可能包含着某个消息包的一部分数据
1)粘包原因:
发送的数据大小小于发送缓冲区,tcp就会把发送的数据多次写入缓冲区,此时发生粘包;
接收数据方的应用层没有及时从 接收缓冲区读取数据,也会发生粘包;
2)拆包原因:
发送的数据大小 大于 tcp发送缓冲区,就会发生拆包;
发送的数据大小 大于 报文最大长度,也会拆包;
原因总结:1.一个TCP报文最大能传输65536个字节,也就是16Kb。2.TCP是流式协议,数据无边界。解决粘包拆包的关键在于为每一个数据包添加界限标识,常用方法如下:
方法1)发送方以固定长度封装数据包。如果不足,则补0填充。
方法2)自定义设置数据包的界限标识,如添加特别标识(如======)。接收方通过标识可以识别不同的数据包;
方法3)发送方为每一个数据包添加报文头部。头部至少包含数据包长度(类似http协议的头部length)。 通过这种方式,接收方通过读取头部的长度知道当前数据包的界限,并在界限处停止读取。

netty处理 拆包/粘包 的方式:
在这里插入图片描述

零拷贝:

  零拷贝概念:在操作数据时, 不需要将数据buffer从一个内存区域拷贝到另一个内存区域。 少了一次内存的拷贝,CPU的效率就得到的提升。在系统层面上的零拷贝通常指避免在用户态(User-space)与内核态(Kernel-space)之间来回拷贝数据。NettyZero-copy完全是在用户态(Java 层面), 更多的偏向于优化数据操作。netty实现零拷贝原理:1.Netty的接收和发送ByteBuffer采用DIRECT BUFFERS,使用堆外直接内存进行Socket读写,不需要进行字节缓冲区的二次拷贝。如果使用传统的堆内存(HEAP BUFFERS)进行Socket读写,JVM会将堆内存Buffer拷贝一份到直接内存中,然后才写入Socket中。相比于堆外直接内存,消息在发送过程中多了一次缓冲区的内存拷贝。2.Netty提供了组合Buffer对象,可以聚合多个ByteBuffer对象,用户可以像操作一个Buffer那样方便的对组合Buffer进行操作,避免了传统通过内存拷贝的方式将几个小Buffer合并成一个大的Buffer3.Netty的文件传输采用了transferTo方法,它可以直接将文件缓冲区的数据发送到目标Channel,避免了传统通过循环write方式导致的内存拷贝问题。

4. Netty实战项目学习

项目学习地址:
Netty教程:十二个实例带你轻松学习Netty
项目代码gitee地址:
nettyTeach

5. Netty实际应用场景

netty可以做什么:
有了Netty,你可以实现自己的HTTP服务器,FTP服务器,UDP服务器,RPC服务器,WebSocket服务器,Redis的Proxy服务器,MySQL的Proxy服务器等等。

传统的HTTP服务器的原理1、创建一个ServerSocket,监听并绑定一个端口2、一系列客户端来请求这个端口3、服务器使用Accept,获得一个来自客户端的Socket连接对象4、启动一个新线程处理连接4.1、读Socket,得到字节流4.2、解码协议,得到Http请求对象4.3、处理Http请求,得到一个结果,封装成一个HttpResponse对象4.4、编码协议,将结果序列化字节流 写Socket,将字节流发给客户端5、继续循环步骤3
 HTTP服务器之所以称为HTTP服务器,是因为编码解码协议是HTTP协议,如果协议是Redis协议,那它就成了Redis服务器,如果协议是WebSocket,那它就成了WebSocket服务器,等等。 使用Netty可以定制编解码协议,实现特定协议的服务器。

netty适用行业:

2.1 互联网行业1、互联网行业:在分布式系统中,各个节点之间需要远程调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通行框架,往往作为基础通信组件被这些 RPC 框架使用。2、典型的应用有:阿里分布式服务框架 DubboRPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信。

在这里插入图片描述

2.2 游戏行业1、无论是手游服务端还是大型的网络游戏,Java 语言得到了越来越广泛的应用。2Netty 作为高性能的基础通信组件,提供了 TCP/UDPHTTP 协议栈,方便定制和开发私有协议栈,账号登录服务器。3、地图服务器之间可以方便的通过 Netty 进行高性能的通信。

2.3 大数据领域

2.2 游戏行业1、经典的 Hadoop 的高性能通信 和 序列化组件(AVRO 实现数据文件共享)的 RPC 框架,默认采 Netty 进行跨界点通信。2、它的 Netty Service 基于 Netty 框架二次封装实现。

在这里插入图片描述
2.4 其它开源项目使用的Netty
网址:https://netty.io/wiki/related-projects.html
在这里插入图片描述

6.扩展

netty相关书籍:

 Netty入门与实战:仿写微信 IM 即时通讯系统Netty 4.x学习笔记 - 线程模型Netty入门与实战理解高性能网络模型Netty基本原理介绍software-architecture-patterns.pdfNetty高性能之道 —— 李林锋Netty In ActionNetty权威指南

netty官网:netty.io

netty优秀开源项目
gitee:

 mqtt-cluster:https://gitee.com/quickmsg/mqtt-cluster.gitnetty-mqtt:https://gitee.com/lxrv587/iot_push.githeart-netty:https://gitee.com/zjz0812/heart-netty.git
netty_redis_zookeeper:https://gitee.com/crazymaker/netty_redis_zookeeper_source_code.git

github:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/107586.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 将容器打包成镜像推送镜像到仓库

Docker 将容器打包成镜像&推送镜像到仓库 一、将容器打包成镜像 $ docker commit <容器ID> <镜像名称:标签>示例&#xff1a; $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS …

数字孪生:重塑制造、医疗和能源等领域的未来

数字孪生技术&#xff0c;作为虚拟仿真的重要领域&#xff0c;正以其强大的能力在各个行业中创造前所未有的创新。本文带大家一起深入探讨数字孪生技术在不同领域的广泛应用场景&#xff0c;展示其在实现效率、可靠性和智能化方面的积极影响。 制造业与工业领域 数字孪生技术在…

Python+TinyPNG熊猫网站自动化的压缩图片

前言 本篇在讲什么 PythonTinyPNG自动化处理图片 本篇需要什么 对Python语法有简单认知 依赖Python2.7环境 依赖TinyPNG工具 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f449;…

抽象类和接口有什么区别?

在 Java 中&#xff0c;抽象类和接口是两种不同的类类型。它们都不能直接实例化&#xff0c;并且它们都是用来定义一些基本的属性和方法的&#xff0c;但它们有以下几点不同&#xff1a; 定义不同&#xff1a;定义的关键字不同&#xff0c;抽象类是 abstract&#xff0c;而接口…

ATF(TF-A)安全通告 TFV-2 (CVE-2017-7564)

安全之安全(security)博客目录导读 ATF(TF-A)安全通告汇总 目录 一、ATF(TF-A)安全通告 TFV-2 (CVE-2017-7564) 二、 CVE-2017-7564 一、ATF(TF-A)安全通告 TFV-2 (CVE-2017-7564) Title 启用安全自托管侵入式调试接口&#xff0c;可允许非安全世界引发安全世界panic CV…

【LeetCode75】第三十七题 二叉树中的最长交错路径

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给我们一棵二叉树&#xff0c;问我们在这棵树里能找到的最长交错路径。最长交错路径就是在二叉树里一左一右一左一右这样走&#xff0c;最…

java- ConcurrentHashMap 并发

1. ConcurrentHashMap 并发 1.1. 减小锁粒度 减小锁粒度是指缩小锁定对象的范围&#xff0c;从而减小锁冲突的可能性&#xff0c;从而提高系统的并发能力。减小锁粒度是一种削弱多线程锁竞争的有效手段&#xff0c;这种技术典型的应用是 ConcurrentHashMap(高性能的 HashMap)…

RT1050的ADC

文章目录 1 ADC介绍2 ADC框图2.1 外部输入通道2.2 输入电压范围2.3 触发源2.4 时钟源2.5 偏移矫正功能2.5.1 校准 1 ADC介绍 RT1052 有 2 个 ADC&#xff0c;每个 ADC 有 12 位、10 位、8 位可选&#xff0c;每个 ADC 有 16 个外部通道。 ADC具有最高 1MS/s 采样率支持单次或…

23.树表和哈希表的查找

当表插入、删除操作频繁时&#xff0c;为维护表的有序性&#xff0c;需要移动表中很多记录。基于此&#xff0c;我们可以改用动态查找表——几种特殊的树。表结构在查找过程中动态生成。对于给定值key&#xff0c;若表中存在&#xff0c;则成功返回&#xff1b;否则&#xff0c…

【微服务】Ribbon的实现原理

1、场景&#xff1a;这里有两个服务&#xff0c;user-server和store-server 1.1、user服务 接口&#xff1a; package com.lkx.user.controller;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController…

HashTable, HashMap, ConcurrentHashMap 之间的区别

前言 哈希表的组织形式是这样的&#xff1a; 对于哈希表这种重要而又频繁被使用的数据结构&#xff0c;是否线程安全往往是人们经常考虑的方向之一。 一、HashTable HashTable是线程安全的。但是它的线程安全在于它的关键方法都使用了synchronized&#xff0c;比如get方法、pu…

Python | assert关键字

Python断言assert是帮助代码流畅的调试工具。断言主要是假设程序员知道或总是希望是真的&#xff0c;因此将它们放在代码中&#xff0c;这样这些失败不会允许代码进一步执行。 简单地说&#xff0c;断言是一个布尔表达式&#xff0c;用来检查语句是True还是False。如果语句为T…

R包开发-2.2:在RStudio中使用Rcpp制作R-Package(更新于2023.8.23)

目录 4-添加C函数 5-编辑元数据 6-启用Roxygen&#xff0c;执行文档化。 7-单元测试 8-在自己的计算机上安装R包&#xff1a; 9-程序发布 参考&#xff1a; 为什么要写这篇文章的更新日期&#xff1f;因为R语言发展很快&#xff0c;很多函数或者方式&#xff0c;现在可以使…

js中作用域的理解?

1.作用域 作用域&#xff0c;即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合 换句话说&#xff0c;作用域决定了代码区块中变量和其他资源的可见性 举个例子 function myFunction() {let inVariable "函数内部变量"; } myFunction();//要先执行这…

NPM 管理组织包

目录 1、关于组织范围和包 1.1 管理无作用域的包 2、使用组织设置配置npm客户端 2.1 配置您的npm客户端以使用您组织的范围 为所有新包设置组织范围 为单个包设置组织范围 2.2 将默认包可见性更改为public 将单个包的包可见性设置为public 将所有包的包可见性设置为pu…

人脸识别平台批量导入绑定设备的一种方法

因为原先平台绑定设备是通过一个界面进行人工选择绑定或一个人一个人绑定设备。如下&#xff1a; 但有时候需要在几千个里选择出几百个&#xff0c;那这种方式就不大现实了&#xff0c;需要另外一种方法。 目前相到可以通过导入批量数据进行绑定的方式。 一、前端 主要是显示…

opencv进阶18-基于opencv 决策树导论

1. 什么是决策树&#xff1f; 决策树是最早的机器学习算法之一&#xff0c;起源于对人类某些决策过程 的模仿&#xff0c;属于监督学习算法。 决策树的优点是易于理解&#xff0c;有些决策树既可以做分类&#xff0c;也可以做回归。在排名前十的数据挖掘算法中有两种是决策树[1…

软件设计师学习笔记6-存储系统

1.层次化存储体系 1.1层次化存储结构 局部性原理是层次化存储结构的支持 时空局部性&#xff1a;刚被访问的内容&#xff0c;立即又被访问(eg: 循环体 ) 空间局部性&#xff1a;刚被访问的内容&#xff0c;临近的空间很快被访问(eg:数组) 1.2层次化存储结构的分类 DRAM&…

统计学补充概念-17-线性决策边界

概念 线性决策边界是一个用于分类问题的线性超平面&#xff0c;可以将不同类别的样本分开。在二维空间中&#xff0c;线性决策边界是一条直线&#xff0c;将两个不同类别的样本分隔开来。对于更高维的数据&#xff0c;决策边界可能是一个超平面。 线性决策边界的一般形式可以表…

使用信号处理算法过滤加速度数据并将其转换为速度和位移研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…