Netty基本原理

目录

前言

原生NIO VS Netty

原生NIO存在的问题

Netty的优点

线程模型

传统阻塞 I/O (Blocking I/O)

2. 非阻塞 I/O (Non-blocking I/O)

3. 多路复用 I/O (Multiplexed I/O)

4. Reactor 模式

常见的 Reactor 模式的变体:

Netty线程模型

工作原理


前言

Netty是一个高性能、异步、高可靠性,基于事件驱动的网络应用程序框架和工具,用于快速开发可维护的高性能和高可扩展性的协议服务器和客户端,换句话说,Netty是一个基于NIO客户端服务器框架,它简化Java 原生NIO开发难度,是目前最流行的NIO框架,Netty在互联网应用领域、游戏领域、大数据分布式计算领域都有广泛的应用,比如分布式服务框架Dobbo,分布式检索引擎ElasticSearch,大数据计算引擎Spark、Flink等都采用Netty作为网络通信的框架。

原生NIO VS Netty

原生NIO存在的问题

  • 复杂性:
    • NIO设计相对复杂,开发者需要处理许多底层细节,如缓冲区管理,通道操作等。
    • 需要手动管理资源,容易出现资源泄露。
    • 缺乏直观API设计
  • 开发工作量大:
    • NIO涉及多线程和异步编程,学习成本高,开发者需要更多的代码实现相同的功能
    • 编解码繁琐,NIO本身不提供高级的编解码能力,开发者需要自己实现数据的序列化和反序列化
  • 缺少内置协议的支持,不支持Http,Ftp协议的支持

Netty的优点

  • 设计优雅:适用于各种传输类型的统一 API 阻塞和非阻塞 Socket;基于灵活且可扩展的事件模型,可以清晰地分离关注点;高度可定制的线程模型 - 单线程,一个或多个线程池.
  • 性能优秀:Netty 设计用于处理大量的并发连接,并且能够在较低的资源消耗下实现高吞吐量,利用了操作系统级别的多路复用技术,减少了线程上下文切换的开销。
  • 丰富的功能:
    • 内置了许多常用的编解码器,支持多种协议,如 HTTP、WebSocket、SMTP
    • Netty 支持 SSL/TLS 加密,确保数据传输的安全性
    • Netty 提供了灵活的 ChannelPipeline 模型,允许开发者轻松地添加、删除或替换处理逻辑
  • 强大的社区支持:Netty 拥有一个活跃的开源社区,提供了丰富的文档、教程和支持,社区贡献了大量的示例代码和插件,帮助开发者快速上手。

线程模型

传统阻塞 I/O (Blocking I/O)

  • 特点:
    • 每个连接由一个独立的线程处理。
    • 线程在等待 I/O 操作完成时会被阻塞。
  • 优点:
    • 实现简单,易于理解。
  • 缺点:
    • 高并发情况下需要大量的线程,导致资源消耗大。
    • 线程上下文切换开销高,影响性能。

2. 非阻塞 I/O (Non-blocking I/O)

  • 特点:
    • 使用 NIO 技术,I/O 操作不会阻塞线程。
    • 通过选择器(Selector)管理多个通道(Channel),实现单线程或多线程处理多个连接。
  • 优点:
    • 更高效地处理大量并发连接。
    • 减少线程数量和上下文切换开销。
  • 缺点:
    • 实现复杂,开发者需要手动管理状态和缓冲区。
    • 调试困难,错误处理复杂。

3. 多路复用 I/O (Multiplexed I/O)

  • 特点:
    • 使用操作系统级别的 I/O 多路复用机制(如 selectpollepoll)来监视多个文件描述符。
    • 单个线程可以同时处理多个连接的 I/O 事件。
  • 优点:
    • 高效地处理大量并发连接。
    • 减少了线程的数量和上下文切换。
  • 缺点:
    • 实现相对复杂。
    • 性能受限于操作系统的 I/O 多路复用机制。

4. Reactor 模式

  • 特点:
    • 主要用于构建高并发服务器。
    • 使用一个或多个 Reactor 线程来分派 I/O 事件到相应的处理器。
  • 优点:
    • 可以处理大量并发连接。
    • 分离了 I/O 处理和业务逻辑处理。
  • 缺点:
    • 实现复杂,特别是对于复杂的业务逻辑。
    • 错误处理和调试较为困难。
