Netty剖析 - Why Netty

news2024/9/25 3:28:48

文章目录

  • Why Netty
  • I/O 请求的两个阶段
  • I/O 模型
  • Netty 如何实现自己的 I/O 模型
  • 线程模型 - 事件分发器(Event Dispather)
  • 弥补 Java NIO 的缺陷
  • 更低的资源消耗
  • 网络框架的选型
  • Netty 发展现状
  • Netty 的使用
  • 思维导图

在这里插入图片描述


Why Netty

  1. I/O 模型、线程模型和事件处理机制优化: Netty 提供了多种 I/O 模型,包括 NIO、Epoll、Kqueue 等,可以根据具体需求选择最适合的模型。其线程模型灵活,支持多种线程池模式,可以有效地利用多核处理器资源。事件处理机制采用了 Reactor 模式,使得并发处理变得简单高效。

  2. 易用性 API 接口: Netty 的 API 设计简洁清晰,提供了丰富的功能组件和工具类,使得开发者可以轻松地构建复杂的网络应用。同时,Netty 提供了良好的文档和示例,降低了学习成本,提高了开发效率。

  3. 对数据协议、序列化的支持: Netty 提供了丰富的编解码器和扩展点,支持各种常用的数据协议(如 HTTP、WebSocket、SSL/TLS 等)和序列化框架(如 Protobuf、JSON、MessagePack 等),可以方便地实现自定义的数据格式和处理逻辑。

  4. 健壮性、性能、可扩展性: Netty 经过了长时间的发展和优化,已经在大规模生产环境中得到了广泛应用和验证。其底层的网络组件经过精心设计和优化,具有出色的性能和稳定性。同时,Netty 提供了丰富的扩展机制和插件系统,可以方便地定制和扩展功能。

综上所述,Netty 在 I/O 模型、线程模型、事件处理机制、易用性 API 接口以及对数据协议、序列化的支持等方面表现优异,因此成为了开发高性能网络应用的首选框架。


I/O 请求的两个阶段

实现高性能的网络应用框架离不开 I/O 模型问题, 理解 I/O 模型的基本知识对于理解 Netty 的高性能原理至关重要。在网络编程中,I/O 请求通常分为两个阶段:调用阶段和执行阶段。

在这里插入图片描述

  1. 调用阶段: 在调用阶段,用户进程向内核发起系统调用,请求进行 I/O 操作,例如读取数据或写入数据。

  2. 执行阶段: 在执行阶段,内核等待 I/O 请求的处理完成,并返回结果给用户进程。执行阶段又可分为两个过程:

    • 等待数据就绪并写入内核缓冲区: 在这个阶段,内核等待数据准备就绪,例如等待网络数据到达或磁盘数据就绪,并将数据写入内核缓冲区,以便用户进程可以访问。

    • 将内核缓冲区数据拷贝至用户态缓冲区: 一旦数据就绪并写入内核缓冲区,内核将数据从内核缓冲区拷贝到用户态缓冲区,以便用户进程可以处理数据。

在传统的阻塞 I/O 模型中,用户进程在执行阶段会被阻塞,直到所有 I/O 操作完成。而在异步 I/O 模型中,用户进程可以继续执行其他任务,而不必等待 I/O 操作完成,从而提高了系统的并发性和吞吐量。

Netty 通过采用异步、事件驱动的模型,并结合高效的 I/O 多路复用机制(如 epoll、kqueue 等),在处理大量并发连接时表现出色,从而实现了高性能和低延迟的网络应用。


I/O 模型

