Netty 介绍

news2024/9/29 19:30:36

1 Netty 原理

        Netty 是一个高性能、异步事件驱动的 NIO 框架,基于 JAVA NIO 提供的 API 实现。它提供了对TCP、UDP 和文件传输的支持,作为一个异步 NIO 框架,Netty 的所有 IO 操作都是异步非阻塞的,通过 Future-Listener 机制,用户可以方便的主动获取或者通过通知机制获得 IO 操作结果。

2 Netty 高性能

        在IO编程过程中,当需要同时处理多个客户端接入请求时,可以利用多线程或者IO多路复用技术进行处理。IO多路复用技术通过把多个 IO的阻塞复用到同一个 select 的阻塞上,从而使得系统在单线程的情况下可以同时处理多个客户端请求。与传统的多线程/多进程模型比,I/O 多路复用的最大优势是系统开销小,系统不需要创建新的额外进程或者线程,也不需要维护这些进程和线程
的运行,降低了系统的维护工作量,节省了系统资源。
        与Socket类和ServerSocket类相对应,NIO也提供了SocketChannel和ServerSocketChannel
两种不同的套接字通道实现。

2.1 多路复用通讯方式

Netty 架构按照 Reactor 模式设计和实现,它的服务端通信序列图如下:

 客户端通信序列图如下:

        Netty 的 IO 线程 NioEventLoop 由于聚合了多路复用器 Selector,可以同时并发处理成百上千个客户端 Channel,由于读写操作都是非阻塞的,这就可以充分提升 IO 线程的运行效率,避免由于频繁 IO 阻塞导致的线程挂起。

2.2 异步通讯

        由于 Netty 采用了异步通信模式,一个 IO 线程可以并发处理 N 个客户端连接和读写操作,这从根本上解决了传统同步阻塞 IO 一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。

 2.3 零拷贝( (DIRECT BUFFERS 使用堆外直接内存 使用堆外直接内存) 

1. Netty 的接收和发送 ByteBuffer 采用 DIRECT BUFFERS,使用堆外直接内存进行 Socket 读写,不需要进行字节缓冲区的二次拷贝。如果使用传统的堆内存(HEAP BUFFERS)进行 Socket 读写,JVM 会将堆内存 Buffer 拷贝一份到直接内存中,然后才写入 Socket 中。相比于堆外直接内存,消息在发送过程中多了一次缓冲区的内存拷贝。
2. Netty 提供了组合 Buffer 对象,可以聚合多个 ByteBuffer 对象,用户可以像操作一个 Buffer 样
方便的对组合 Buffer 进行操作,避免了传统通过内存拷贝的方式将几个小 Buffer 合并成一个大的
Buffer。
3. Netty的文件传输采用了transferTo方法,它可以直接将文件缓冲区的数据发送到目标Channel,
避免了传统通过循环 write 方式导致的内存拷贝问题

2.4 内存池 ( 基于内存池的缓冲区重用机制)

      随着 JVM 虚拟机和 JIT 即时编译技术的发展,对象的分配和回收是个非常轻量级的工作。但是对于缓冲区 Buffer,情况却稍有不同,特别是对于堆外直接内存的分配和回收,是一件耗时的操作。为了尽量重用缓冲区,Netty 提供了基于内存池的缓冲区重用机制。

2.5 高效的 Reactor 线程模型

        常用的 Reactor 线程模型有三种,Reactor 单线程模型, Reactor 多线程模型, 主从 Reactor 多线程模型。
Reactor 单线程模型
        Reactor 单线程模型,指的是所有的 IO 操作都在同一个 NIO 线程上面完成,NIO 线程的职责如下:
1) 作为 NIO 服务端,接收客户端的 TCP 连接;
2) 作为 NIO 客户端,向服务端发起 TCP 连接;
3) 读取通信对端的请求或者应答消息;
4) 向通信对端发送消息请求或者应答消息。

         由于 Reactor 模式使用的是异步非阻塞 IO,所有的 IO 操作都不会导致阻塞,理论上一个线程可以独立处理所有 IO 相关的操作。从架构层面看,一个 NIO 线程确实可以完成其承担的职责。例如,通过Acceptor 接收客户端的 TCP 连接请求消息,链路建立成功之后,通过 Dispatch 将对应的 ByteBuffer派发到指定的 Handler 上进行消息解码。用户 Handler 可以通过 NIO 线程将消息发送给客户端。
Reactor 多线程模型
        Rector 多线程模型与单线程模型最大的区别就是有一组 NIO 线程处理 IO 操作。 有专门一个
