当前位置: 首页 > news >正文

Netty 学习笔记——概念篇

Netty Home
Netty GitHub

Netty简介

Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。
“快速”和“简单”并不用产生维护性或性能上的问题。Netty 是一个吸收了多种协议(包括FTP、SMTP、HTTP等各种二进制文本协议)的实现经验,并经过相当精心设计的项目。最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。

本质

网络应用程序框架

实现

异步、事件驱动

特性

高性能、可维护、快速开发

用途

开发服务器和客户端

优势

  1. 支持常用的应用层协议
  2. 解决传输中粘包、半包问题
  3. 支持流量整性
  4. 完善的断连、Idle 等异常处理等

三种 I/O 模式

  • 阻塞与非阻塞
    阻塞:没有数据传过来时,读会阻塞直到有数据;缓冲区满时,写操作也会阻塞。非阻塞遇到这种情况,会直接返回。连接数高的情况下,阻塞 -> 耗资源、效率低。
  • 异步与同步
    数据就绪后自己去读就是同步,数据就绪直接读好再回调给程序是异步。

Netty 对三种 I/O 模式的支持
对于 Nio 与 Bio 来说,特定场景下如连接数少,并发度低,BIO 性能不输 NIO。

通用的 NIO 实现(Common)在 Linux 下也是使用 epoll,Netty 重新单独实现,暴露了更多的可控参数,例如:JDK 的 NIO 默认实现是水平触发,Netty 是边缘触发(默认)和水平触发可切换;Netty 实现的垃圾回收更少、性能更好;
Netty 有多种 NIO 实现
对于 ServerSocketChannel:工厂模式 + 泛型 + 反射实现

三种 Reactor

Reactor 及三种版本

Reactor 及三种版本

Reactor 是一种开发模式,模式的核心流程:
注册感兴趣的事件 -> 扫描是否有感兴趣的事件发生 -> 事件发生后做出相应的处理。
Reactor 及三种版本

Thread-Per-Connection 模式

Thread-Per-Connection 模式

Reactor 模式 V1:单线程

Reactor 模式 V1:单线程

Reactor 模式 V2:多线程Reactor 模式 V2:多线程

Reactor 模式 V3:主从多线程

Reactor 模式 V3:主从多线程

在 Netty 中使用 Reactor 模式

如何在 Netty 中使用 Reactor 模式

TCP 粘包/半包

什么是粘包和半包

  • 粘包的主要原因:
    发送方每次写入数据 < 套接字缓冲区大小
    接收方读取套接字缓冲区数据不够及时
  • 半包的主要原因:
    发送方写入数据 > 套接字缓冲区大小
    发送的数据大于协议的 MTU(Maximum Transmission Unit,最大传输单元),必须拆包
  • 根本原因
    TCP 是流式协议,消息无边界
    说明:UDP 像邮寄的包裹,虽然一次运输多个,但每个包裹都有“界限”,一个一个签收,
    所以无粘包、半包问题

解决粘包和半包问题的几种常用方法

找出消息的边界

Netty 对三种常用封帧方式的支持

Netty 对三种常用封帧方式的支持

常用的“二次”编解码方式

假设我们把解决半包粘包问题的常用三种解码器叫一次解码器,那么我们在项目中,除了可选的的压缩解压缩之外,还需要一层解码,因为一次解码的结果是字节,需要和项目中所使用的对象做转化,方便使用,这层解码器可以称为“二次解码器”,相应的,对应的编码器是为了将 Java 对象转化成字节流方便存储或传输。

  • 一次解码器:ByteToMessageDecoder
    io.netty.buffer.ByteBuf (原始数据流)-> io.netty.buffer.ByteBuf (用户数据)
  • 二次解码器:MessageToMessageDecoder
    io.netty.buffer.ByteBuf (用户数据)-> Java Object

常用的“二次”编解码方式

• Java 序列化
• Marshaling
• XML
• JSON
• MessagePack
• Protobuf
• 其他
Netty 对二次编解码的支持

ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
ch.pipeline().addLast(new ProtobufDecoder(PersonOuterClass.Person.getDefaultInstance()));
ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
ch.pipeline().addLast(new ProtobufEncoder());

keepalive 与 Idle 监测

keepalive