在这里插入图片描述

  1. 同步阻塞 I/O(BIO):

    • 特点: 在进行 I/O 操作时,调用线程会被阻塞,直到操作完成。
    • 优点: 编程模型简单。
    • 缺点: 需要为每个连接创建一个线程,资源消耗较大。
  2. 同步非阻塞 I/O(NIO):

    • 特点: 调用线程不会阻塞,但需要轮询来检查 I/O 是否完成。
    • 优点: 节省了线程资源,提高了并发性。
    • 缺点: 轮询过程中可能出现大量系统调用,导致性能浪费。
  3. I/O 多路复用(select/poll/epoll):

    • 特点: 使用一个线程同时监听多个 I/O 事件,当其中一个事件就绪时,唤醒对应的线程进行处理。
    • 优点: 解决了同步阻塞和同步非阻塞模型中资源消耗和性能浪费的问题,提高了并发性能。
    • 缺点: 在连接数较多时,系统调用开销较大。
  4. 信号驱动 I/O:

    • 特点: 内核通过发送信号通知应用进程何时可以开始一个 I/O 操作。
    • 优点: 操作相对异步,不会阻塞调用线程。
    • 缺点: 使用较少,且在信号处理方面有一定复杂性。
  5. 异步 I/O:

    • 特点: I/O 操作的完整过程(包括将数据从内核缓冲区拷贝到用户态缓冲区)都由系统异步完成,应用进程只需等待通知即可。
    • 优点: 最大程度上减少了系统调用和上下文切换的开销,提高了性能。
    • 缺点: 实现较复杂,且对操作系统的支持要求较高。

Netty 如何实现自己的 I/O 模型

Netty 构建在 JDK 的 NIO 框架之上,利用了其提供的非阻塞 I/O 特性,并通过多路复用器 Selector 实现了自己的高效 I/O 模型。

  1. 基于非阻塞 I/O: Netty采用了非阻塞 I/O,即在进行网络通信时,不会阻塞当前线程,而是通过异步方式处理 I/O 事件。

  2. 使用 Selector 实现多路复用: Netty的核心是多路复用器 Selector。一个 Selector 实例可以同时轮询多个 Channel,以检查是否有 I/O 事件发生。这样,Netty 可以在一个线程中管理多个连接,而无需为每个连接创建一个线程,从而减少了线程资源的开销。

  3. 采用 epoll 模式: Netty 在 Linux 系统下会优先使用 epoll 作为底层的多路复用技术。epoll 是一种高效的事件通知机制,能够有效地处理大量并发连接。在 epoll 模式下,Netty 只需要一个线程负责调用 epoll_wait() 系统调用来轮询注册在 Selector 上的事件,从而可以接入成千上万的客户端而不会出现性能瓶颈。

  4. 适配不同操作系统: Netty 不仅仅在 Linux 下使用 epoll,还会根据不同的操作系统选择合适的多路复用技术,如在 Windows 平台下会使用 IOCP(Input/Output Completion Port),以达到最佳的性能表现。

综上所述,Netty 的 I/O 模型基于 JDK NIO 框架,利用了非阻塞 I/O 和多路复用器 Selector,并根据不同的操作系统选择合适的底层多路复用技术,从而实现了高性能、低延迟的网络通信。


线程模型 - 事件分发器(Event Dispather)

在这里插入图片描述

在 Netty 中采用的是主从 Reactor 多线程模型,这是一种高效的事件驱动模型,有助于实现高性能、低延迟的网络通信。

  1. 主从 Reactor 多线程模型: 在该模型中,有两类线程,即主线程和从线程。主线程负责接收客户端的连接,并将连接注册到 I/O 多路复用器(如 Selector)上。从线程则负责处理 I/O 事件,当有 I/O 事件就绪时,从线程从 I/O 多路复用器中获取事件,并将事件分发给对应的事件处理器进行处理。

  2. 事件分发器: 在 Netty 中,事件分发器的角色由从线程扮演。从线程负责从 I/O 多路复用器中获取就绪的事件,并将事件分发给对应的事件处理器进行处理。这种设计避免了同步问题和多线程切换带来的资源开销,从而提高了系统的性能和并发处理能力。

  3. 简化处理逻辑: 主从 Reactor 多线程模型将接收连接和处理 I/O 事件的工作分开,使得系统的处理逻辑更加清晰和简单。主线程只负责接收连接,而从线程则专注于处理 I/O 事件,降低了系统的复杂度和维护成本。

  4. 高性能、低延迟: 通过主从 Reactor 多线程模型,Netty 实现了高性能、低延迟的网络通信。主线程和从线程之间的工作分配清晰,避免了线程间的竞争和同步问题,同时有效利用了多核处理器的性能优势,从而实现了高效的事件驱动和并发处理。

综上所述,Netty 的主从 Reactor 多线程模型结合了 Reactor 模式和多线程技术,通过合理分配工作任务和减少同步开销,实现了高性能、低延迟的网络通信。


弥补 Java NIO 的缺陷