NIO 线程-Acceptor 线程用于监听服务端,接收客户端的 TCP 连接请求; 网络 IO 操作-读、写
等由一个 NIO 线程池负责,线程池可以采用标准的 JDK 线程池实现,它包含一个任务队列和 N
个可用的线程,由这些 NIO 线程负责消息的读取、解码、编码和发送;

主从 Reactor 多线程模型
        服务端用于接收客户端连接的不再是个 1 个单独的 NIO 线程,而是一个独立的 NIO 线程池。
Acceptor 接收到客户端 TCP 连接请求处理完成后(可能包含接入认证等),将新创建的
SocketChannel 注册到 IO 线程池(sub reactor 线程池)的某个 IO 线程上,由它负责
SocketChannel 的读写和编解码工作。Acceptor 线程池仅仅只用于客户端的登陆、握手和安全
认证,一旦链路建立成功,就将链路注册到后端 subReactor 线程池的 IO 线程上,由 IO 线程负
责后续的 IO 操作。

2.6 无锁设计 、线程绑定

        Netty 采用了串行无锁化设计,在 IO 线程内部进行串行操作,避免多线程竞争导致的性能下降。表面上看,串行化设计似乎 CPU 利用率不高,并发程度不够。但是,通过调整 NIO 线程池的线程参数,可以同时启动多个串行化的线程并行运行,这种局部无锁化的串行线程设计相比一个队列-多个工作线程模型性能更优。 

 

 Netty 的 NioEventLoop 读取到消息之后,直接调用 ChannelPipeline 的
fireChannelRead(Object msg),只要用户不主动切换线程,一直会由 NioEventLoop 调用
到用户的 Handler,期间不进行线程切换,这种串行化处理方式避免了多线程操作导致的锁
的竞争,从性能角度看是最优的。

2.7 高性能的序列化框架 

        Netty 默认提供了对 Google Protobuf 的支持,通过扩展 Netty 的编解码接口,用户可以实现其它的高性能序列化框架,例如 Thrift 的压缩二进制编解码框架。
1. SO_RCVBUF 和 SO_SNDBUF:通常建议值为 128K 或者 256K。小包封大包,防止网络阻塞
2. SO_TCPNODELAY:NAGLE 算法通过将缓冲区内的小封包自动相连,组成较大的封包,阻止大量小封包的发送阻塞网络,从而提高网络应用效率。但是对于时延敏感的应用场景需要关闭该优化算法。

软中断 Hash 值和 CPU 绑定
3. 软中断:开启 RPS 后可以实现软中断,提升网络吞吐量。RPS 根据数据包的源地址,目的地址以及目的和源端口,计算出一个 hash 值,然后根据这个 hash 值来选择软中断运行的 cpu,从上层来看,也就是说将每个连接和 cpu 绑定,并通过这个 hash 值,来均衡软中断在多个 cpu 上,提升网络并行处理性能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jQuery 模版

一、安装 <script type"text/javascript" src"http://ajax.microsoft.com/ajax/jquery /jquery-1.4.min.js"></script> 二、元素隐藏/显示 &#xff0c;jQuery toggle() 通过 jQuery&#xff0c;可以使用 toggle() 方法来切换 hide() 和 sh…

关于系统/网络运维面试经验总结

一. 熟悉Linux命令 1. 最最最常问到的是 如何查看系统内存占用情况&#xff1f; ① free命令&#xff1a;free [-h][-m] 显示系统的内存使用情况&#xff0c;包括总内存、已使用内存、空闲内存等信息。其中&#xff0c;-m选项是以MB为单位来展示内存使用信息&#xff1b;-h选…

一些常见的测度

见 知乎 https://zhuanlan.zhihu.com/p/615270645

Linux添加新硬盘并挂载(mount)到目录下

首先列出文件系统的整体磁盘空间使用情况&#xff0c;可以用来查看磁盘已被使用多少空间和还剩余多少空间。 df -h 然后列出块设备信息&#xff1a;以树形展示你的磁盘以及磁盘分区信息 lsblk 现在有一块 3T 的磁盘 vdb&#xff0c;我们现在将它进行 磁盘分区 fdisk /dev/vd…

jdk的bin目录下的工具

Java Development Kit (JDK) 的 bin 目录包含了许多与 Java 开发和运行相关的命令。 以下是 bin 目录下一些常见的命令&#xff0c;包括 jps&#xff1a; java - 启动 Java 应用程序的命令。javac - Java 编译器&#xff0c;用于将 Java 源代码编译成字节码文件。javap - Java …

基于springboot实现家具销售电商平台管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现家具销售电商平台管理系统演示 摘要 社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。网络计算机的交易方式逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。互联网具有便利性&#xff0c;速度快&#xff0c;效率高&am…