需要 keepalive 的场景包含三点,对端异常“崩溃”、对端在,但是处理不过来、对端在,但是不可达。
不做 keepalive 的后果,连接已坏,但是还浪费资源维持,下次直接用会直接报错。

TCP keepalive 核心参数:

net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
当启用(默认关闭)keepalive 时,TCP 在连接没有数据通过的7200秒后发送 keepalive 消息,当探测没有确认时,按75秒的重试频率重发,一直发 9 个探测包都没有确认,就认定连接失效。
所以总耗时一般为:2 小时 11 分钟 (7200 秒 + 75 秒* 9 次)

应用层 keepalive

  • 协议分层,各层关注点不同
    传输层关注是否“通”,应用层关注是否可服务? 服务器连接在,但是不定可以服务(例如服务不过来等)
  • TCP 层的 keepalive 默认关闭,且经过路由等中转设备 keepalive 包可能会被丢弃
  • TCP 层的 keepalive 时间太长
    默认 > 2 小时,虽然可改,但属于系统参数,改动影响所有应用

HTTP 属于应用层协议,但是常常听到名词“ HTTP Keep-Alive ”指的是对长连接和短连接的选择
Connection : Keep-Alive 长连接(HTTP/1.1 默认长连接,不需要带这个 header)
Connection : Close 短连接

Idle 监测

Idle 监测,只是负责诊断,诊断后,做出不同的行为,决定 Idle 监测的最终用途:
• 发送 keepalive :一般用来配合 keepalive ,减少 keepalive 消息。
Keepalive 设计演进:V1 定时 keepalive 消息 -> V2 空闲监测 + 判定为 Idle 时才发keepalive。
• V1:keepalive 消息与服务器正常消息交换完全不关联,定时就发送;
• V2:有其他数据传输的时候,不发送 keepalive ,无数据传输超过一定时间,判定为 Idle,再发 keepalive 。

直接关闭连接:
• 快速释放损坏的、恶意的、很久不用的连接,让系统时刻保持最好的状态。
• 简单粗暴,客户端可能需要重连。
实际应用中:结合起来使用。按需 keepalive ,保证不会空闲,如果空闲,关闭连接。

在Netty 中开启 TCP keepalive 和 Idle 检测

开启keepalive

Server 端开启 TCP keepalive

bootstrap.childOption(ChannelOption.SO_KEEPALIVE,true) 
bootstrap.childOption(NioChannelOption.of(StandardSocketOptions.SO_KEEPALIVE), true)

提示:.option(ChannelOption.SO_KEEPALIVE,true) 存在但是无效

开启不同的 Idle Check

