Netty 学习之路

Netty入门学习 打个比喻,每个 Channel 是一个产品的加工车间,Pipeline 是车间中的流水线,ChannelHandler 就是流水线上的各道工序,而后面要讲的 ByteBuf 是原材料,经过很多工序的加工:先经过一道道入站工序,再经过一道道出站工序最终变成产品。如果事件轮询的持续时间大于等于 timeoutMillis,那么说明是正常的,否则表明阻塞时间并未达到预期,可能触发了空轮询的 Bug,则计数器+1,如果计数器超过阙值,则重建Selector并迁移所有其管理的channel。如果还是没有则创建对象。 阅读详情

前言

好几年没写博客了,全是自己本地做笔记。最近项目中遇到在线即时通讯、事件通知等一系列需求,遂开始学习十几年前但现在依然很火的经典开源框架 – Netty,并记录下来分享分享。

I/O 模型

学习 Netty 之前,必须要理解就是这个 I/O 模型了;废话不多说,开整

BIO(Blocking IO)

以流的方式处理数据,基于字节流和字符流
Java BIO 是传统的的 Java IO 编程,类和接口在 java.io 中

  • 服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器就需要启动一个线程进行处理,但如果这个连接不做任何事,会造成不必要的线程开销(可以使用线程池机制改善,实现多客户连接,但不能减少线程的个数)
  • 适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4 以前的唯一选择
  • 连接过后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费
    编程流程
  1. 服务端启动一个 ServerSocket
  2. 客户端启动 Socket 连接对服务器通信,默认情况下服务器端对每个客户建立一个线程与之通讯
  3. 客户端发出请求后,先咨询服务器是否有线程响应,如果没有则会等待或者被拒绝
  4. 如果有响应,客户端线程会等待请求结束后,才继续执行

NIO (Non Blocking IO)

以块的方式处理数据,基于 Channel 和 Buffer
JDK1.4 之后输入/输出的新特性,是同步非阻塞的,类在 java.nio 下

  • NIO 是面向缓冲区、或者面向块编程,可以做到用一个线程处理多个操作(一个线程监听多个客户端通道)。而不需要类似100个请求就开辟100个线程
  • 一个线程从某个通道请求或者读取数据,但它仅能得到目前可用的数据;如果没有数据可用,就什么都不会做,而不是保持线程阻塞
  • HTTP2.0 使用了多路复用,做到同一个连接并发处理多个请求,是 HTTP1.0 的好几个数量级
  • NIO 包括三大核心组件
名称描述
Selector选择器一个 Selector(类比注册中心) 对应一个线程,管理着多个 Channel;Selector 切换到哪个 Channel 是由事件决定的,Selector 会根据不同的事件在 Channel 上切换
Channel通道一个 Channel 都对应一个 Buffer;Channel 是双向的,可以反应底层操作系统的情况(例如 Linux 底层的操作系统是双向的)
Buffer缓冲区Buffer 是一个内存块,底层是一个数组;数据的读写都是通过 Buffer,和 BIO(输入流/输出流) 本质上不同(BIO 不是双向)

NIO组件关系

Selector 选择器

能够检测多个注册的通道上是否有事件发生(多个 channel 以事件的方式可以注册到同一个 Selector)

当客户端连接时

  1. 通过 ServerSocketChannel 得到 Socketchannel
  2. 将 SocketChannel 注册到 Selector 上,使用 register(Selector sel, int ops) 方法;一个 Selector 上可以注册多个 SocketChannel
  3. 每一次注册后返回 selectionKey, 被 Selector 作成集合的形式管理起来
  4. Selector 此时可以进行监听, 使用方法 Select 方法,并返回有事件发生的通道个数,进而得到各个 SelectionKey
事件名称事件行为
OP_CONNECT客户端连接事件
OP_ACCEPT接受客户端注册事件
OP_READ客户端读事件
OP_WRITE客户端写事件
  1. 再通过 SelectionKey 可以反向获取 SocketChannel,通过得到的 channel 完成业务读写处理

Channel 连接通道

NIO 中的接口
通道可以同时进行读写数据、实现异步读写数据、从缓冲区读写数据

常用类名作用
FileChannel用于文件数据读写
DatagramChannel用于 UDP 数据读写
ServerSocketChannel用于 TCP 数据读写
SocketChannel用于 TCP 数据读写

Buffer 容器对象

名称类型描述
markint标记
positionint位置,下一个要被读写的元素的索引,每次读写缓冲区数据时都会改变值,为下一次读写做准备
limitint表示缓冲区的当前终点,不能对缓冲区超过极限的位置进行读写操作,且极限是可以修改的
capacityint容量,即可以容纳的最大数据量,在缓冲区创建时被设定并且不能改变
hb[]数据承载结构

