基于Netty的网络调用实现

作为一个分布式消息队列,通信的质量至关重要。基于TCP协议和Socket实现一个高效、稳定的通信程序并不容易,有很多大大小小的“坑”等待着经验不足的开发者。RocketMQ选择不重复发明轮子,基于Netty库来实现底层的通信功能。

1 Netty介绍

Netty是一个网络应用框架,或者说是一个Java网络开发库。Netty提供异步事件驱动的方式,使用它可以快速地开发出高性能的网络应用程序,比如客户端/服务器自定义协议程序,大大简化了网络程序的开发过程。

Netty是一个精心设计的框架,它从许多协议实现中吸收了丰富的经验,比如FTP、SMTP、HTTP等许多基于二进制和文本的传统协议。借助Netty,可以比较容易地开发出达到Java网络专家+并发编程专家水平的通信程序。

了解Netty前需要对Java NIO有个基本的了解,熟悉Channel、ByteBuffer、Selector等基本概念。对于Java网络编程经验不多的读者,可以试着先用Java NIO的基本类写一个简单的Client/Server程序,然后再用Netty对比着实现一遍,这样比较容易理解Netty里各种组件存在的原因。

2 Netty架构总览

如图13-1所示,Netty主要分为三部分:一是底层的零拷贝技术和统一通信模型;二是基于JVM实现的传输层;三是常用协议支持。如果想深入了解的话可以阅读一些专门介绍Netty的书籍。

图13-1 Netty整体架构

3 重新实现ByteBuffer

在网络通信中,CPU处理数据的速度大大快于网络传输数据的速度,所以需要引入缓冲区,将网络传输的数据放入缓冲区,累积足够的数据再发给CPU处理。

Netty使用自己重新实现的buffer API,而不是使用NIO的ByteBuffer来表示一个连续的字节序列。新实现的buffer类型ByteBuf可以从底层解决ByteBuffer的一些问题,是一种更适合日常网络应用开发需要的缓存类型。重新实现的ByteBuf特性包括允许使用自定义的缓存类型、透明的零拷贝实现、比ByteBuffer更快的响应速度等。

字节缓存在网络通信中会被频繁地使用,ByteBuf实现的是一个非常轻量级的字节数组包装器。ByteBuf有读操作和写操作,为了便于用户使用,该缓冲区维护了读索引和写索引。ByteBuf由三个片段构成:废弃段、可读段和可写段。其中,可读段表示缓冲区实际存储的可用数据。当用户使用read或者skip方法时,将会增加读索引。读索引之前的数据将进入废弃段,表示该数据已被使用过了。此外,用户可主动使用discardReadBytes清空废弃段以便得到更多的可写空间。简单来说和ByteBuffer相比,ByteBuf用在网络编程时更合适,更易用。

3 统一的异步I/O接口

传统的Java I/O API在应对不同的传输协议时需要使用不同的类型和方法。例如java.net.Socket和java.net.DatagramSocket,但它们没有相同的父类型,因此需要使用不同的调用方式执行Socket操作。因为在模式上不匹配,所以更换网络应用的传输协议时工作会变得很繁杂。由于(Java I/O API)缺乏协议间的可移植性,无法在不修改网络传输层的前提下增加多种协议的支持。从理论上讲,多种应用层协议可运行在多种传输层协议之上,例如TCP/IP、UDP/IP、SCTP和串口通信。

还有个复杂的情况是,Java的新I/O(NIO)API与原有的阻塞式I/O(OIO)API不兼容。这两者无论是在设计上还是在性能上,其特性都不相同,可是在开发时一般只选择某一种API。例如,在用户数较小的时候可以选择使用传统的OIO(Old I/O)API,毕竟与NIO相比使用OIO更加容易;但是当业务快速增长,服务器需要同时处理成千上万的客户连接时问题就来了,这时候不得不尝试使用NIO来解决,新的NIO Selector编程接口和Old I/O差别很大,很难做到快速升级。

