Netty原理及高性能

news2024/11/13 10:41:26

1. Netty原理

Netty是一个基于Java的异步事件驱动的网络应用框架,他用于快速开发高性能、高可靠性的网络服务器和客户端应用。Netty的原理涉及多个方面,包括 Reactor模式、核心组件、编解码、线程模型以及TCP粘包和拆包处理等

1.1 Reactor模式

Reactor模式是一种经典的事件驱动编程模型,Reactor模式的基本思想是将一个或者多个线程作为IO事件的处理线程,这些线程负责监听、分发和执行IO事件。Netty中的Reactor线程实现分为单线程模式和多线程模式,以适应不同的应用场景。

1.2 核心组件

Netty的核心组件包括

  • Channel: 表示一个和远程对端的连接,他是Netty对Java NIO中的Channel的抽象和封装。
  • EventLoop:事件循环器,处理事件的执行和IO操作,每个Channel都绑定一个EventLoop,并且所有的操作都是在EventLoop中执行的。
  • ChannelFuture: 异步IO操作结果的封装类,可以用来处理异步操作。例如,在Netty中,写操作是异步的,会立即返回一个ChannelFuture,通过它可以检查操作是否完成、是否成功,以及注册回调。
  • ChannelPipeline:通道处理器的中间件,处理数据的所有处理器都被包含在ChannelPipeline,可以通过ChannelPipeline编排数据的处理流程。
  • ChannelHandler:消息的处理器,将数据的读写和消息的处理独立开来,方便扩展。

1.3 编解码

Netty提供了通用的编解码框架——ChannelHandler,可以根据需要自定义数据的编解码方式。支持多种数据格式的编解码,如字符串、二进制数据、对象等。

1.4 线程模型

Netty的线程模型具有很好的可伸缩性和可扩展性,可以适应不同的应用场景和需求。

  • 单线程模型:一个线程处理所有IO事件,适用于负载不高、并发不强的场景。
  • 多线程模型:通过线程池处理IO事件,提高并发度和系统稳定性。
  • 主从多线程模型:主线程接收连接请求并建立连接,将连接分派给从线程对应处理,增加处理连接的线程数,提高系统的并发度。
  • 多Reactor多线程模型:每个Reactor都有独立的线程池,进一步提高并发度和系统可靠性。

2. Netty高性能

在IO编程过程中,当需要同时处理多个客户端连接请求时,可以利用多线程或者IO多路复用技术进行处理。IO多路复用技术通过把多个IO阻塞复用到同一个select的阻塞上,从而使得系统在单线程的情况下可以处理多个客户端连接。与传统的多线程/多进程模型相比,IO多路复用的最大优势是系统开销小。

与Socket类和ServerSocket相对应,NIO也提供了SocketChannel和ServerSocketChannel两种不同的套接字通道实现。

2.1 多路复用通信方式

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

2.2 异步通信NIO

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

2.3 零拷贝(Direct Buffers使用堆外直接内存)

在Netty中,零拷贝技术被广泛应用以提高网络数据传输的效率,零拷贝指的是在数据传输过程中,减少或者避免CPU的拷贝次数,从而加快数据传输速度,降低CPU负载。
在Netty中,零拷贝主要通过以下几种方式实现:

  1. 直接使用堆外内存
  • 堆外直接内存是指JVM堆内存之外的内存,通常由操作系统的物理内存直接映射。Netty默认情况下使用堆外直接内存来创建缓冲区,这样做的好处是可以减少JVM堆内存的使用,降低垃圾回收压力,并且可以提高网络传输的效率。因为数据在传输过程中,可以直接从操作系统的网络缓冲区传输到Netty的缓冲区,无需经过JVM堆内存。
  1. 组合ByteBuf(CompositeByteBuf)
  • CompositeByteBuf是一个特殊的缓冲区,可以将多个ByteBuf实例组合成一个逻辑上的ByteBuf,但实际物理内存仍然是分散的,这种方式在需要将多个小的缓冲区合并为一个大的缓冲区进行传输时非常有用,因为他避免了数据的拷贝和合并。
  1. FileRegion
  • FileRegion允许Netty将文件的一部分直接映射到内存(mmap)或者通过操作系统的页面缓存直接发送到网络通道,从而避免了将文件内容先拷贝到JVM堆内存,再发送出去的传统方式。

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

