• 一,Broker服务端入口(NettyServer端)

首先RocketMq网络通信采用的Netty通信。服务端主要集中在Broker中。我们先看一下Broker的启动类BrokerStartup

显然具体逻辑是在start方法里面,下面是实现:

 public void start() throws Exception {
if (this.messageStore != null) {
this.messageStore.start();
} if (this.remotingServer != null) {
this.remotingServer.start();
} if (this.fastRemotingServer != null) {
this.fastRemotingServer.start();
} if (this.fileWatchService != null) {
this.fileWatchService.start();
} if (this.brokerOuterAPI != null) {
this.brokerOuterAPI.start();
} if (this.pullRequestHoldService != null) {
this.pullRequestHoldService.start();
} if (this.clientHousekeepingService != null) {
this.clientHousekeepingService.start();
} if (this.filterServerManager != null) {
this.filterServerManager.start();
} if (!messageStoreConfig.isEnableDLegerCommitLog()) {
startProcessorByHa(messageStoreConfig.getBrokerRole());
handleSlaveSynchronize(messageStoreConfig.getBrokerRole());
} this.registerBrokerAll(true, false, true); this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() { @Override
public void run() {
try {
BrokerController.this.registerBrokerAll(true, false, brokerConfig.isForceRegister());
} catch (Throwable e) {
log.error("registerBrokerAll Exception", e);
}
}
}, 1000 * 10, Math.max(10000, Math.min(brokerConfig.getRegisterNameServerPeriod(), 60000)), TimeUnit.MILLISECONDS); if (this.brokerStatsManager != null) {
this.brokerStatsManager.start();
} if (this.brokerFastFailure != null) {
this.brokerFastFailure.start();
} }

可以从名字大致猜出接收远程消息是remotingServer.start(),点进去观察一下其具体实现:

这里看到我们熟悉的面孔ServerBootStrap, 那么可以明确一点,我们要知道的具体通信协议实现,必定是写在一个handler里面的:

.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline()
.addLast(defaultEventExecutorGroup, HANDSHAKE_HANDLER_NAME,
new HandshakeHandler(TlsSystemConfig.tlsMode))
.addLast(defaultEventExecutorGroup,
new NettyEncoder(),
new NettyDecoder(),
new IdleStateHandler(0, 0, nettyServerConfig.getServerChannelMaxIdleTimeSeconds()),
new NettyConnectManageHandler(),
new NettyServerHandler()
);
}

从这些handler中,由名字可以猜测,通信消息的解析发生在NettyServerHandler,进入NettyServerHandler:

由上图可知,它本身就是一个读消息的Handler, 可以看到的是接收的消息体是RemotingCommand。这个类必然就是整个RocketMq的通信协议。

点进去看一下:

大致上看由code、Header、body以及一些metedata组成。其实所有的Rpc调用框架基本上都是这个设计思路。所有的请求必须继承自某一个父类。

不过现在的微服务体系似乎没有这样子做,可能是出于不同的服务需求多样性考虑,但是没有统一的请求头着实怪异,后续有时间看一下这方面的设计考虑。

至此,Rpc的Netty调用链基本结束。

  •  二,RocketMq 通信编码 

由一的部分成功定位到了接收消息的入口,本章着重讲解其解析消息的细节实现。

rocketMq通信协议Netty采用的是面向字节流的报文设计。在发送端,前4个字节存储整个报文长度,紧接着4个字节存储头信息,然后紧接着发送body字节流。源码如下:

 public ByteBuffer encodeHeader(final int bodyLength) {
// 定义头4个字节储存整个报文长度
int length = 4; // 计算头部长度
byte[] headerData;
headerData = this.headerEncode();
length += headerData.length; // 计算body长度
length += bodyLength;

     // 头部信息:整体报文长度信息(4个字节) + 头部数据(length-bodyLehth)
ByteBuffer result = ByteBuffer.allocate(4 + length - bodyLength); // 第一个4字节: 存放报文整体长度信息,从这里我们可以看到meaasge的消息长度是有限制的
result.putInt(length); // 第二个4字节: 第一个字节存放的是序列化类型,有Java或者RocketMq类型。后三个字节存放的是头部数据长度
result.put(markProtocolType(headerData.length, serializeTypeCurrentRPC)); // 写入头部数据
result.put(headerData); result.flip(); return result;
}

  通过对编码部分源码学习,一般对字节的操作喜欢用位运算符,比如要整型的第三个字节,int >>>0xff & 0xff 即可。下面是rocketMq解析的部分示例代码:

   public static SerializeType getProtocolType(int source) {
return SerializeType.valueOf((byte) ((source >> 24) & 0xFF));
}

  待续。。。。。。