Netty有一个被称为Channel的统一异步I/O编程接口,这个编程接口抽象了所有点对点的通信操作。这样,如果应用是基于Netty的某一种传输方式来实现的,则可以快速迁移到另一种传输实现上。Netty提供了几种拥有相同编程接口的基本传输实现:

·基于NIO的TCP/IP传输(io.netty.channel.nio);

·基于OIO的TCP/IP传输(io.netty.channel.oio);

·基于OIO的UDP/IP传输(io.netty.channel.oio);

·本地传输(io.netty.channel.local)。

切换不同的传输实现通常只需修改几行代码,而且由于核心API具有高度的可扩展性,很容易定制自己的传输实现。

4 基于拦截链模式的事件模型

一个定义良好并具有扩展能力的事件模型可以大大提高事件驱动程序的效率,Netty就具有定义良好的I/O事件模型,它采用严格的层次结构来区分不同的事件类型,Netty也允许在不破坏现有代码的情况下实现自己的事件类型。事件模型是Netty的一个亮点,很多NIO通信框架没有或者仅有有限的事件模型概念,当需要一个新的事件类型的时候常常需要修改已有的代码,有的甚至不允许进行自定义的扩展。

在Netty中,ChannelPipeline内部的一个ChannelEvent被一组ChannelHandler处理。这个管道是Intercepting Filter(拦截过滤器)模式的一种高级形式的实现,因此对于一个事件如何被处理,以及管道内部处理器间的交互过程,用户拥有绝对的控制力。

5 高级组件

Netty提供了一系列的高级组件来让开发过程更加快捷,比如Codec框架、SSL/TLS支持、HTTP实现等。

首先看看Codec框架。从业务逻辑代码中分离协议处理部分可以让代码结构变得更清晰,但是如果从零开始实现会有很高的复杂性,比如处理分段消息,相互叠加的多层协议,还有些协议复杂到无法在一台独立的状态机上实现。Netty提供了一组构建在其核心模块之上的codec实现,是一种可扩展、可重用、可单元测试,并且是多层的codec框架,为用户提供容易维护的codec代码。

Netty还提供对SSL/TLS的支持,不同于传统阻塞式的I/O实现,在NIO模式下支持SSL功能不能只是简单地包装一下流数据并进行加密或解密工作,还需要借助于javax.net.ssl.SSLEngine。SSLEngine是一个有状态的实现,使用SSLEngine必须管理所有可能的状态,例如密码套件、密钥协商(或重新协商)、证书交换以及认证等,而且SSLEngine不是一个绝对的线程安全实现。在Netty内部,SslHandler封装了所有艰难的细节,以及使用SSLEngine可能带来的陷阱。用户只需要配置并将该SslHandler插入你的ChannelPipeline中即可,而且Netty允许实现像StartTlS那样的高级特性。

HTTP是互联网上最受欢迎的协议,与现有的HTTP实现相比,Netty的HTTP实现是相当与众不同的。在HTTP消息的低层交互过程中用户拥有绝对的控制力,因为Netty的HTTP实现只是一些HTTP Codec和HTTP消息类的简单组合,不存在任何限制,例如那种被迫选择的线程模型。用户可以根据自己的需求编写那种可以完全按照你期望的工作方式工作的客户端或服务器端代码,比如线程模型、连接生命期、快编码等。基于这种高度可定制化的特性,用户可以开发一个非常高效的HTTP服务器,例如要求持久化链接以及服务器端推送技术的聊天服务,需要保持链接直至整个文件下载完成的媒体流服务,需要上传大文件并且没有内存压力的文件服务,支持大规模混合客户端应用用于连接以万计的第三方异步web服务等。

Netty的WebSockets实现,WebSockets允许双向,全双工通信信道。在TCP socket中,它被设计为允许一个Web浏览器和Web服务器之间通过数据流交互。WebSocket协议已经被IETF列为RFC 6455规范,并且Netty实现了RFC 6455和一些老版本的规范。