常见的 Reactor 模式的变体:
  • 单线程 Reactor:
    • 所有的 I/O 事件和业务逻辑都在一个线程中处理。
    • 适合简单的应用场景,但不适合高负载场景。
  • 多线程 Reactor:
    • 使用多个工作线程来处理业务逻辑。
    • 提高了吞吐量,但仍需处理线程同步问题。
  • 主从 Reactor:
    • 主 Reactor 处理新连接请求,从 Reactor 处理已建立连接的 I/O 事件。
    • 提高了系统的可伸缩性和稳定性

1.Reactor主线程 MainReactor 对象通过select 监听连接事件, 收到事件后,通过Acceptor 处理连接事件

2.当 Acceptor 处理连接事件后,MainReactor 将连接分配给从Reactor

3.从Reactor 将连接加入到连接队列进行监听,并创建handler进行各种事件处理

4.当有新事件发生时, 从reactor 就会调用对应的handler处理

5.handler 通过read 读取数据,分发给后面的worker 线程处理

6.worker 线程池分配独立的worker 线程进行业务处理,并返回结果

7.handler 收到响应的结果后,再通过send 将结果返回给client

8.Reactor 主线程可以对应多个Reactor 子线程, 即MainRecator 可以关联多个SubReactor

Netty就是基于Reactor模式实现的线程模型。

Netty线程模型

工作原理

Netty抽象出两组线程池,Boss Group负责接收客户端的连接,Worker Group负责网络的读写,Boss Group和Worker Group的类型都是NioEventLoop

NioEventLoopGroup是一个事件循环组,这个组有多个线程,每个线程包含一个NioEventLoop

NioEventLoop表示一个不断执行任务的循环线程,每个NioEventLoop都有一个Selector,用于监听绑定在该通道上的socket网络通讯

BossNioEventLoop循环执行步骤:

1.轮询accept事件

2.处理accept事件,与客户端建立连接,生成NioSocketChannel,并将其注册某个worker NioEventLoop上的selector上

3.处理任务队列的任务,即runAllTasks

每个WorkerNioEventLoop循环执行步骤

1.轮询read/write事件

2.处理read/write事件,在对应的NioSocketChannel上处理

3.处理任务队列的任务,即runAllTasks

每个WorkerNioEventLoop处理业务时,会使用Pipeline,pipeline中包含了bossGroup上NioEventLoop注册到Worker的selector的channel,即通过pipeline可以获取到对应的channel,channel中维护了很多Hander

Netty ChannelHandler组件

ChannelHandler UML图如下:

Netty 中的 ChannelHandler 的作用是,在当前 ChannelHandler 中处理 IO 事件,并将其传递给 ChannelPipeline 中下一个 ChannelHandler 处理,因此多个 ChannelHandler 形成一个责任链,责任链位于 ChannelPipeline 中。

数据在基于 Netty 的服务器或客户端中的处理流程是:读取数据-->解码数据-->处理数据-->编码数据-->发送数据。其中的每个过程都用得到 ChannelHandler 责任链。

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

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

相关文章

MySQL系列之数据类型(Numeric)

导览 前言一、数值类型综述二、数值类型详解1. NUMERIC1.1 UNSIGNED或SIGNED1.2 数据类型划分 2. Integer类型取值和存储要求3. Fixed-Point类型取值和存储要求4. Floating-Point类型取值和存储要求 结语精彩回放 前言 MySQL系列最近三篇均关注了和我们日常工作或学习密切相关…

一学就废|Python基础碎片,格式化F-string

Python 3.6 中引入了 f-string语法,提供了一种简洁直观的方法来将表达式和变量直接嵌入到字符串中进行字符串格式化,f -string背后的想法是使字符串插值更简单。 要创建 f -string,在字符串前加上字母 “f”即可,与字符串本身的格…

在 Mac(ARM 架构)上安装 JDK 8 环境