RocketMq中网络通信之服务端的更多相关文章

  1. web应用中浏览器与服务端的编码和解码

    转自:http://blog.sina.com.cn/s/blog_87cb63e50102w2b6.html 以下为正文: ************************************* ...

  2. DelphiXE7中创建WebService(服务端+客户端)

    相关资料: http://www.2ccc.com/news/Html/?1507.html http://www.dfwlt.com/forum.php?mod=viewthread&tid ...

  3. 在python中编写socket服务端模块(二):使用poll或epoll

    在linux上编写socket服务端程序一般可以用select.poll.epoll三种方式,本文主要介绍使用poll和epoll编写socket服务端模块. 使用poll方式的服务器端程序代码: i ...

  4. DelphiXE7中创建WebService(服务端+客户端) good

    相关资料:http://www.2ccc.com/news/Html/?1507.html DelphiXE7新建WebService具体操作:1.打开“DelphiXE7”->“File”-& ...

  5. Asp.net 中,在服务端向客户端写脚本的常用方法

    在Asp.net 服务端处理脚本,一般都用 ClientScriptManager ,即web窗体服务端的this.ClientScript.该对象比较常用的方法: 1.RegisterArrayDe ...

  6. 在Unity3D中连接WCF服务端

    服务端不多讲解,有一处需要改的地方.具体服务端请看WCF入门学习2-控制台做为宿主 建议实际项目不要拿去用,毕竟是mono不是原生.net.或许是个坑 由于Unity的mono版本问题不能直接用net ...

  7. [gRPC] 在 .NET Core 中创建 gRPC 服务端和客户端

    gRPC 官网:https://grpc.io/ 1. 创建服务端 1.1 基于 ASP.NET Core Web 应用程序模板创建 gRPC Server 项目. 1.2 编译并运行 2. 创建客户 ...

  8. php开发中怎么获取服务端MAC地址?

    MAC(Media Access Control或者Medium Access Control)地址,意译为媒体访问控制,或称为物理地址.硬件地址,用来定义网络设备的位置.在php中如何获取MAC(M ...

  9. jQuery中的ajax服务端返回方式详细说明

    http://blog.sina.com.cn/s/blog_6f92e3a70100u3b6.html     上次总结了下ajax的所有参数项,其中有一项dataType是设置具体的服务器返回方式 ...

随机推荐

  1. [apue] dup2的正确打开方式

    管道与重定向常常需要使用dup与dup2复制句柄,其中dup2又较为常用,但是使用dup2有几个小坑需要注意. int dup2(int oldfd, int newfd); man手册页上是这样讲的 ...

  2. Quartz每次调度时被执行两次

    [关键字:重复执行.重复调用.每次执行两次.执行2次] 前言: 先说一下,项目背景.由于组内某成员在用Maven搭建项目时不规范,导致项目的名称与实际访问项目名称不一致.在部署项目时,必需要配一下虚拟 ...

  3. ZOJ 3955:Saddle Point(思维)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3955 题意:给出一个n*m的矩阵,定义矩阵中的特殊点Aij当且仅当Aij是 ...

  4. Codeforces 617E:XOR and Favorite Number(莫队算法)

    http://codeforces.com/problemset/problem/617/E 题意:给出n个数,q个询问区间,问这个区间里面有多少个区间[i,j]可以使得ai^ai+1^...^aj ...

  5. spring源码深度解析— IOC 之 bean 的初始化

    一个 bean 经历了 createBeanInstance() 被创建出来,然后又经过一番属性注入,依赖处理,历经千辛万苦,千锤百炼,终于有点儿 bean 实例的样子,能堪大任了,只需要经历最后一步 ...

  6. Maven打包成Jar文件时依赖包的问题

    我们项目中使用到第三方的库文件,这些jar库文件并没有放到Maven中央库上,导致我们需要在项目中自己配置使用.我们的两三个开发人员对Java都是很熟,因此在使用中遇到了一些问题,表现在:在本地中引入 ...

  7. Linux命令学习-tail命令

    Linux中,tail命令的全称就是tail,主要用于监控日志文件. 对于一个正在运行应用来说,其对应的log日志文件肯定是在不断的更新,此时,便可通过tail命令来动态显示日志文件的内容.假设当前目 ...

  8. EF 使用遇到过的错误记录备忘

    1. is only supported for sorted input in LINQ to Entities  The method :只支持排序输入实体LINQ 的方法 是使用skip()时没 ...

  9. Java - 格式化输出JSON字符串的两种方式

    目录 1 使用阿里的fastjson 1.1 项目的pom.xml依赖 1.2 Java示例代码 2 使用谷歌的gson 2.1 项目的pom.xml依赖 2.2 Java示例代码 1 使用阿里的fa ...

  10. PHP---微信JS-SDK获取access_token/jsapi_ticket/signature权限签名算法,php/thinkphp实现微信分享自定义文字和图片

    PHP---微信JS-SDK获取access_token/jsapi_ticket/signature权限签名算法, php/thinkphp实现微信分享自定义文字和图片. 一.先看微信JS-SDK文 ...