Netty中的内存池是一种高效的内存管理方式,旨在减少内存分配和回收次数,降低垃圾回收压力,从而提高性能。

  1. 内存池的基本概念
  • 内存池是一种内存管理机制,他 预先分配一定大小的内存块,并将这些内存块存储在一个池中,当需要内存时,直接从池中取出,使用完毕后再放回池中,而不是每次都从操作系统申请或者释放内存。这种方式可以减少内存碎片,提高内存利用率,并降低内存分配和回收的开销。
  1. Netty内存池的特点
  • 使用Jemalloc算法:Netty内存池使用Jemalloc算法进行内存管理和分配,Jemalloc是一种高效的内存分配器,能够减少内存碎片,提高内存分配和回收效率。
  • 分层管理:Netty的内存池被分为多个层级,如small、normal、huge,每个层级对应不同大小的内存块。这种分层管理的方式可以更好的适应不同大小的内存请求,提高内存分配的灵活性。
  • ThreadLocal缓存:Netty使用ThreadLocal方式为每个使用内存池的线程个管理一个PoolThreadCache,作为内存片段的缓存,这样可以避免多线程竞争,提高内存分配的速度。
  • 内存规整化:Netty在分配内存时,会对申请的大小进行规整化处理,确保分配内存的大小是2的幂次方或特定倍数,这样可以减少内存碎片,提高内存利用率。
  1. Netty内存池的工作流程
  • 内存申请:当需要内存时,首先检查ThreadLocal缓存中是否有可用的内存片段,如果有,则直接从缓存中取出;如果没有,则向全局内存池申请。
  • 内存分配:全局内存池根据申请的内存大小,从small、normal、huge中选择合适的内存块进行分配,如果层级内没有足够的内存,可能会向操作系统申请更多的内存。
  • 内存使用:分配到的内存片段被用于存储数据或者其他对象,在Netty中,这些内存片段通常被封装为ByteBuf对象,用于网络传输或者处理数据。
  • 内存回收:当内存片段不再需要时,他会被放回ThreadLocal缓存或者全局内存池中,以便后续重用。如果ThreadLocal缓存已满,则可能会将内存片段放回全局内存池或进行其他处理。

2.5 高效的Reactor线程模型

Netty是一个高性能、异步事件驱动的网络编程框架。他基于NIO提供了一套丰富的API,使得开发者可以轻松的构建可伸缩、可扩展的网络应用。Netty线程模型是其核心特性之一,定义了Netty如何处理网络请求和响应,对应用程序的可伸缩性和性能有着重要影响。

  1. 单Reactor单线程模型
  • 特点: 所有IO操作(连接、接收、发送)都有一个线程来处理。
  • 使用场景:适用于并发连接数较小且业务处理简单的场景。
  • 优缺点:模型简单、没有线程上下文切换开销;但是一个线程处理所有IO操作,容易成为性能瓶颈。
  1. 单Reactor多线程模型
  • 特点:Reactor负责监听和分发事件,但不在处理具体的业务。业务逻辑处理由多个线程组成的线程池来完成。
  • 使用场景:适用于并发连接数较多但业务处理逻辑不是非常复杂的场景。
  • 优缺点:通过多线程处理业务逻辑,提高了系统的并发处理能力;但是Reactor仍然是一个潜在的性能瓶颈,特别是在高并发场景下。
  1. 主从Reactor多线程模型(Boss-Worker模型)
  • 特点:Netty主要基于这种模型,并做了一定的改进,他包含一个或者多个主Reactor和多个从Reactor。主Reactor负责监听和接收客户端的连接请求,并将接收到的连接分配给从Reactor处理。从Reactor负责具体的IO操作和业务逻辑处理。
  • 使用场景:适用于高并发、高负载的场景。
  • Netty实现:
    a. Boss Group:专门负责客户端连接,包含多个NioEventLoop(事件循环),每个 NioEventLoop负责监听和接收连接请求。
    b. Worker Group: 专门负责网络读写,包含多个NioEventLoop,每个NioEventLoop负责处理分配给他的连接上的IO事件,并通过ChannelPipeline中的ChannelHandler进行业务逻辑处理。
  • 优点:通过分离连接处理和IO操作,提高了系统的并发处理能力;灵活可扩展,可以根据需要调整线程池的大小。
    总结: Netty的线程模型是其高性能和可扩展的关键所在,通过合理选择线程模型,并根据应用场景调整线程池的大小,可以充分利用多核CPU的计算能力,提高系统的并发处理能力和吞吐量。在实际应用中,建议根据应用的具体需求和预期负载情况选择合适的线程模型。

