随笔 @Java领域中相关通信点(三)

Netty是一款高性能的Java网络编程框架,支持异步事件驱动模型,适用于开发服务器和客户端应用程序。本文详细介绍Netty的特点、架构及线程模型,并提供基础程序演示,包括解决拆包粘包问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

夜光序言:

你走过无数个城市看过无数的风景见过无数个人。

却到底放不下心里念的那个人。

 

正文:

二、 Netty


1  简介


Netty 是由 JBOSS 提供的一个 java 开源框架。Netty 提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

 

也就是说,Netty 是一个基于 NIO 的客户、服务器端编程框架,使用 Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty 相当简化和流线化了网络应用的编程开发过程,例如,TCP 和 UDP 的 socket 服务开发。“快速”和“简单”并不用产生维护性或性能上的问题。

 

Netty 是一个吸收了多种协议的实现经验,这些协议包括 FTP,SMTP,HTTP,各种二进制,文本协议,并经过相当精心设计的项
目,最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。

Netty 从 4.x 版本开始,需要使用 JDK1.6 及以上版本提供基础支撑。

在设计上:针对多种传输类型的统一接口 - 阻塞和非阻塞;简单但更强大的线程模型;

真正的无连接的数据报套接字支持;链接逻辑支持复用;

在性能上:比核心 Java API 更好的吞吐量,较低的延时;资源消耗更少,这个得益于共享池和重用;减少内存拷贝

在健壮性上:消除由于慢,快,或重载连接产生的 OutOfMemoryError;消除经常发现

在 NIO 在高速网络中的应用中的不公平的读/写比

在安全上:完整的 SSL / TLS 和 StartTLS 的支持且已得到大量商业应用的真实验证,如:Hadoop 项目的 Avro(RPC 框架)、Dubbo、Dubbox等 RPC 框架。

Netty 的官网是:http://netty.io,有 三 方 提 供 的 中 文 翻 译 Netty 用 户 手 册 ( 官 网 提 供 源 信 息 ):
http://ifeve.com/netty5-user-guide/

2 Netty  架构

 

3  线程模型

 

Netty 中支持单线程模型,多线程模型,主从多线程模型。
3.1  单线程模型


在 ServerBootstrap 调用方法 group 的时候,传递的参数是同一个线程组,且在构造线程组的时候,构造参数为 1,这种开发方式,就是一个单线程模型。个人机开发测试使用。不推荐。


3.2  多线程模型


在 ServerBootstrap 调用方法 group 的时候,传递的参数是两个不同的线程组。负责监听的 acceptor 线程组,线程数为 1,也就是构造参数为 1。负责处理客户端任务的线程组,线程数大于 1,也就是构造参数大于 1。这种开发方式,就是多线程模型。长连接,且客户端数量较少,连接持续时间较长情况下使用。如:企业内部交流应用。


3.3  主从多线程模型


在 ServerBootstrap 调用方法 group 的时候,传递的参数是两个不同的线程组。负责监听的 acceptor 线程组,线程数大于 1,也就是构造参数大于 1。负责处理客户端任务的线程组,线程数大于 1,也就是构造参数大于 1。这种开发方式,就是主从多线程模型。长连接,客户端数量相对较多,连接持续时间比较长的情况下使用。如:对外提供服务的相册服务器。


4  基础程序演示


详见代码
4.1  入门案例
4.2  拆包粘包问题解决


netty 使用 tcp/ip 协议传输数据。而 tcp/ip 协议是类似水流一样的数据传输方式。多次访问的时候有可能出现数据粘包的问题,解决这种问题的方式如下:


4.2.1  定长数据流


客户端和服务器,提前协调好,每个消息长度固定。(如:长度 10)。如果客户端或服务器写出的数据不足 10,则使用空白字符补足(如:使用空格)。

4.2.2  特殊结束符


客户端和服务器,协商定义一个特殊的分隔符号,分隔符号长度自定义。如: ‘#’、 ‘$_$’、‘AA@’。在通讯的时候,只要没有发送分隔符号,则代表一条数据没有结束。


4.2.3  协议


相对最成熟的数据传递方式。有服务器的开发者提供一个固定格式的协议标准。客户端和服务器发送数据和接受数据的时候,都依据协议制定和解析消息。

4.3  序列化对象


JBoss Marshalling 序列化
Java 是面向对象的开发语言。传递的数据如果是 Java 对象,应该是最方便且可靠。


4.4  定时断线重连


客户端断线重连机制。
客户端数量多,且需要传递的数据量级较大。可以周期性的发送数据的时候,使用。要求对数据的即时性不高的时候,才可使用。

优点: 可以使用数据缓存。不是每条数据进行一次数据交互。可以定时回收资源,对资源利用率高。相对来说,即时性可以通过其他方式保证。如: 120 秒自动断线。数据变化 1000 次请求服务器一次。300 秒中自动发送不足 1000 次的变化数据。

 

4.5  心跳监测


使用定时发送消息的方式,实现硬件检测,达到心态检测的目的。心跳监测是用于检测电脑硬件和软件信息的一种技术。如:CPU 使用率,磁盘使用率,内存使用率,进程情况,线程情况等。


4.5.1 sigar


需要下载一个 zip 压缩包。内部包含若干 sigar 需要的操作系统文件。sigar 插件是通过JVM 访问操作系统,读取计算机硬件的一个插件库。读取计算机硬件过程中,必须由操作系统提供硬件信息。硬件信息是通过操作系统提供的。zip 压缩包中是 sigar 编写的操作系统文件,如:windows 中的动态链接库文件。解压需要的操作系统文件,将操作系统文件赋值到${Java_home}/bin 目录中。


4.6 HTTP 议 协议 处理


使用 Netty 服务开发。实现 HTTP 协议处理逻辑。


5  流数据的传输处理


在基于流的传输里比如 TCP/IP,接收到的数据会先被存储到一个 socket 接收缓冲里。不幸的是,基于流的传输并不是一个数据包队列,而是一个字节队列。即使你发送了 2 个独立的数据包,操作系统也不会作为 2 个消息处理而仅仅是作为一连串的字节而言。因此这是不能保证你远程写入的数据就会准确地读取。所以一个接收方不管他是客户端还是服务端,都应该把接收到的数据整理成一个或者多个更有意思并且能够让程序的业务逻辑更好理解的数据。

在处理流数据粘包拆包时,可以使用下述处理方式:

使用定长数据处理,如:每个完整请求数据长度为 8 字节等。 (FixedLengthFrameDecoder)

使用特殊分隔符的方式处理,如:每个完整请求数据末尾使用’\0’作为数据结束标记。(DelimiterBasedFrameDecoder)

使用自定义协议方式处理,如:http 协议格式等。使用 POJO 来替代传递的流数据,如:每个完整的请求数据都是一个 RequestMessage对象,在 Java 语言中,使用 POJO 更符合语种特性,推荐使用。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值