首页 > 其他分享 >本地启动RocketMQ未映射主机名产生的超时问题

本地启动RocketMQ未映射主机名产生的超时问题

时间:2024-02-25 21:12:18浏览次数:33  
标签:java 主机名 9876 RocketMQ apache org 日志 超时 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

标签:java,主机名,9876,RocketMQ,apache,org,日志,超时,rocketmq
From: https://www.cnblogs.com/nuccch/p/18033047

相关文章

  • C# 方法执行超时处理
    C#方法执行超时处理封装了一个方法,用于处理一些需要判断是否执行超时了的操作internalstaticTTimeoutCheck<T>(intms,Func<T>func){varwait=newManualResetEvent(false);boolRunOK=false;vartask=Task.Run<T>(()......
  • 9.Polly在NET中的使用,重试、熔断、超时、降级、限流简单用法
    Polly是一个.NET弹性和瞬态故障处理库,允许开发人员以Fluent和线程安全的方式来实现重试、断路、超时、隔离、限流和降级策略。文档: https://gitee.com/hubo/Polly重试(Retry)出现故障自动重试,这个是很常见的场景,如:当发生请求异常、网络错误、服务暂时不可用时,就应该重试。......
  • zabbix修改主机名称可支持中文名
    如图默认情况下,Zabbix是不支持主机名中存在中文字符的,要让zabbix主机名支持中文,需要修改zabbix的php代码文件, 实线步骤:找到zabbixweb目录,一般在/var/www/zabbix或者/usr/share/zabbix下 找到zabbixweb目录,一般在/var/www/zabbix或者/usr/share/zabbix下一、修改/usr/......
  • 银河麒麟桌面版操作系统修改主机名
    1图形化方式修改1.1在计算机图标上右键,选择属性1.2修改1.2.1点击修改计算机名选择玩属性后会自动跳转到关于中,在计算机名中点击修改图标本质就是设置里面的系统下的关于,我们右键计算机选择属性就直接跳转过来了1.2.2修改系统名字这里修改为user-pcOS1.2.3重启生效......
  • 深入剖析如何设计订单超时自动取消的功能
    我们在美团APP下单,假如没有立即支付,进入订单详情会显示倒计时,如果超过支付时间,订单就会被自动取消。这篇文章,笔者想以架构师的视角,深入剖析如何设计订单超时自动取消的功能。1定时任务首先,我们非常自然的想到定时任务的方案。方案流程:每隔30秒查询数据库,取出最近的N......
  • RocketMQ搭建(单组节点单副本模式)
    RocketMQ搭建(单组节点单副本模式) 1、下载RocketMQ二进制包wgethttps://archive.apache.org/dist/rocketmq/5.1.2/rocketmq-all-5.1.2-bin-release.zip 2、解压,移动程序包至安装目录并创建软连接。unziprocketmq-all-5.1.2-bin-release.zipmvrocketmq-all-5.1.2-b......
  • RocketMQ源码系列(1) — 基础架构
    基础架构我们先通过下面这张图来整体的对RocketMQ有一个基础架构上的认识。RocketMQ主要有四个角色:NameServer、Broker、Producer、Consumer。Broker每台机器上部署的RocketMQ进程一般称之为Broker,生产者向Broker发送消息,Broker收到生产者的消息后存储到本地磁盘文件中......
  • RocketMQ—RocketMQ消息重复消费问题
    RocketMQ—RocketMQ消息重复消费问题重复消费问题的描述什么情况下会发生重复消费的问题:生产者多次投递消息:如果生产者发送消息时,连接有延迟,MQ还没收到消息,生产者又发送了一次消息;消费者方扩容时会重试:topic中有四个queue,queue2中有一个消息MSG,如果此时只有一个消费者,MSG......
  • RabbitMQ 使用细节 → 优先级队列与ACK超时
    开心一刻今天坐在太阳下刷着手机老妈走过来问我:这么好的天气,怎么没出去玩我:我要是有钱,你都看不见我的影子老妈:你就不知道带个碗,别要边玩?我:......优先级队列说到队列,相信大家一定不陌生,是一种很基础的数据结构,它有一个很重要的特点:先进先出但......
  • RocketMQ—RocketMQ消费重试和死信消息
    RocketMQ—RocketMQ消费重试和死信消息消费重试生产者重试设置重试的代码如下//失败的情况重发3次producer.setRetryTimesWhenSendFailed(3);//消息在1S内没有发送成功,就会重试producer.send(msg,1000);一般情况下,我们不会在生产者方进行重试。消费者重试消费者在消......