2.6 无锁设计、线程绑定

Netty采用了串行无锁化设计,在IO线程内部进行串行操作。避免多线程竞争导致的性能下降,从表面上看,串行化设计似乎CPU利用率不高,并发程度不够,但是 通过调整NIO线程池的线程参数,可以同时启动多个串行化的线程并行执行,这种局部无锁化的串行线程相比一个队列多个工作线程模型性能更优。(换句话说:一个NioEvent事件由一个线程处理,启动多个线程来处理不同的事件,要比一个NioEvent事件多个线程处理性能更优,因为有线程切换、同步等的开销)
在这里插入图片描述
Netty的NioEventLoop读取到消息之后,直接调用ChannelPipeline的fireChannelRead,只要用户不主动切换线程,一直会由NioEventLoop调用到用户的Handler,期间不进行线程切换,这种串行化处理方式避免了多线程操作导致的锁的竞争,从性能角度看是最优的。

2.7 高性能的序列化框架

在Netty中,Google Protobuf是一个特别受欢迎的序列化框架,因为他在编解码速度和字节码流大小方面表现优异。是一种高效的结构化数据存储格式,具有良好的兼容性和可扩展性。

  • 高效:Protobuf的编码和解码速度非常快,且生成的二进制数据体积小,有利于网络传输和存储。
  • 跨平台:支持多种编程语言,可以轻松实现跨平台的数据交换。
  • 向后兼容:Protobuf更新不会破坏已经运行的数据格式的程序。

2.8 小包封大包,防止网络阻塞

“小包封大包,防止网络阻塞” 这一策略,在网络通信中,特别是TCP/IP协议栈的实现中,是一个常见的优化手段。主要涉及到的是TCP的NAGLE算法。

  1. 算法概述:
  • NAGLE算法是一种避免发送大量小数据包的TCP/IP协议优化算法,当启用NAGLE算法是,TCP会将小的数据包缓存起来,而不是立即发送他们。只有当缓存区满了,或者收到了对之前发送数据的确认之后,才会将缓存的数据包合并成一个较大的数据包发送出去。这样做的目的是减少网络中的小数据包数量,从而降低网络拥塞的可能性,提高网络传输效率。
  1. 防止网络阻塞的原理
  • 减少小数据包数量:在网络通信中,小数据包的传输效率通常较低,因为他们会占用大量的网络带宽和处理器资源来处理头部信息和进行路由选择,通过合并小数据包为大数据包,可以减少这些开销,提高网络利用率。
  • 降低网络拥塞风险:大量小数据包的发送容易导致网络拥塞,因为每个数据包都需要单独的网络资源和处理时间。而合并后的大数据包则能够更有效的利用网络资源,减少拥塞的发生。
  • 优化TCP性能:TCP协议本身具有流量控制和拥塞控制机制,但这些机制在处理大量小数据包时可能会变得不够高效,通过NAGLE算法,TCP能够更智能的管理数据包的发送,从而提高整体性能。
  1. 注意事项
  • SO_TCPNODELAY:在Socket编程中,通过设置SO_TCPNODELAY选项来关闭NAGLE算法,当SO_TCPNODELAY被设置为1时,TCP会立即发送数据,而不是等待缓冲区满或者收到ACK后再发送。
  • 时延敏感应用:虽然NAGLE算法能够提高网络传输效率,但也增加了数据包的延迟。因此,时延敏感应用中,需要关闭NAGLE算法以确保数据及时传输。

2.9 软中断和基于Hash值的CPU绑定