Netty 相对于 JDK 的 NIO 框架有着几个显著的优势,这些优势使得 Netty 成为了许多开发者选择的首选框架:

  1. 易用性: Netty对 JDK NIO 进行了更高层次的封装,屏蔽了底层 NIO 的复杂性。它提供了更加人性化的 API,使得开发者无需深入理解 NIO 的底层概念(如 Channels、Selectors、Sockets、Buffers),就能够快速上手进行网络编程。此外,Netty还提供了大量开箱即用的工具和组件,如编解码器、长度域解码器等,极大地简化了开发过程。

  2. 稳定性: Netty 对 JDK NIO 存在的一些已知问题进行了修复和优化,提高了系统的稳定性和可靠性。例如,修复了 select 空转导致 CPU 消耗高的问题,改进了 TCP 断线重连和 keep-alive 检测等方面的功能。

  3. 可扩展性: Netty 提供了强大的可扩展性,使得开发者可以根据自身需求定制化线程模型和事件驱动模型。对于线程模型,Netty允许用户通过启动配置参数选择 Reactor 线程模型,以满足不同的性能和并发需求;而在事件驱动模型方面,Netty实现了框架层和业务层的关注点分离,使得开发者只需专注于业务逻辑的实现,而不必过多关注底层的网络处理细节。


更低的资源消耗

Netty 通过采用对象池复用技术和零拷贝技术,有效降低了 JVM 垃圾回收的压力,从而实现了更低的资源消耗。

  1. 对象池复用技术: Netty 使用对象池来复用对象,避免频繁创建和销毁对象所带来的开销。在网络通信过程中,需要处理大量的网络数据对象,如果每次都新建对象,将会增加垃圾回收的压力。通过使用对象池,Netty 可以重复利用已经创建的对象,减少了对象创建和销毁的次数,从而降低了垃圾回收的频率,提高了系统的性能和稳定性。

  2. 零拷贝技术: Netty 在 I/O 读写过程中采用了零拷贝技术,避免了数据在不同内存区域之间的拷贝操作。例如,在进行网络数据传输时,Netty 直接使用 DirectBuffer,这样数据可以直接从操作系统内核缓冲区复制到用户空间的 DirectBuffer 中,而无需经过堆内存,从而避免了数据在堆内存和堆外内存之间的拷贝。这种零拷贝的技术不仅提高了数据传输的效率,还减少了内存的使用,降低了垃圾回收的压力,提高了系统的性能。

Netty 通过对象池复用技术和零拷贝技术的应用,有效降低了 JVM 垃圾回收的压力,减少了资源的消耗,从而实现了更低的资源消耗,在网络编程中得到了广泛的应用和青睐。


网络框架的选型

在选择网络框架时,需要根据项目的需求和特点来决定使用哪种框架。

  1. 通信协议支持:

    • Tomcat 主要解决 HTTP 协议层的传输,适合构建 Web 应用。
    • Netty 不仅支持 HTTP 协议,还支持 SSH、TLS/SSL 等多种应用层的协议,同时具有自定义应用层协议的能力。适用于需要定制协议或多种协议支持的场景。
  2. 性能和并发能力:

    • Tomcat 在 Servlet 3.0 之后支持了 NIO,但仍然受到 Servlet 规范的限制,适用于低并发或者传统的 Web 应用。
    • Netty 的设计不受 Servlet 规范的限制,能够最大化发挥 NIO 特性,适用于高并发、大规模网络通信的场景。
  3. 易用性和稳定性:

    • Tomcat 在 Web 开发领域有着较长时间的应用和成熟的生态系统,易于上手且稳定可靠。
    • Netty 在面向 TCP 的网络应用开发方面有着丰富的经验和灵活的设计,提供了丰富的功能和易于扩展的接口,但相对而言可能需要更多的学习和适应时间。
  4. 其他选择:

    • Mina 和 Grizzly 是其他可选的网络框架,但相对于 Netty,它们在设计和功能上可能不如 Netty 灵活和优雅。

Netty 发展现状

