Netty 学习笔记——概念篇

news/2024/5/18 16:37:08 标签: 学习, 网络, udp

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


http://www.niftyadmin.cn/n/61717.html

相关文章

spring(三)-----------什么是beanDefinition?

上篇我们以mybatis如何注入mapper对象为引&#xff0c;发现mybatis使用了FactoryBean&#xff08;动态代理&#xff09;动态注册beanDefinition 的方式实现了对多个bean进行注入。 这篇我们延续上篇的问题&#xff0c;什么是beanDefinition&#xff1f;动态注入beanDefinition…

模型部署综述

https://github.com/leeguandong/KuaiZaihttps://github.com/leeguandong/KuaiZaiAI 框架部署方案之模型部署概述 - 知乎文小P 家的 1011010 概述模型训练重点关注的是如何通过训练策略来得到一个性能更好的模型&#xff0c;其过程似乎包含着各种“玄学”&#xff0c;被戏称为“…

SonicWall:请立即修复SMA 1000 漏洞

近日&#xff0c;网络安全供应商SonicWall发布了关于安全移动访问 (SMA) 1000设备的三个安全漏洞的紧急报告&#xff0c;其中包括一个高威胁性的身份验证绕过漏洞。SonicWall指出&#xff0c;攻击者可以利用这些漏洞绕过授权&#xff0c;并可能破坏易受攻击的设备。 从报告中可…

STM32单片机红外遥控

红外遥控接口电路STM32单片机红外遥控程序源代码#include "sys.h"#define LED_RED PBout(12) //红色发光二极管控制管脚初始化PB12#define LED_GREEN PBout(13) //绿色发光二极管控制管脚初始化PB13#define LED_YELLOW PBout(14) //黄色发光二极管控制管脚初始化PB14…

多种充电模式_手持无线充气泵方案

一、手持无线充气泵手持无线充气泵是一个通过锂电池供电达到无需插电就能使用的便携式充气泵&#xff0c;它的适用场景大部分是为身处户外没有办法接通电源的人而设计的&#xff0c;方便人们的出行也可解燃眉之急。不仅如此&#xff0c;为预防手持无线充气泵的锂电池电量用完而…

test2

物理层故障分析 一、传输介质故障 a.主要用途简述 传输介质主要分为 导向传输介质和非导向传输介质。前者包括双绞线&#xff08;两根铜线并排绞合&#xff0c;距离过远会失真&#xff09;、同轴电缆&#xff08;铜质芯线屏蔽层&#xff0c;抗干扰性强&#xff0c;传输距离更…

Python3的一些小知识:无穷大、无穷小...

文章目录小知识小知识 无穷大&#xff1a;float(inf) 无穷小&#xff1a;float (-inf) 遍历获取下标&#xff1a;enumerate () 例如&#xff1a; test_list [a, b, c] for index, item in enumerate(test_list)print(findex{index}, item{item}输出结果&#xff1a; index…

微信小程序 java springboot招聘求职应聘简历系统

应聘系统是基于微信小程序&#xff0c;java编程语言&#xff0c;mysql数据库&#xff0c;springboot框架&#xff0c;idea工具开发&#xff0c;本系统主要分为用户&#xff0c;企业&#xff0c;管理员三个角色&#xff0c;用户注册登陆小程序&#xff0c;查看应聘分类&#xff…