Bootstrap关于盒子(盒模型)边距的设置

关于Bootstrap的盒子(盒模型)边距&#xff0c;其实在之前的很多示例代码中用到了。在博文 Bootstrap的CSS类积累学习 也有收集到不少相关的类。 详细的介绍&#xff0c;请大家参看下面这张图。 示例代码如下&#xff1a; <!DOCTYPE html> <html> <head>&l…

sface人脸相似度检测

sface人脸相似度检测&#xff0c;基于OPENCV&#xff0c;人脸检测采用yunet&#xff0c;人脸识别采用sface&#xff0c;支持PYTHON/C开发&#xff0c;图片来自网络&#xff0c;侵权请联系本人立即删除 yunet人脸检测sface人脸识别&#xff0c;检测两张图片的人脸相似度

华为OD机试 - 数组组成的最小数字(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

UI自动化测试:Selenium+PO模式+Pytest+Allure整合

本人目前工作中未涉及到WebUI自动化测试&#xff0c;但为了提升自己的技术&#xff0c;多学习一点还是没有坏处的&#xff0c;废话不多说了&#xff0c;目前主流的webUI测试框架应该还是selenium&#xff0c;考虑到可维护性、拓展性、复用性等&#xff0c;我们采用PO模式去写我…

基于Springboot实现点餐平台网站管理系统项目【项目源码+论文说明】

基于Springboot实现点餐平台网站管理系统演示 摘要 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多商家的之中&#xff0c;随之就产生了“点餐平台网站”&#xff0c;这样就让点餐平台网站更加方便简单。 对于本…

设计模式 - 行为型模式考点篇:观察者模式(概述 | 案例实现 | 优缺点 | 使用场景)

目录 一、行为型模式 1.1、观察者模式 1.1.1、概述 1.1.2、案例实现 1.1.3、优缺点 1.1.4、使用场景 一、行为型模式 1.1、观察者模式 1.1.1、概述 观察者模式又称为 发布 - 订阅 模式.&#xff0c;就是让多个观察者对象同时监听同一个主题对象. 这个主题对象在变化的同…

详解一典型的反激式开关电源方案

理解一个单端反激式开关电源方案&#xff1a; 1、抛出问题&#xff1a; 如图&#xff0c;在某系统方案上看到下图所示的单端反激式开关电源方案。 2、解析问题&#xff1a; 2.1、乍一看&#xff1a; 典型的AC-DC电路&#xff0c;考虑了安规及过压过流保护&#xff0c;如&am…

黑马点评-06缓存雪崩问题(大量key失效)及其解决方案

缓存雪崩问题(大量key失效) 解决方案 缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库给服务器带来巨大压力 当我们批量导入缓存数据的时候可以给不同的Key的TTL添加随机值,让其在不同时间段分批失效利用Redis集群提高服务的可用性 使…

用低代码轻松实现高效、易用的流程审批表单

在企业运营中&#xff0c;流程引擎表单的配置和使用是一个重要的环节。无论是发起人、审批人还是其他角色&#xff0c;他们在流程中所看到的表单内容可能会有所不同&#xff0c;因此我们需要根据不同的场景灵活选择和设计表单。每一个流程节点都需要一个表单&#xff0c;通过灵…

基于BES平台音乐信号处理之DRC算法实现

基于BES平台音乐信号处理之DRC算法实现 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)&#xff1f;加我微信hezkz17, 本群提供音频技术答疑服务 1 DRC实现 drc.h 2 调用 audio_process.c 3 DRC动态范围控制算法在音乐信号处理中的位置 4 DRC具体细节源码 可参考…

C++QT-day4

#include <iostream> //运算符重载 using namespace std;class Person { // //全局函数实现运算符重载 // friend const Person operator(const Person &L,const Person &R); // //全局函数实现-运算符重载 // friend const Person operator-(const …

【LeetCode】——链式二叉树经典OJ题详解

主页点击直达&#xff1a;个人主页 我的小仓库&#xff1a;代码仓库 C语言偷着笑&#xff1a;C语言专栏 数据结构挨打小记&#xff1a;初阶数据结构专栏 Linux被操作记&#xff1a;Linux专栏 LeetCode刷题掉发记&#xff1a;LeetCode刷题 算法头疼记&#xff1a;算法专栏…

PTE考试预览

目录 pte评分机制是对比 不同水平的人之后跟你匹配 前两次 两个听力题没有写 咯噔一下 无源65分 Headset Check 调试耳机听筒 Microphone zhigeiCheck 调试麦克风 麦克风测试话语 老师说她放在鼻梁骨那里声音很好 自我介绍 读完之后 &#xff0c;立马点next&#xf…