Netty在过去几年里取得了显著的发展,并且得到了广泛的应用和认可。

  1. 社区活跃度高: Netty拥有一个活跃的社区,迭代周期短,文档齐全。开发者可以通过官方社区、GitHub等平台获取学习资料和技术支持。

  2. 稳定版本推荐: Netty官方提供了稳定的3.x和4.x版本。3.x到4.x的升级带来了较大的变化,但主流推荐使用4.x版本,因为它提供了更多的优化和新特性。

  3. 项目结构调整: Netty从3.x到4.x版本进行了项目结构的调整,模块化程度更高,包名也从org.jboss.netty更新为io.netty。

  4. API改进和优化: Netty 4.x版本中引入了流式风格的API,并对Buffer相关功能进行了优化和调整,提高了性能和健壮性。

  5. 内存管理优化: Netty 4.1版本开始使用jemalloc作为默认的内存分配方式,提高了内存管理的效率,减少了GC压力。

  6. 线程模型优化: Netty 4.x提供了更严谨的线程模型控制,降低了用户编写ChannelHandler时的线程安全问题,使得编程更加简洁和高效。

  7. 其他新特性: Netty 4.x还引入了一些其他新特性,如内存泄漏检测功能、通用工具类等,进一步提升了框架的性能和易用性。


Netty 的使用

https://netty.io/wiki/related-projects.html

使用Netty的知名公司和项目:

  • 服务治理: Apache Dubbo和gRPC等服务治理框架都采用了Netty作为底层通信框架,用于实现高效的远程服务调用和通信。

  • 大数据: Hbase、Spark、Flink和Storm等大数据处理框架也使用了Netty作为底层通信框架,用于实现大规模数据处理和分布式计算。

  • 搜索引擎: Elasticsearch作为一款流行的搜索引擎,同样选择了Netty作为其底层通信框架,用于处理搜索请求和响应。

  • 消息队列: RocketMQ等消息队列系统也采用了Netty作为底层通信框架,用于实现高性能的消息传输和处理。


思维导图

在这里插入图片描述

戳这里

在这里插入图片描述

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

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

相关文章

货币系统(闫氏DP分析法)

题目描述: 给定 V 种货币(单位:元),每种货币使用的次数不限。 不同种类的货币,面值可能是相同的。 现在,要你用这 V 种货币凑出 N 元钱,请问共有多少种不同的凑法。 输入格式&am…

深入Facebook的世界:探索数字化社交的无限可能性

引言 随着数字化时代的到来,社交媒体平台已经成为了人们日常生活中不可或缺的一部分,而其中最为突出的代表之一便是Facebook。作为全球最大的社交媒体平台之一,Facebook不仅仅是一个社交网络,更是一个数字化社交的生态系统&#…

Windows/Linux-openEuler系统使用路由侠内网穿透,部署项目详细教程

文章目录 Windows/Linux-openEuler系统使用路由侠内网穿透,部署项目详细教程一、在windows系统下载安装路由侠并实现项目部署1、下载路由侠并注册安装到Windows系统2、点击内网映射,添加映射,注册域名前缀3、选择网站应用4、配置你想要代理项…

【Bug-ModuleNotFoundError: No module named ‘models‘】

🚀 作者 :“码上有前” 🚀 文章简介 :Python 🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬 出现这个错误: 出现了ModuleNotFoundError: No module named models’的问题。 文件在Model…

「吞噬星空」存在哪些境界,不朽级呼延博是否有一席之位?

吞噬星空中浩瀚无垠的宇宙,其深邃与广阔,仿佛一个无尽的迷宫,蕴藏着无数未知的境界。从地球出发,见证了行星级与恒星级的威能,然而这只是宇宙力量的冰山一角。行星级强者,在地球上已是至高无上的存在&#…

MTransE阅读笔记

Multilingual Knowledge Graph Embeddings for Cross-lingual Knowledge Alignment 用于交叉知识对齐的多语言知识图谱嵌入(MTransE) Abstract 最近的许多工作已经证明了知识图谱嵌入在完成单语知识图谱方面的好处。由于相关的知识库是用几种不同的语言构建的,因…

2010-2021年银行网点及员工信息数据

2010-2021年银行网点及员工信息数据 1、时间:2010-2021年 2、来源:整理自csmar 3、指标:银行代码、股票代码、银行中文简称、统计截止日期、分行数量、机构网点数量、其中:境内网点数量、其中:境外网点数量、在职员…

python和c语言的区别是什么