在linux环境下,软中断和基于Hash值的CPU绑定是提高网络吞吐量和并行处理性能的重要手段。

  1. 软中断
  • 软中断是Linux内核中用于处理中断的一种机制,特别是在网络子系统中,他用于处理接收到的网络数据包,当网络接口接收到数据包时,他会产生一个硬件中断,这个中断被内核捕获并转化为软中断来处理。软中断的好处是可以减轻CPU负担,因为他允许中断在较低的优先级上执行,而不必立即中断当前CPU上的其他任务。
  • 在Linux内核版本2.6.35及以上,如果支持RPS(Receive Packet Steering 接收包引导)功能, 可以实现基于Hash值的软中断分发。RPC根据数据包的原地址、目的地址、目的和原端口等信息,计算出一个Hash值,然后根据这个Hash值来选择处理该数据包的软中断运行的CPU,这样,每个连接或者数据包类型都可以绑定到特定的CPU上,从而实现CPU的复杂均衡和并行处理。
  1. 基于Hash值的CPU绑定
  • CPU绑定是指将特定的任务或者线程固定到某个CPU核心上运行,以减少线程在CPU之间切换的开销。

总结:在Netty高性能网络通信中,软中断和CPU绑定是提高网络吞吐量和并行处理性能的重要策略。1. 软中断通过基于Hash值的分发机制,将数据包的处理任务均衡的分配给多个CPU核心2. 而CPU绑定则通过减少线程在CPU之间的切换开销,提高特定任务或者线程的执行效率。

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

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

相关文章

玻璃存储还没整明白,陶瓷纳米存储又来了!

关注我们 - 数字罗塞塔计划 - 在信息爆炸的当下,我们每天产生的数据比以往任何时候都多。其实很多数据都是存储后很少被访问,但仍需要长期保存的“冷数据”。磁带、硬磁盘、光盘等传统存储介质难以提供冷数据存储所需的超长寿命、超大容量和持续可访问性…

Docker Compse单机编排

一.Docker Compse 介绍 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,你可以使用 YAML 文件来配置应用程序的服务、网络和卷,然后使用单个命令创建和启动所有服务。这使得在开发、测试和部署过程中管理多容器应用程…

精彩分享|暴雨亮相第二十届智能计算国际会议(ICIC 2024)

8月6日至8日,第二十届智能计算国际会议(ICIC 2024)在天津盛大召开,这场由宁波东方理工大学(暂名)主办,天津科技大学承办,中国矿业大学(北京)、中国矿业大学和…

【学习笔记】Matlab和python双语言的学习(非线性规划法)

文章目录 前言一、非线性规划法二、例题:选址问题1.确定决策变量2.确定约束条件3.确定目标函数4.建立模型5.求解 三、代码实现----Matlab1.Matlab 的 fmincon 函数(1)基本用法(2)简单示例 2.Matlab 代码第一问&#xf…

RegNet 图像识别网络,手写阿拉伯数字的图像分类

1、RegNet 网络介绍 regnet 是一个深度学习模型架构,用于图像分类任务。它是由 Facebook AI Research(FAIR)提出的,旨在实现高效的网络设计。regnet 通过在不同的网络层级上增加网络宽度和深度来提高模型性能。 regnet 的设计思…

如何使用 AWS CLI 创建和运行 EMR 集群

为初学者提供清晰易懂的教程 为初学者提供清晰易懂的教程 Apache Spark 和 AWS EMR 上的 Spark 集群 添加图片注释,不超过 140 字(可选) 欢迎来到雲闪世界。Spark 被认为是“大数据丛林之王”,在数据分析、机器学习、流媒体和图形…

DataWhale AI夏令营第四期-魔搭生图task1学习笔记

根据教程提供的链接,进入相应文章了解魔搭生图的主要工作是通过对大量图片的训练,生成自己的模型,然后使用不同的正向、反向提示词使模型输出对应的图片 1.官方跑baseline教程链接:Task 1 从零入门AI生图原理&实践 2.简单列举一下赛事的…

【K8S】K8S架构及相关组件

文章目录 1 K8S总体架构2 相关组件2.1 控制面板组件2.2 节点组件2.3 附加组件 写在最后 1 K8S总体架构 K8S,全称Kubernetes,是一个开源的容器部署和管理平台,由Google开发,后捐献给云原生计算基金会(CNCF)…

algorithm算法库学习之——修改序列的操作2

algorithm此头文件是算法库的一部分。本篇介绍修改序列的操作函数。(2) 修改序列的操作 fill 将一个给定值复制赋值给一个范围内的每个元素 (函数模板) fill_n 将一个给定值复制赋值给一个范围内的 N 个元素 (函数模板) generate 将相继的函数调用结果赋…

Debezium日常分享系列之:Debezium UI 的状态