此外Netty还支持Google Protocol Buffer,Google Protocol Buffers是快速实现一个高效的二进制协议的理想方案。通过使用ProtobufEncoder和ProtobufDecoder,我们可以把Google Protocol Buffers编译器(protoc)生成的消息类放入Netty的codec实现中。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TCP报文解析

1.端口号 标记同一台计算机上的不同进程 源端口:占2个字节,源端口和IP的作用是标记报文的返回地址。 目的端口:占2个字节,指明接收方计算机上的应用程序接口。 TCP报头中的源端口号和目的端口号同IP报头中的源IP和目的IP唯一确定一…

马蹄集第34周

1.战神的对称谜题 不知道为什么超时&#xff01; def main():s input()result 0for i in range(len(s)):l i - 1r i 1while l > 0 and r < len(s) and s[l] s[r]:result max(result, r - l 1)l - 1r 1l ir i 1while l > 0 and r < len(s) and s[l] s…

二分查找与搜索树高频问题

关卡名 逢试必考的二分查找 我会了✔️ 内容 1.山脉数组的峰顶索引 ✔️ 2.旋转数字的最小数字 ✔️ 3.寻找缺失数字 ✔️ 4.优化求平方根 ✔️ 5.中序与搜索树原理 ✔️ 6.二叉搜索树中搜索特定值 ✔️ 7.验证二叉搜索树 ✔️ 基于二分查找思想&#xff0c;可以拓展出很…

【PUSDN】WebStorm中报错Switch language version to React JSX

简述 WebStorm中报错Switch language version to React JSX 可能本页面的写法是其他语法。所以可以不用管。 测试项目&#xff1a;ant design vue pro 前情提示 系统&#xff1a; 一说 同步更新最新版、完整版请移步PUSDN Powered By PUSDN - 平行宇宙软件开发者网www.pusdn…

算法学习—排序

排序算法 一、选择排序 1.算法简介 选择排序是一个简单直观的排序方法&#xff0c;它的工作原理很简单&#xff0c;首先从未排序序列中找到最大的元素&#xff0c;放到已排序序列的末尾&#xff0c;重复上述步骤&#xff0c;直到所有元素排序完毕。 2.算法描述 1&#xff…

C语言-预处理与库

预处理、动态库、静态库 1. 声明与定义分离 一个源文件对应一个头文件 注意&#xff1a; 头文件名以 .h 作为后缀头文件名要与对应的原文件名 一致 例&#xff1a; 源文件&#xff1a;01_code.c #include <stdio.h> int num01 10; int num02 20; void add(int a, in…

uniapp 使用web-view外接三方

来源 前阵子有个需求是需要在原有的项目上加入一个电子签名的功能&#xff0c;为了兼容性和复用性后面解决方法是将这个电子签名写在一个新的项目中&#xff0c;然后原有的项目使用web-view接入这个电子签名项目&#xff1b; 最近又有一个需求&#xff0c;是需要接入第三方的…

蓝桥杯每日一题2023.11.30

题目描述 九数组分数 - 蓝桥云课 (lanqiao.cn) 题目分析 此题目实际上是使用dfs进行数字确定&#xff0c;每次循环中将当前数字与剩下的数字进行交换 eg.1与2、3、4、、、进行交换 2与3、4、、、进行交换 填空位置将其恢复原来位置即可&#xff0c;也就直接将其交换回去即可…

Linux(CentOS7.5):新增硬盘分区纪实

一、服务器概述 1、既有一块系统硬盘&#xff0c;新增一块100G硬盘。 2、要求&#xff0c;将新插入硬盘分为&#xff1a;20G、30G、50G。 二、操作步骤 1、确认新硬盘是否插入成功&#xff1a; fdisk -l# 红色框出来的&#xff0c;为识别出来的新硬盘信息 # 黄色框出来的&#…

Linux:锁定部分重要文件,防止误操作