Python可以说是目前最火的语言之一了,人工智能的兴起让Python一夜之间变得家喻户晓,Python号称目前最最简单易学的语言,现在有不少高校开始将Python作为大一新生的入门语言。本萌新也刚开始接触Python,发现Python与其他语言确实有…

在Semantic Kernel中使用Qdrant向量数据库

本文将介绍如何在Semantic Kernel中使用Qdrant向量数据库,并演示如何在Semantic Kernel中进行向量更新和查询操作。 1. 背景 在前一篇文章《Qdrant 向量数据库的部署以及如何在 .NET 中使用 TLS 安全访问》中,我们介绍了如何使用 Docker 部署 Qdrant 向…

9-Dubbo源码分析之:Dubbo Serialize 层:多种序列化算法,总有一款适合你

通过前面课时的介绍,我们知道一个 RPC 框架需要通过网络通信实现跨 JVM 的调用。既然需要网络通信,那就必然会使用到序列化与反序列化的相关技术,Dubbo 也不例外。下面我们从 Java 序列化的基础内容开始,介绍一下常见的序列化算法…

PCB损耗来源

信号经过PCB板会产生损耗,主要包括导体损耗,介电损耗和辐射损耗 导体损耗:导体损耗是由于电流流动过程中产生电阻损耗而发热。 介电损耗:介电损耗是由于电场通过介质时分子的交替极化和晶格碰撞造成的。 辐射损耗:辐…

能够解析任何编程语言的开源语法解析树 | 开源日报 No.171

tree-sitter/tree-sitter Stars: 14.6k License: MIT tree-sitter 是一个用于编程工具的增量解析系统。 该项目的主要功能、关键特性、核心优势包括: 通用性,能够解析任何编程语言高效性,能够在文本编辑器中每次按键都进行解析健壮性&…

pygame用chatgpt绘制3d沿x轴旋转的

import pygame from pygame.locals import * import sys import mathpygame.init()width, height 800, 600 screen pygame.display.set_mode((width, height))vertices [(0, 100, 0), (100, 200, 0), (300, 100, 0)]angle 0 rotation_speed 2 # 可根据需要调整旋转速度 c…

javaWeb项目-火车票订票信息系统功能介绍

项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架:ssm、Springboot 前端:Vue、ElementUI 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog 1、Spring Boot框架 …

c++核心学习--继承2

4.6.7多继承语法 4.6.8菱形继承 利用虚继承解决菱形继承的问题:继承之前加上关键字virtual变为虚继承

35岁的程序员,该何去何从?

2024 年,是充满未知和挑战的一年。AI 的发展日新月异,已经有人用它来写代码了,啥时候会替代程序员,可真不好说。另一方面,程序员扎堆的 IT 互联网行业却进入了平台期甚至下行期,降本增效成为行业主流&#…

详细解析记忆泊车的顶层技术原理

详细解析记忆泊车的顶层技术原理 附赠自动驾驶学习资料和量产经验:链接 相对于记忆行车而言,记忆泊车 MPA(Memory Parking Assist)可以看成是停车场区域内的一个自动驾驶功能,可帮助用户按记忆的路线自动巡航并泊入车…

Kubernetes 知识体系 系列一

多年前,大多数软件应用程序都是大型的单体,要么作为单个进程运行,要么作为少数服务器上的少量进程运行。这种过时的系统一直延续很久。 它们的发布周期较慢,更新相对较少。 在每个发布周期结束时,开发人员将整个系统…

第三十二天-PythonWeb主流框架-Django框架

目录 1.介绍 发展历史 介绍 2.使用 1.安装 2.创建项目 3.项目结构 4.启动 3.开发流程 1.设置ip可访问 2.创建模块 3.第一个页面 4.视图 5.include()参数 6.url与视图的关系 7.响应内容 4.视图处理业务逻辑 1.响应html 2.获取url参数 3.从文件响应html内容 …

一招让你的薪水暴增,每个程序员都应该学会跟老板提加薪

为什么要学会薪资谈判? 在最近的一篇文章中,职业专家奥斯汀贝尔卡克 (Austin Belcak ) 解释了进行一点薪资谈判如何对您的长期收入产生巨大影响。 这是奥斯汀在他的薪资谈判示例中描绘的场景: Amari 和 Taylor 的年薪均为 50,000 美元 未来…