Debezium日常分享系列之:Debezium UI 的状态 一、下一阶段工作二、设计新的UI三、目前阶段四、更多内容 虽然Debezium的UI是我们愿景的重要组成部分,但开发与Kafka Connect紧密绑定的UI并不是正确的方向。因此,决定冻结当前Web UI项目的开发。…

红酒与高尔夫:球场上的优雅选择

在绿茵茵的高尔夫球场上,每一次挥杆都充满了力量与优雅。而当这优雅的运动与洒派红酒(Bold & Generous)的醇厚邂逅,一场视觉与感官的盛宴便悄然上演。今天,就让我们一起走进这个充满魅力的世界,感受红酒…

【动态规划】1、不同路径II+2、三角形最小路径和

1、不同路径II&#xff08;难度中等&#xff09; 该题对应力扣网址 AC代码 只会写简单的if-else class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {//1、定义子问题//2、子问题递推关系//3、确定dp数组的计算顺序…

快速入手mybits(xml配置文件版本)

目录 Blue的留声机 1、快速入手 第一步&#xff1a;导依赖 第二步&#xff1a;配置mybits-config.xml文件 第三步&#xff1a;编写sql映射文件BlogMapper.xml 第四步&#xff1a;编写运行文件&#xff0c;执行sql 2、Mapper代理开发&#xff08;企业中最常用&#xff09;…

GraphRAG

GraphRAG 与基线 RAG RAG 检索增强生成 &#xff08;RAG&#xff09; 是一种使用真实世界信息改进 LLM 输出的技术。这种技术是大多数基于 LLM 的工具的重要组成部分&#xff0c;大多数 RAG 方法使用向量相似性作为搜索技术&#xff0c;我们称之为基线 RAG。 RAG 技术在帮助 …

立即升级你的前端技能!跟随这份Vue3项目搭建教程,从零基础到专业,一步步掌握最新Web开发技术,打造响应快速、界面优雅的现代网站。

全能开发套餐&#xff0c;轻松打造现代网站&#xff01;Vue3携手Vite带来开发新体验&#xff0c;结合Axios、Pinia、Element Plus实现功能与美观并重&#xff0c;TailwindCSS与DaisyUI提供设计灵活性&#xff0c;Router 4处理页面导航。从前端到后端&#xff0c;一站式解决&…

必看!全网最详细的仓库管理办法!

如今仓库管理的优劣直接影响着企业的运营效率和成本控制。一个高效、有序的仓库能够确保货物的及时供应&#xff0c;减少库存积压&#xff0c;提高客户满意度&#xff1b;而一个混乱、无序的仓库则可能导致货物丢失、损坏&#xff0c;延误交货&#xff0c;甚至影响企业的声誉和…

【宠粉赠书】Python数据可视化:科技图表绘制

为了回馈粉丝们的厚爱&#xff0c;今天小智给大家送上一套数据可视化学习的必备书籍——《Python数据可视化&#xff1a;科技图表绘制》。下面我会详细给大家介绍这本书&#xff0c;文末留有领取方式。 图书介绍 《Python数据可视化&#xff1a;科技图表绘制》结合编者多年的数…

顶象文字点选模型识别

注意&#xff0c;本文只提供学习的思路&#xff0c;严禁违反法律以及破坏信息系统等行为&#xff0c;本文只提供思路 如有侵犯&#xff0c;请联系作者下架 文字点选如何训练&#xff0c;之前的文章说了很多遍了&#xff0c;这里只放现成的模型供查看&#xff0c;有需要成品联系…

datax做增量导入数据到hive:mysql>hive

为什么要做增量导入? 例如mysql表中的数据导入hive&#xff0c;如果第一天抽取了mysql中t_user表中的全部数据&#xff0c;则第二天只需要抽取新增数据即可&#xff01; 增加导入是利用where 条件查询实现的&#xff0c;查询条件一般是自增的id或者时间列 下面演示基于时间列的…

sns.regplot()用法

概念 seaborn.regplot&#xff08;&#xff09;函数可以在两个变量之间绘制一个线性回归模型&#xff0c;可以输出线性回归线以及数据的散点图。 参数解释 seaborn.regplot(dataNone, xNone, yNone, x_estimatorNone, x_binsNone, x_cici, scatterTrue, fit_regTrue, ci95, …