一、情景描述 比如root用户或者拥有root权限的用户&#xff0c;登陆系统后&#xff0c;通过useradd指令&#xff0c;新增一个用户。 而我们业务限制&#xff0c;只能某一个人才有权限新增用户。 那么&#xff0c;这个时候&#xff0c;我们就用chattr来锁定/etc/passwd文件&…

一些ab命令

1.ab简介 ab是apache自带的压力测试工具&#xff0c;是apachebench命令的缩写。ab非常实用&#xff0c;它不仅可以对apache服务器进行网站访问压力测试&#xff0c;也可以对或其它类型的服务器如nginx、tomcat、IIS等进行压力测试。 ab的原理&#xff1a;ab命令会创建多个并发…

力扣 790. 多米诺和托米诺平铺(一维dp)

题目描述&#xff1a; 有两种形状的瓷砖&#xff1a;一种是 2 x 1 的多米诺形&#xff0c;另一种是形如 "L" 的托米诺形。两种形状都可以旋转。 给定整数 n &#xff0c;返回可以平铺 2 x n 的面板的方法的数量。返回对 109 7 取模 的值。 平铺指的是每个正方形都…

df新增一列数据,并指定列名

方法1&#xff1a;直接指定df列名赋值为list即可 skill_info_df[age] age_list ps:list的长度要和df对齐 方法二 使用insert&#xff1a;

智能优化算法应用:基于象群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于象群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于象群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.象群算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

AntDB数据库,通信行业20年变迁的见证者

2000年至今&#xff0c;通信行业发展已过了20多年。面对通信行业巨大的数据信息&#xff0c;数据库在行业发展中发挥了巨大的作用&#xff0c;AntDB数据库便是其中较为知名的一款数据库。在通信行业快速发展的阶段&#xff0c;打破国外产品与技术垄断是产业发展的重点与难点。面…

latex表格中内容过多如何换行【已解决】

最近在写论文的时候放了一个表格&#xff0c;但是表格看起来特别大&#xff0c;因为想让某些内容多的单元格完成换行操作 首先在main.tex引入makecell包 \usepackage{makecell} 然后回到表格找到你想换行的单元格&#xff0c;把\makecell{}加进去&#xff0c;然后在需要换行的…

深入浅出强化学习

目录 一、强化学习的概念 二、强化学习的特点 三、强化学习的训练过程 一、强化学习的概念 强化学习是一种机器学习方法&#xff0c;旨在教会算法如何通过与环境的交互来进行学习和决策。与传统的监督学习和无监督学习不同&#xff0c;强化学习侧重于学习与奖励和惩罚&#…

首批量子计算机即将部署!欧盟为波兰提供新算力优势

&#xff08;图片来源&#xff1a;网络&#xff09; 英国量子计算机开发商ORCA公司将为波兰的波兹南超级计算和网络中心&#xff08;PSNC&#xff09;提供两个PT-1光量子系统&#xff0c;以加速其在量子计算领域的研究和应用工作&#xff0c;如生物学、化学和机器学习领域。 …

机器人最优控制开源库 Model-based Optimization for Robotics

系列文章目录 文章目录 系列文章目录前言一、开源的库和工具箱1.1 ACADO1.2 CasADi1.3 Control Toolbox1.4 Crocoddyl1.5 Ipopt1.6 Manopt1.7 LexLS1.8 NLOpt1.9 qpOASES1.10 qpSWIFT1.11 Roboptim 二、其他库和工具箱2.1 MUSCOD2.2 OCPID-DAE12.3 SNOPT 前言 机器人&#xff…

Conductor之动态分叉

Conductor之动态分叉 动态分叉 关于动态分叉&#xff0c;参考1 动态分叉 有时候我们希望在运行时能动态添加分叉任务&#xff08;注意是分叉任务&#xff0c;不是动态任务&#xff09;&#xff0c;Conductor当前版本也是支持的&#xff0c;但是经过试验的版本只支持串行分叉&…