文章目录 步骤 1:检查系统版本步骤 2:下载支持 ARM 的 JDK 8步骤 3:安装 JDK步骤 4:配置环境变量步骤 5:验证安装步骤 6:注意事项步骤7:查看Java的安装路径 在 Mac(ARM 架构&#xf…

【AI绘画】Midjourney进阶:色调详解(上)

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 💯前言💯Midjourney中的色彩控制为什么要控制色彩?为什么要在Midjourney中控制色彩? 💯色调白色调淡色调明色调 &#x1f4af…

【C++】LeetCode:LCR 023. 相交链表

题干 LCR 023. 相交链表 的头节点 headA 和 headB ,请找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意,函数返回结果…

【Linux学习】【Ubuntu入门】2-5 shell脚本入门

1.shell脚本就是将连续执行的命令携程一个文件 2.第一个shell脚本写法 shell脚本是个纯文本文件,命令从上而下,一行一行开始执行,其扩展名为.sh,shell脚本第一行一定要为:#!/bin/bash,表示使用bash。echo…

【C++】list模拟实现(完结)

1.普通迭代器(补充) 1.1 后置和后置-- 我们迭代器里面实现了前置和前置--,还需要实现后置和后置--。 在list.h文件的list_iterator类里面实现。 //后置/-- Self& operator(int) {Self tem(*this);//保存原来的值_node _node->_nex…

基于Python的飞机大战复现

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

MR30分布式 IO 模块在冷却水泵系统中的卓越应用

在当今各类工业生产以及大型设施运行的场景中,冷却水泵系统起着至关重要的作用,它犹如保障整个运转体系顺畅运行的 “血液循环系统”,维持着设备适宜的温度环境,确保其稳定、高效地工作。而随着科技的不断发展,明达技术…

银河麒麟桌面系统——桌面鼠标变成x,窗口无关闭按钮的解决办法

银河麒麟桌面系统——桌面鼠标变成x,窗口无关闭按钮的解决办法 1、支持环境2、详细操作说明步骤1:用root账户登录电脑步骤2:导航到kylin-wm-chooser目录步骤3:编辑default.conf文件步骤4:重启电脑 3、结语 &#x1f49…

多线程常见问题集

一、多线程预防和避免线程死锁 如何预防死锁? 破坏死锁的产生的必要条件即可: 破坏请求与保持条件:一次性申请所有的资源。破坏不剥夺条件:占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释…

Java ArrayList 与顺序表:在编程海洋中把握数据结构的关键之锚

我的个人主页 我的专栏:Java-数据结构,希望能帮助到大家!!!点赞❤ 收藏❤ 前言:在 Java编程的广袤世界里,数据结构犹如精巧的建筑蓝图,决定着程序在数据处理与存储时的效率、灵活性以…

【第三方云音乐播放器SPlayer本地安装结合内网穿透打造个性化远程音乐库】

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” 文章目录 前言1. 安装Docker2. 创建并启动Splayer容器3. 本地访问测试4. 公网远程访问本地Splayer4.1 内网穿…

easyui combobox 只能选择第一个问题解决

easyui combobox 只能选择第一个问题解决 问题现象 在拆分开票的时候,弹出框上面有一个下拉框用于选择需要新增的明细行,但是每次只能选择到第一个 选择第二条数据的时候默认选择到第一个了 代码如下 /*新增发票编辑窗口*/function addTicketDialog…

从零开始:Linux 环境下的 C/C++ 编译教程

个人主页:chian-ocean 文章专栏 前言: GCC(GNU Compiler Collection)是一个功能强大的编译器集合,支持多种语言,包括 C 和 C。其中 gcc 用于 C 语言编译,g 专用于 C 编译。 Linux GCC or G的安…

transformer.js(三):底层架构及性能优化指南

Transformer.js 是一个轻量级、功能强大的 JavaScript 库,专注于在浏览器中运行 Transformer 模型,为前端开发者提供了高效实现自然语言处理(NLP)任务的能力。本文将详细解析 Transformer.js 的底层架构,并提供实用的性…

STM32 Keil5 attribute 关键字的用法

这篇文章记录一下STM32中attribute的用法。之前做项目的时候产品需要支持远程升级,要求版本只能向上迭代,不支持回退。当时想到的方案是把版本号放到bin文件的头部,设备端收到bin文件的首包部数据后判断是否满足升级要求,这里就可…

aws服务--机密数据存储KMS(1)介绍和使用

在AWS(Amazon Web Services)中存储机密数据时,安全性和合规性是最重要的考虑因素。AWS 提供了多个服务和工具,帮助用户确保数据的安全性、机密性以及合规性。AWS Secrets Manager、KMS(Key Management Service)是推荐的存储机密数据的AWS服务和最佳实践。这里先看KMS。 …

51c~C语言~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/12652943 一、嵌入式开发中的C语言编译器 如果你和一个优秀的程序员共事,你会发现他对他使用的工具非常熟悉,就像一个画家了解他的画具一样。----比尔.盖茨1 不能简单的认为是个工具 嵌入式程序开发…

ensp静态路由实验

一、实验目的 1、熟练掌握交换机的基本配置命令 2、熟练掌握静态路由的使用方法 3. 熟练掌握交换机端口模式 二、实验内容 需求: 根据要求利用现有实验设备组建小型局域网 实验设备: 交换机S37002台;PC机2台;路由器2台。 …