本地启动RocketMQ未映射主机名产生的超时问题
问题描述
参考RocketMQ官方文档在本地启动一个验证环境的时候遇到超时报错问题。
本地环境OS:CentOS Linux release 8.5.2111
首先,进入到RocketMQ安装目录,如:~/opt/rocketmq-all-5.2.0-bin-release。
执行如下命令启动NameServer:
$ sh bin/mqnamesrv
该命令执行很慢,但是最终还是显示启动NameServer成功了,输出日志如下:
Java HotSpot(TM) 64-Bit Server VM warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release
Java HotSpot(TM) 64-Bit Server VM warning: UseCMSCompactAtFullCollection is deprecated and will likely be removed in a future release.
The Name Server boot success. serializeType=JSON, address 0.0.0.0:9876
执行jps命令也能看到相应进程:
$ jps
13730 NamesrvStartup
执行如下命令启动Broker + Proxy:
$ sh bin/mqbroker -n localhost:9876 --enable-proxy
该命令执行非常漫长,差不多要90s左右才会输出如下日志:
Sat Feb 24 19:48:03 CST 2024 rocketmq-proxy startup successfully
在~/logs/rocketmqlogs/proxy.log日志中也能看到broker启动成功的日志:
2024-02-24 19:47:53 INFO main - The broker[broker-a, 192.168.88.135:10911] boot success. serializeType=JSON and name server is localhost:9876
注意:日志中的broker-a是在broker.conf文件中配置的brokerName参数,如下所示:
brokerClusterName = DefaultCluster
brokerName = broker-a # 配置的默认brokerName参数
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
再次执行jps命令确认相应进程是否已经启动:
$ jps
jps
13730 NamesrvStartup
14410 ProxyStartup
一切似乎看起来都正常,从~/logs/rocketmqlogs/namesrv.log和~/logs/rocketmqlogs/proxy.log日志中也看不出明显的异常。
但是在创建Topic时就会报错:
$ sh bin/mqadmin updatetopic -n localhost:9876 -t TestTopic -c DefaultCluster
该命令在执行大约40s左右就会输出如下报错日志:
org.apache.rocketmq.tools.command.SubCommandException: UpdateTopicSubCommand command failed
at org.apache.rocketmq.tools.command.topic.UpdateTopicSubCommand.execute(UpdateTopicSubCommand.java:198)
at org.apache.rocketmq.tools.command.MQAdminStartup.main0(MQAdminStartup.java:164)
at org.apache.rocketmq.tools.command.MQAdminStartup.main(MQAdminStartup.java:114)
Caused by: org.apache.rocketmq.remoting.exception.RemotingTimeoutException: invokeSync call the addr[127.0.0.1:9876] timeout
at org.apache.rocketmq.remoting.netty.NettyRemotingClient.invokeSync(NettyRemotingClient.java:549)
at org.apache.rocketmq.client.impl.MQClientAPIImpl.getBrokerClusterInfo(MQClientAPIImpl.java:1961)
at org.apache.rocketmq.tools.admin.DefaultMQAdminExtImpl.examineBrokerClusterInfo(DefaultMQAdminExtImpl.java:577)
at org.apache.rocketmq.tools.admin.DefaultMQAdminExt.examineBrokerClusterInfo(DefaultMQAdminExt.java:318)
at org.apache.rocketmq.tools.command.CommandUtil.fetchMasterAddrByClusterName(CommandUtil.java:94)
at org.apache.rocketmq.tools.command.topic.UpdateTopicSubCommand.execute(UpdateTopicSubCommand.java:171)
... 2 more
从报错信息看似乎是无法连接127.0.0.1:9876,但是经过验证发现该地址是一定可以连通的,再几经尝试之后依然报错。
于是换了一台Windows机器继续验证,奇怪的是在Windows机器上一切正常,而且我注意到在Windows环境启动RocketMQ的时候brokerName使用是主机名,如下日志:
# zhangsan是主机名
The broker[zhangsan, 20.5.133.188:10911] boot success. serializeType=JSON and name server is localhost:9876
于是脑袋中突然闪现一个疑问,是不是因为没有在CentOS的/etc/hosts文件中映射主机名与127.0.0.1地址导致的。
验证后果然就正常的。
原因追踪
根据相关报错日志梳理RocketMQ的源代码,报错是因为在NettyRemotingClient.invokeSync()方法中做了超时判断。
@Override
public RemotingCommand invokeSync(String addr, final RemotingCommand request, long timeoutMillis)
throws InterruptedException, RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException {
long beginStartTime = System.currentTimeMillis();
final Channel channel = this.getAndCreateChannel(addr);
String channelRemoteAddr = RemotingHelper.parseChannelRemoteAddr(channel);
if (channel != null && channel.isActive()) {
long left = timeoutMillis; // 默认超时时长是5000ms
try {
long costTime = System.currentTimeMillis() - beginStartTime;
left -= costTime;
if (left <= 0) { // 当执行时长超过5s时直接抛出异常
throw new RemotingTimeoutException("invokeSync call the addr[" + channelRemoteAddr + "] timeout");
}
RemotingCommand response = this.invokeSyncImpl(channel, request, left);
updateChannelLastResponseTime(addr);
return response;
}
//其他代码省略...
}
//其他代码省略...
}
由于是做了超时检查抛出的异常,所以单纯从日志信息看就会认为是无法连接127.0.0.1:9876,实际上该地址是可以连通的。
进一步追踪发现,是在执行Netty的ReflectiveChannelFactory.newChannel()方法耗时较长,约10s左右。
@Override
public T newChannel() {
try {
// constructor是NioSocketChannel.class
// 所以本质上这里是要通过反射的方式实例化一个NioSocketChannel对象
T t = constructor.newInstance();
return t;
} catch (Throwable t) {
throw new ChannelException("Unable to create Channel from class " + constructor.getDeclaringClass(), t);
}
}
验证代码如下:
long start = System.currentTimeMillis();
Constructor constructor = NioSocketChannel.class.getConstructor();
constructor.newInstance();
System.out.println(String.format("%s ms", System.currentTimeMillis() - start));
执行后输出日志:
10144 ms
奇怪的是,当在/etc/hosts文件中明确指定主机名与127.0.0.1的映射关系后,执行就非常快。
暂时还不清楚这个地方的深层次原因是什么,为什么通过反射方式实例化NioSocketChannel对象会跟主机名与127.0.0.1的映射有关系呢?
【参考】
Windows 启动RocketMQ
本地启动RocketMQ未映射主机名产生的超时问题的更多相关文章
- 通过获取DNS解析的未转义主机名,区分测试环境和正式环境代码
ASP.Net编程中经常有一些代码,测试环境下需要执行,而正式环境下不需要执行(或者反之). 我们经常做的方式是:去掉注释,测试,再注释,再编译上传(或者反之). 现在,不妨试试以下办法: Reque ...
- C#怎么得到主机名,IP,MAC
一:基础知识 a: Dns 类 提供简单的域名解析功能. Dns 类是一个静态类,它从 Internet 域名系统 (DNS) 检索关于特定主机的信息. 在 IPHostEntry 类的实例中返回来自 ...
- Ubuntu18.04修改主机名和网卡地址
date: 2019-06-26 09:56:04 author :headsen chen notice :个人原创 1,Ubuntu18.04 设置固定IP: 2,Ubuntu 18.04 设置主 ...
- CentOS6修改主机名(hostname)及 修改/etc/hosts 文件,增加ip和hostname的映射关系(转)
CentOS修改主机名(hostname) 需要修改两处:一处是/etc/sysconfig/network,另一处是/etc/hosts,只修改任一处会导致系统启动异常.首先切换到root用户. ...
- Linux 修改主机名 和 ip 映射关系
1. 修改主机名 vim /etc/sysconfig/network NETWORKING=yes HOSTNAME=hadoop 2. 修改主机名和IP的映射关系 vim /etc/hosts 1 ...
- linux的设置ip连接crt,修改主机名,映射,建文件
1.修改IP(或者vim vi /etc/sysconfig/network-scripts/ifcfg-eth0) 2.连接 crt 3.修改主机名 用vim 编辑 /etc/sysconfig/n ...
- 无法启动T-SQL调试。未能连接到计算机"."。这是在主机名解析时通常出现的暂时错误……
今天在按在SSMS中,按F11进行断点调试时,弹出错误:"无法启动T-SQL调试.未能连接到计算器".".这是在主机名解析时通常出现的暂时错误--", 如下图: ...
- Windows下主机名和IP映射设置
如果需要添加域名和IP的对应关系可以在以下地方进行修改. 打开系统目录:c:/windows/system32/drivers/etc找到hosts文件,打开hosts文件并在最后面添加一条记录 例如 ...
- Java获取本地IP地址和主机名
方式一:通过java.net.InetAddress类获取 public void test1() { try { InetAddress addr = InetAddress.getLocalHos ...
- CentOS7 设置主机名及IP映射
1.设置主机名 查看本机的主机名,使用如下三个命令中任意一个即可 # hostname # uname -n # cat /proc/sys/kernel/hostname 使用 vi 编辑器打开 / ...
随机推荐
- [转帖]docker使用buildx构建多平台(x86,arm64)构架镜像
https://blog.csdn.net/atzqtzq/article/details/128583331 配置文件激活buildx docker目前使用版本为Server Version: 20 ...
- [转帖]Unixbench的使用(综合性能测试、2D测试)和问题解决(跑不出多线程分数,调不出窗口,报错等)
一.Unixbench简介 Unixbench一个基于系统的基准测试工具,不单纯是CPU 内存 或者磁盘测试工具.测试结果不仅仅取决于硬件,也取决于系统.开发库.甚至是编译器.Unixbench是一个 ...
- DBLink实现备份文件不落盘的导入其他Oracle数据库实例的方法
DBLink实现备份文件不落盘的导入其他Oracle数据库实例的方法 背景 公司内经常有从其他服务器备份数据库实例的需求 之前的操作一般需要,备份源服务器使用expdp将source导出dump文件. ...
- csv用Excel打开出现乱码
CSV用Excel打开出现乱码 今天出现一个问题 使用wps打开不会出现乱码.但使用 excel 打开的时候会出现乱码. 其实在我们把文件流转成文件的时候需要在bolb 对象前加上unicode标识, ...
- elementUI自定义单选框内容
<template> <div> <div class="heng-div"> <el-radio v-model="radio ...
- 升级到win11 22h2的体验
win11 22h2更稳定了 在win11 22h2发布后没多久,我就升级到了这个版本,截止目前已经使用半个月了,谈谈我的使用感受. 总体要比之前的版本更稳定,表现为笔记本风扇不会突然响,突然卡顿,不 ...
- 基于新浪微博海量用户行为数据、博文数据数据分析:包括综合指数、移动指数、PC指数三个指数
基于新浪微博海量用户行为数据.博文数据数据分析:包括综合指数.移动指数.PC指数三个指数 项目介绍 微指数是基于海量用户行为数据.博文数据,采用科学计算方法统计得出的反映不同事件领域发展状况的指数产品 ...
- 8.1 TEB与PEB概述
在开始使用TEB/PEB获取进程或线程ID之前,我想有必要解释一下这两个名词,PEB指的是进程环境块(Process Environment Block),用于存储进程状态信息和进程所需的各种数据.每 ...
- C/C++ 结构体与指针笔记
结构体的定义与使用: #include <stdio.h> #include <stdlib.h> struct Student { int num; char name[30 ...
- C/C++ Qt QThread 线程组件应用
QThread库是QT中提供的跨平台多线程实现方案,使用时需要继承QThread这个基类,并重写实现内部的Run方法,由于该库是基本库,默认依赖于QtCore.dll这个基础模块,在使用时无需引入其他 ...