注意事项


  1. put 时的类型,get 时需要按照对应的类型获取
  2. MappedByteBuffer 让文件直接在内存中修改(堆外内存)
  3. Scattering,将数据写入到 Buffer 时,可以采用 Buffer 数组,依次写入(分散)
  4. Gathering,从 Buffer 读取数据时,可以采用 Buffer 数组,依次读(聚合)

零拷贝

注意:不是不拷贝,而是没有 CPU 的拷贝
在 Java 中常用的两种拷贝方式:mmap(内存映射)、sendFile

  • 传统 I/O 的文件拷贝方式(4次拷贝3次切换)

  1. 首先从硬件 (Hard Drive)DMA Copy(direct memory access 直接内存拷贝),即不使用 CPU
  2. 拷贝至内核(kernal buffer)
  3. 再将内核中的数据使用 CPU Copy 至 user buffer,此时数据可以修改
  4. 再使用 CPU Copy 至 Socket buffer
  5. 最后使用 DMA Copy 至 protocol engine(协议引擎/栈)

传统IO文件拷贝方式

  • mmap 优化(3次拷贝3次切换)

适合数据、文件较小
通过内存映射,将文件映射到内核缓冲区,同时,用户空间可以共享内核空间的数据;这样在网络传输时,就可以减少内核空间到用户空间的拷贝次数

  1. 首先从硬件 (Hard Drive)DMA Copy(direct memory access 直接内存拷贝),即不使用 CPU
  2. 由于共享了内核空间,因此此时可以在 kernal buffer 中进行数据修改
  3. 再通过 CPU Copy 至 Socket Buffer
  4. 最后使用 DMA Copy 至 protocol engine(协议引擎/栈)
  • sendFile(3次拷贝2次切换)

Linux 2.1 版本提供的 sendFile 函数,适合大文件
数据根本不经过用户态,直接从内核缓冲区进去 Socket Buffer,同时,由于和用户态完全无关,就减少了一次上下文切换
其优势在于

  • 更少的数据 复制
  • 更少的上下文切换
  • 更少的 CPU 缓存伪共享
  • 无 CPU 校验和计算
  1. 首先从硬件 (Hard Drive)DMA Copy(direct memory access 直接内存拷贝),即不使用 CPU
  2. 此时,减少了user context 的切换
  3. 直接从 kernal buffer 通过 CPU Copy 至 Socket Buffer
  4. 再使用 DMA Copy 至 protocol engine(协议引擎/栈)
  5. 但是,在 Linux 2.4 时做了修改,实现了零拷贝;减少了从 kernal buffer 经过 CPU 至 Socket Buffer 的过程,直接从 kernal buffer 通过 DMA Copy 至 protocol engine,从而减少了一次数据拷贝(kernal buffer 的 length、offset 还是会 copy 至 socket buffer,但是信息量很少,消耗很低,可以忽略)

AIO(Asynchronous I/O)

JDK7 引入了 Asynchronous I/O。涉及到两种模式 Reactor 和 Proactor;而 Java 的 NIO 就是 Reactor
AIO 也被称呼为 NIO2.0,异步非阻塞 IO。引入异步通道的概念,采用了 Proactor 模式,简化了程序编写,有效的请求才启动线程,特点是先由操作系统完成后才通知服务端开启线程去处理,适用于连接数较多、连接时间较长的应用场景

NXP应用随记(八):S32K3XX的HSE学习记录(HSE\MU\UTEST\IVT\A,B SWAP) HSE,即硬件安全引擎(Hardware Security Engine),是NXP S32K312微控制器(MCU)中的一个功能,它提供了一系列的安全特性,包括加密、安全启动和密钥存储等。这些功能旨在增强汽车电子系统的信息安全,符合ISO26262标准,达到ASIL D安全等级。具体来说,S32K312的HSE支持AES-128/192/256加密、RSA、ECC等加密算法,以及侧通道保护,确保了数据传输和存储的安全性。 阅读详情

相关推荐

(Linux)DHCP 超级作用域和中继代理(超难受做了超久)

DHCP服务器在192.168.159.0 可以实现分配IP的功能,现在要跨网段分配IP 就需要用到DHCP中继代理。中继代理有两张网卡分别eth0:IP 192.168.159.2 ;eth1: IP:192.168.200.2 。现在要实现192.168.200.0网段的客户机可以获取DHCP服务器的IP。中继代理其实是相当于一个路由器的作用 DHCP服务器的IP地址 :192.168.159...

DJ_joker的博客 2223

netty 文件传输两种方案代码

netty 文件传输实例

深圳市多克创新科技有限公司 852

Eureka自我保护机制