ch.pipeline().addLast(“idleCheckHandler", new IdleStateHandler(0, 20, 0, TimeUnit.SECONDS));

“锁”事

锁的对象和范围 -> 减少粒度

Synchronized method -> Synchronized block

锁的对象本身大小 -> 减少空间占用

AtomicLong -> Volatile long + AtomicLongFieldUpdater

锁的速度 -> 提高速度

高并发时:java.util.concurrent.atomic.AtomicLong -> java.util.concurrent.atomic.LongAdder

不同场景选择不同的并发类 -> 因需而变

Object.wait/notify -> CountDownLatch

衡量好锁的价值 -> 能不用则不用

对竞争的态度:乐观锁(java.util.concurrent 包中的原子类)与悲观锁(Synchronized)
等待锁的人是否公平而言:公平锁 new ReentrantLock (true)与非公平锁 new ReentrantLock ()
是否可以共享:共享锁与独享锁:ReadWriteLock ,其读锁是共享锁,其写锁是独享锁

内存使用

减少对像本身大小

用基本类型就不要用包装类
应该定义成类变量的不要定义为实例变量

对分配内存进行预估

对于已经可以预知固定 size 的 HashMap避免扩容
根据接受到的数据动态调整(guess)下个要分配的 Buffer 的大小

Zero-Copy

使用逻辑组合,代替实际复制
使用包装,代替实际复制
调用 JDK 的 Zero-Copy 接口

堆外内存

内存池

轻量级对象池实现 io.netty.util.Recycler

相关文章:

Netty 学习笔记——概念篇

Netty Home Netty GitHub Netty简介 Netty是由JBOSS提供的一个java开源框架&#xff0c;现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具&#xff0c;用以快速开发高性能、高可靠性的网络服务器和客户端程序。 也就是说&#xff0c;Netty 是一个…...

元宇宙开始告别以资本为主导的野蛮生长,新的竞争格局和态势将形成

欲要成为这样一场洗牌的胜利者&#xff0c;元宇宙的玩家需要真正站在商业的角度&#xff0c;而非资本市场的角度来看待元宇宙&#xff0c;来寻找元宇宙的正确的发展模式和方法。原因在于&#xff0c;在这样一场洗牌过程当中&#xff0c;仅仅只是对于以往以资本为主导的发展模式…...

MySQL 5:MySQL视图

View&#xff08;视图&#xff09;是一个不存在的虚拟表。 其实质是根据SQL语句获取动态数据集并命名。 用户只需要使用视图名就可以获取结果集&#xff0c;并作为表来使用。数据库中只存储了视图的定义&#xff0c;不存储视图中的数据。 这些数据存储在原始表中。当使用视图查…...

中国干细胞医疗行业市场规模及未来发展趋势

中国干细胞医疗行业市场规模及未来发展趋势近年来&#xff0c;中国干细胞医疗行业发展迅速&#xff0c;市场规模不断扩大&#xff0c;发挥着越来越重要的作用。根据最新统计数据显示&#xff0c;2018年&#xff0c;中国干细胞医疗行业市场规模达到1242.6亿元&#xff0c;比上一…...

SpringBoot日志文件

日志有什么用&#xff1f; 1)快速的排查和定位问题&#xff0c;直接看报错信息&#xff1b; 2)进行记录用户登录的信息记录业务功能日志方便分析用户是正常登录还是暴力破解用户&#xff1b; 假设我们在这个登录程序中没有写反暴力破解的机制&#xff0c;比如说用户输入密码六次…...

R语言读取Excel表格数据并绘制多系列柱状图、条形图

本文介绍基于R语言中的readxl包与ggplot2包&#xff0c;读取Excel表格文件数据&#xff0c;并绘制具有多个系列的柱状图、条形图的方法。 首先&#xff0c;我们配置一下所需用到的R语言readxl包与ggplot2包&#xff1b;其中&#xff0c;readxl包是用来读取Excel表格文件数据的&…...

【操作系统】操作系统IO技术底层机制和ZeroCopy

1.DMA技术详解 &#xff08;1&#xff09;应用程序 从 磁盘读写数据 的时序图&#xff08;未用DMA技术前&#xff09; &#xff08;2&#xff09;什么是DMA 技术 (Direct Memory Access&#xff09; 直接内存访问&#xff0c;直接内存访问是计算机科学中的一种内存访问技术。…...

给你的边框加点渐变

目录前言border-imageborder-image实现background父子divbackgorund一个div一个伪元素background-clip&#x1f9e8;&#x1f9e8;&#x1f9e8; 大家好&#xff0c;我是搞前端的半夏 &#x1f9d1;&#xff0c;一个热爱写文的前端工程师 &#x1f4bb;. 如果喜欢我的文章&…...

【目标检测】如何使用Yolov8

如何使用Yolov8一、前言二、用法2.1 安装2.2 使用方法2.3 模型2.3.1 目标检测2.3.2 实例分割2.3.3 分类一、前言 一种易于使用的新的对象检测模型。 由 Ultralytics 开发的 Ultralytics YOLOv8 是一种尖端的、最先进的 (SOTA) 模型&#xff1a; https://github.com/ultralyt…...

NVM安装、配置环境、简单使用

nvm 是Node.js 的版本管理工具&#xff0c;可以在同一台电脑上安装多个Node.js版本灵活切换。 安装# sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash 其中0.39.0可以替换为当前最新的版本号。 配置环境变量# cd ~touch .bash_profile…...

【SPSS】数据预处理基础教程(附案例实战)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…...

某饿了么APP最新版逆向分析(二):加密参数初探

二、分析加密参数 说做就做&#xff0c;这边用的python进行模拟请求 万事俱备只欠东风&#xff0c;点击run 发现报错了 怎么回事&#xff1f; 明明请求的内容和抓包的内容完全一致 怎么没有返回我们想要的数据 报错内容为参数错误 因此我就想可能是请求体有参数加密 我…...

程序的编译与链接(预处理详解)+百度面试笔试题+《高质量C/C++编程指南》笔试题

本篇重点介绍程序的编译与链接过程中的预处理阶段&#xff0c;将详细的介绍在预处理阶段会发生什么&#xff0c;以及讲解有关百度该内容的面试笔试题和源于《高质量C/C编程指南》的笔试题。一.【预处理详解】①预定义符号②#define2.1 #define 定义标识符注意&#xff1a;2.2 #…...

全解析 ESM 模块语法,出去还是进来都由你说了算

模块语法是ES6的一个重要特性&#xff0c;它的出现让JavaScript的模块化编程成为了可能。 在JavaScript中可以直接使用import和export关键字来导入和导出模块&#xff0c;但是这种语法并不是ES6的标准&#xff0c;而是ESM&#xff08;ECMAScript Module&#xff09;模块语法的…...

MATLAB 粒子群算法

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…...

java微信小程序音乐播放器分享系统

随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,音乐播放器小程序被用户普遍使用,为方便用户能够可以随时进行音乐播放器小程序的数据信息管理,特开发了基于音乐播放器小程序…...

VS各版本VC各版本对应关系

Visual Studio 经过多年的发展&#xff0c;有许多版本&#xff0c;经常我们在拿到一份代码时不知道对应的VS版本 这时候可以打开工程目录下的vcproj/vcxproj文件&#xff0c;如下所示 <?xml version"1.0" encoding"utf-8"?> <Project DefaultT…...

如何处理“WLAN没有有效的IP配置”这一问题?

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;暂无 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我最大的…...

ElasticSearch-学习笔记05【SpringDataElasticSearch】

Java后端-学习路线-笔记汇总表【黑马程序员】ElasticSearch-学习笔记01【ElasticSearch基本介绍】【day01】ElasticSearch-学习笔记02【ElasticSearch索引库维护】ElasticSearch-学习笔记03【ElasticSearch集群】ElasticSearch-学习笔记04【Java客户端操作索引库】【day02】Ela…...

【GlobalMapper精品教程】045:空间操作(2)——相交(Intersect)

GlobalMapper提供的空间分析(操作)的方法有:交集、并集、单并集、差异、对称差集、相交、重叠、接触、包含、等于、内部、分离等,本文主要讲述相交工具的使用。 文章目录 一、实验数据二、符号化设置三、相交运算四、结果展示五、心灵感悟一、实验数据 加载配套实验数据(…...

Android 一体机研发之修改系统设置————自动锁屏

Android 一体机研发之修改系统设置————屏幕亮度 Android 一体机研发之修改系统设置————声音 Android 一体机研发之修改系统设置————自动锁屏 修改系统设置系列篇章马上开张了&#xff01; 本章将为大家细节讲解自动锁屏。 自动锁屏功能&#xff0c;这个可以根据…...

七天实现一个go rpc框架

目录rpc协议目的关于RPC和框架服务端与消息编码确保接口的实现消息的序列化与反序列化通信过程服务端的实现main 函数支持并发与异步的客户端Call 的设计实现客户端服务注册(service register)通过反射实现 service集成到服务端超时处理创建连接超时Client.Call 超时服务端处理…...

EMQX Cloud Serverless 正式上线:三秒部署、按量计费的 MQTT Serverless 云服务

近日&#xff0c;全球领先的开源物联网数据基础设施软件供应商 EMQ 正式发布了 MQTT Serverless 云服务 —— EMQX Cloud Serverless 的 Beta 版本&#xff0c;开创性地采用弹性多租户技术&#xff0c;用户无需关心服务器基础设施和服务规格伸缩所需资源&#xff0c;仅用三秒即…...

快速排序 容易理解的版本

package huaweiod.排序算法;import java.util.Arrays;public class 快速排序 {public static void main(String[] args) {int[] arr {9,8,3,5,6,7,8,9};mysort(arr, 0, arr.length - 1); // myprint(arr," ");}private static void myprint(int[] arr, Strin…...

Linux体系结构

Linux体系结构一、引入概念二、内核三、管理1、内存管理2、进程管理3、进程调度控制进程对CPU的访问4、设备驱动程序和网络接口四、Linux Shell五、磁盘分区硬盘内的分区Linux下磁盘分区和目录的关系一、引入 操作系统的本质是什么&#xff1f; 是一种管理(协调)资源机制&…...

【汽车电子】什么是ADAS?

文章目录ADAS——先进驾驶辅助系统ADAS——商用车安全性能提升的利器总结ADAS——先进驾驶辅助系统 ADAS&#xff0c;全称Advanced Driver Assistance Systems &#xff0c;“先进驾驶辅助系统”&#xff0c;adas是汽车上面的一种系统&#xff0c;中文名叫做高级驾驶辅助系统&…...

java: 错误: 不支持发行版本 5(快速解决办法)

目录 前言 一、出现报错 二、报错的原因 三、解决办法 四、解决成功 前言 在maven web项目上面要部署运行tomcat时候&#xff0c;会出现这个问题 一、出现报错 java: 错误: 不支持发行版本 5 二、报错的原因 &#xff08;1&#xff09;官方解释&#xff1a;这个错误…...

QT中pro文件常用qmake语法

变量 配置QT模块 QT core gui sql network QT - sql注释 # 开启注释 # DEFINES QT_DISABLE_DEPRECATED_BEFORE0x060000 # disables all the APIs deprecated before Qt 6.0.0添加源文件 SOURCES \main.cpp \widget.cppSOURCES *.cpp SOURCES 1.cpp 2.cpp 3.cpp添加…...

Android 一体机研发之修改系统设置————声音

Android 一体机研发之修改系统设置————屏幕亮度 Android 一体机研发之修改系统设置————声音 Android 一体机研发之修改系统设置————自动锁屏 修改系统设置系列篇章马上开张了&#xff01; 本章将为大家细节讲解声音。 对于声音功能大家都不陌生&#xff0c;在多…...

挖掘长尾关键词的五大思路

本文重点介绍做SEO挖掘长尾词的五大思路&#xff1a;长尾词是搜索量不大&#xff0c;但是关键词的量非常庞大的词&#xff0c;那我们可以通过以下方法挖掘&#xff1a;1、目标型长尾搜索的关键词是直接包含了商业需求的&#xff0c;直接能跟我们的服务或产品对接的&#xff0c;…...

成都今日各区疫情情况/ seo won

BossAnim 项目地址&#xff1a;Alex-Cin/BossAnim简介&#xff1a;仿 boss 直聘&#xff0c;查看用户头像博客地址 http://www.jianshu.com/p/eadd1a764720BossAnim 博客地址 http://www.jianshu.com/p/eadd1a764720...

商丘做网站优化/分销渠道

https://blog.csdn.net/sidely/article/details/43059795 xrandr --output VGA --auto --output LVDS --off 打开外接显示器&#xff0c;同时关闭笔记本液晶屏幕&#xff08;只用外接显示器工作&#xff09; xrandr --output VGA --off --output LVDS --auto 关闭外接显示器…...

威海网站开发制作/上海网站建设方案

快速排序是一种分治的排序算法&#xff0c;其主要思想是通过选择一个基准数&#xff0c;将数组划分成两个子序列&#xff0c;左边的数都比基准数小&#xff0c;右边的数都比基准数大&#xff0c;然后对这两个子序列分别进行快速排序&#xff0c;以此达到最终排序的目的。 在Jav…...

日照的网站建设/推广平台网站有哪些

数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下&#xff0c;精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关&#xff0c;数据结构有以下几种基本的结构算法…...

网站设计公司飞沐/各国足球世界排名

之前在看spring注解的时候&#xff0c;有看到再配置文件里面定义component scan package就能自动扫描对应包下面的class&#xff0c;然后根据注解生成相应的bean。自己对这个功能很好奇&#xff0c;就搜了下&#xff0c;找到了实现的关键代码&#xff0c;记录下。后续再对这段代…...

做康复医院网站/集团网站推广

大概的思路&#xff1a;1、读取xml文件2、当一个下拉框选中某选项时&#xff0c;根据该选项&#xff0c;当前节点指向下一层&#xff0c;进入下一层下拉框的设置3、取消当前下拉框的禁用&#xff0c;禁用下一层的下拉框4、清空当前下拉框的选项5、根据当前节点读取xml的数据&am…...