Eureka自我保护机制 默认情况下,当eureka server在一定时间内没有收到实例的心跳,便会把该实例从注册表中删除(默认是90秒),但是,如果短时间内丢失大量的实例心跳,便会触发eureka server的自我保护机制,比如在开发测试时,需要频繁地重启微服务实例,但是我们很少会把eureka server一起重启(因为在开发过程中不会修改eureka注册中心),当一分钟内收到的心跳数大量减少时,会触发该保护机制。可以在eureka管理界面看到Renews threshold和Renews(last

Soul_Ming的博客 542

【操作系统】零拷贝

零拷贝技术

a20040518的博客 469

Python爬取腾讯视频m3u8加密流实战(附完整代码)

本文提供了一份详细的Python实战教程,指导如何通过抓包分析、模拟请求头与载荷,破解腾讯视频的m3u8加密流防盗链机制,并附上完整代码实现视频片段的下载与合并。教程涵盖从侦察到代码实现的完整流程,并包含参数动态化、多线程下载等高级技巧与避坑指南,旨在帮助开发者掌握流媒体下载的核心技术。

weixin_29090089的博客 1587

2.4G射频微带线阻抗匹配设计实战(WiFi/BLE)

本文深入探讨了2.4G射频微带线阻抗匹配在WiFi/BLE产品开发中的关键作用。文章详细解析了共面波导微带线结构,提供了基于SI9000工具的阻抗计算实战指南,并总结了不同PCB板厚下的设计参数对照表。同时,文章分享了PCB布局布线、与板厂沟通以及天线匹配调试等核心避坑经验,旨在帮助硬件工程师构建从射频芯片到天线的稳定高效传输通道。

j0k1l2m3n的博客 367

零拷贝技术详细解读(Zero Copy)

文章目录为什么要有DMA技术?了解一下传统的文件传输如何实现零拷贝PageCache有什么用? 为什么要有DMA技术? 在没有 DMA 技术前,I/O 的过程是这样的: CPU 发出对应的指令给磁盘控制器,然后返回; 磁盘控制器收到指令后,于是就开始准备数据,会把数据放入到磁盘控制器的内部缓冲区中,然后产生一个中断; CPU 收到中断信号后,停下手头的工作,接着把磁盘控制器的缓冲区的数据一次一个字节地读进自己的寄存器,然后再把寄存器里的数据写入到内存,而在数据传输的期间 CPU 是无法执行其他任务的。

码农界扛把子的博客 6610

避坑指南:雅特力AT32F403A在Keil5中的V2库配置常见问题解析

本文详细解析了国产MCU雅特力AT32F403A在Keil5中配置V2库的常见问题,包括工程创建、库文件配置、编译错误和外设设置等关键环节。针对项目文件夹结构混乱、芯片型号选择错误、头文件路径设置不当等典型问题提供实用解决方案,帮助开发者高效避坑,提升开发效率。

weixin_30335575的博客 375

零拷贝与sendFile

零拷贝是指计算机执行IO操作时,CPU不需要将数据从一个存储区域复制到另一个存储区域,进而减少上下文切换以及CPU的拷贝时间。它是一种IO操作优化技术。Kafka的特性之一就是高吞吐率,原因之一就是因为底层使用ZeroCopy技术,直接将磁盘无需拷贝到用户空间,而是直接将数据通过内核空间传递输出,数据并没有抵达用户空间。

码农郭大大的博客 1467

【python】geopandas库安装出现各种问题?可以看看这篇文章

geopandas的安装方法

jgsecurity的博客 3886

【自监督学习完整教程】第 1 章:初识自监督学习

摘要: 自监督学习(SSL)是一种利用无标签数据自动生成伪标签进行模型训练的方法,有效降低了人工标注成本。本文对比了监督学习、无监督学习和SSL的差异,重点阐述了SSL通过设计PretextTasks(如图像旋转预测)从数据中提取深层特征的原理。实践部分以PyTorch实现图像旋转预测任务为例,展示了SSL的训练流程。实验表明,SSL能够学习通用视觉特征,适用于计算机视觉、自然语言处理等领域,尤其在标注数据稀缺的场景中表现优异。

u012133341的博客 259

关于零拷贝

https://blog.youkuaiyun.com/lw_1299946338/article/details/106930726 什么是DMA 在了解零拷贝之前,我们先要了解一个概念叫做DMA,详情百度-DMA Direct Memory Access,直接存储器访问 CPU将地址总线、数据总线、有关控制的总线的数据权交给DMA引擎 它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料复制到暂存器,然后把它们再次写回到新的地方。在这个时间中,

yygr的博客 479

【AUTOSAR-COM】-2.3_通过PduGroup批量控制CAN Frame/Pdu的接收

-->如果实现类似UDS诊断 $28服务,控制所有APP CAN Rx Frame/Pdu/报文接收; -->自定义过滤CAN信号的接收。

「汽车电子助手」的博客 1989

netty学习

[netty学习1](https://blog.youkuaiyun.com/gupaoxueyuan/article/details/88359769]

RuiDer的博客 437

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Netty学习项目教程

Netty学习项目教程 项目介绍 Netty学习项目(netty-learning)是一个旨在帮助开发者深入理解和掌握Netty框架的开源项目。Netty是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。该项目通过一系列的教程和案例,帮助开发者从基础到高级逐步掌握Netty的使用和原理。 项目快速启动 环境准备 Java开发环境(JDK 8或更高版本) 集成开发环境...

gitblog_00481的博客 689

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Netty 入门学习

netty入门学习笔记; EventLoop,Channel,ByteBuf;

weixin_53142722的博客 4697

Netty学习手册指南

Netty学习手册指南 项目介绍 Netty学习手册 是一个专门针对尚硅谷韩顺平老师的Netty课程编写的辅助学习资源。此项目旨在为已具备一定Java编程基础,熟悉设计模式、数据结构、多线程以及网络编程的开发者提供深入学习Netty的核心技术及源码的教程。它不仅包含了课程的整理资料,还有部分代码示例和文档美化,适合已经有一定项目经验和源码阅读能力的学习者。 项目快速启动 为了快速启动并体验Nett...

gitblog_00258的博客 528

Netty学习路线

Netty学习路线 很早就说要写关于Netty的博客了,如今他来了他来了!!! 第一章 Netty入门 1.1 Netty的概述 1.1.1 Netty简介 官网中的解释: Netty是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。(王婆卖瓜自卖自夸) 1.1.2 谁在使用Netty? Dubbo、zk、RocketMQ、ElasticSearch、Spring5(对HTTP协议的实现)、GRPC、Spark等大型开源项目都在使用Netty作为底层通讯框架 1.1.3 Ne

weixin_47479914的博客 875

Netty学习资料

一起学Netty

guozhaohui628 380

Netty 学习资料

6、Netty, the IO framework that propels them all By Stephane LANDELLE 视频教程。掌握 Java 的面向对象编程、多线程编程、IO 编程、网络编程等知识。《Netty 核心源码剖析章节》内容学习最好有项目开发和阅读源码的经历。本课程不适合零基础的学员,需要掌握常用的设计模式和数据结构。《尚硅谷 Netty 核心技术及源码剖析》课程学习手册。2、Netty实践学习案例。1、Netty学习手册。3、Netty源码解析。4、Netty源代码。

ccf19881030的专栏 822

Netty学习心得

Selector是NIO(即非阻塞IO)实现的核心,它会不断轮询注册在其上的Channel,如果某个Channel上面有新的TCP连接接入、读和写操作事件,这个Channel就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey获取就绪的Channel的集合,进行后续的操作。如在Reactor中实现读:注册读就绪事件和相应的事件处理器、事件分发器等待事件、事件到来,激活分发器,分发器调用事件对应的处理器、事件处理器完成实际的读操作,处理读到的数据,注册新的事件,然后返还控制权。

weixin_65085529的博客 715

Netty 学习项目教程

Netty 学习项目教程 1. 项目的目录结构及介绍 netty-learning ├── netty-in-action ├── netty-practice ├── netty-private-protocol ├── netty-rpc ├── .gitignore ├── LICENSE ├── README.md └── pom.xml 目录结构介绍 netty-in-action:...

gitblog_01174的博客 717

Netty学习之路

Netty学习之路 入职高德也有将近2个月了,着实感受到了高德人才的优秀,本想着混日子了,奈何朋友圈时不时冒出来一两个优秀的人刺激一把,还是决定不要放弃了,hh,不然太给hit丢人了,希望一个月之内能把netty学完 ...

D206_hero的博客 464

netty学习推荐书_Netty学习路线总结

序之前开过品味性能系列、Mysql学习系列,颇为曲高和寡。都是讲理论,很少有手把手深入浅出的文章。不过确实我就这脾气,文雅点的说法叫做“伪雅”,下里巴人叫做“装逼”。学习资料本篇文章,打算总结下学习过程,分析学习要点。关于netty的资料颇多,学习起来未免杂乱。对于初学者麻烦点在于难以找到重点,再此则推荐一个学习路线。通信理论学习,akka bio nio aio(可以绕过)第一步 上手练习Tel...

weixin_39856265的博客 1248

Netty框架学习笔记

主要讲述netty框架的学习笔记

weixin_47257473的博客 1058

netty学习网站

netty的学习网站 http://www.tianshouzhi.com/api/tutorials/netty/221

qq_43504447的博客 361
上一篇: Python爬取数据并存入MongoDB
下一篇: Netty 学习之路
Ling2099
博客等级 码龄9年 14粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值