zoukankan      html  css  js  c++  java
  • RocketMQ踩坑记

    一、前言

    现在的主流消息队列基本都是kafka、RabbitMQ和RocketMQ,只有了解各自的优缺点才能在不同的场景选择合适的MQ,对比图如下:

    MQ对比图
    MQ对比图

    本篇文章主要介绍我自己在跑官方demo时遇到的一些坑(基于4.3版本),建议先看看RocketMQ的理论知识。

    Apache 上开源官方地址:https://rocketmq.apache.org/
    GitHub 托管地址:https://github.com/apache/rocketmq
    阿里官方的介绍文档:http://jm.taobao.org/2017/01/12/rocketmq-quick-start-in-10-minutes/
    Apache 官方提供的 4.3.0 版本的 “快速入门” 文档:https://rocketmq.apache.org/docs/quick-start/

    二、安装

    安装过程可以参考官方的快速入门文档,这时可能会遇见第一个坑。

    坑一:启动broker失败,查看日志nohup.out 显示内存不足

    Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000005c0000000, 8589934592, 0) failed; error='Cannot allocate memory' (errno=12)
    #
    # There is insufficient memory for the Java Runtime Environment to continue.
    # Native memory allocation (mmap) failed to map 8589934592 bytes for committing reserved memory.
    # An error report file with more information is saved as:
    # /usr/local/rocketmq-all-4.3.0/distribution/target/apache-rocketmq/hs_err_pid7209.lo
    

    这是因为 apache-rocketmq/bin 目录下启动 nameserv 与 broker 的 runbroker.shrunserver.sh 文件中默认分配的内存太大,而系统实际内存却太小导致启动失败。解决办法就是修改runbroker.shrunserver.sh里的内存配置,调小一些即可。

    runserver.sh
    runserver.sh

    runbroker.sh
    runbroker.sh

    三、运行官方示例

    这时候在服务器启动好namesrv和broker,你以为建个项目复制好代码就万事大吉了?

    项目截图
    项目截图

    坑二:No route info of this topic
    运行OnewayProducer的main方法控制台可能报如下错误:
    org.apache.rocketmq.client.exception.MQClientException: No route info of this topic

    网上的解决方案有好几种,主要如下:

    1.没有创建topic

    原因归于我们没有创建topic,要把启动broker的命令改为nohup sh bin/mqbroker -n localhost:9876 autoCreateTopicEnable=true &

    默认情况下 broker会自动创建话题,所以这个完全是没用的。

    2.防火墙问题

    如果真是防火墙问题,那报错信息一定连接失败什么的,当时我也以为是这个问题但是发现防火墙已经关闭了。

    3.pom文件的jar问题

    pom文件上rocketmq-client的版本要与 /usr/local/rocketmq-all-4.3.2/distribution/target/apache-rocketmq/lib目录下的jar包版本一致。当时项目pom.xml上的版本是4.3,RocketMQ上的是rocketmq-client-4.3.2.jar,后来将依赖改为4.3.2就好。

    4.broker未启动完毕

    这是我发现的一种情况,broker启动是需要时间的,日志显示启动成功后再运行代码。

    坑三:org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to <172.19.0.1:10909> failed

    再次运行OnewayProducer会发现错误又变了!

    Exception in thread "main" org.apache.rocketmq.client.exception.MQClientException: Send [1] times, still failed, cost [4190]ms, Topic: TopicTest, BrokersSent: [bogon]
    See http://rocketmq.apache.org/docs/faq/ for further details.
        at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:610)
        at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendOneway(DefaultMQProducerImpl.java:905)
        at org.apache.rocketmq.client.producer.DefaultMQProducer.sendOneway(DefaultMQProducer.java:285)
        at cn.sp.simple.OnewayProducer.main(OnewayProducer.java:21)
    Caused by: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to <172.19.0.1:10909> failed
        at org.apache.rocketmq.remoting.netty.NettyRemotingClient.invokeOneway(NettyRemotingClient.java:561)
        at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:324)
        at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:294)
        at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendKernelImpl(DefaultMQProducerImpl.java:785)
        at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:529)
        ... 3 more
    

    重点在于connect to <172.19.0.1:10909> failed这里的ip地址并不是我本地虚拟机的ip地址,我们需要手动设置broker的ip地址

    #进入rocketmq根目录
    cd /usr/local/rocketmq-all-4.3.2/distribution/target/apache-rocketmq
    #编写配置文件,并写好配置
    echo "brokerIP1=10.2.x.x" > broker.properties
    #启动 mqnamesrv 
    nohup sh bin/mqnamesrv &
    
    #重点:mrbroker 启动时通过 -c 加载配置文件
    nohup sh bin/mqbroker -n localhost:9876 -c /usr/local/rocketmq-all-4.3.2/distribution/target/apache-rocketmq/broker.properties &
    
    

    这时可以正常的生产消息和消费了,但是当我运行异步生产消息的AsyncProducer时又开始报错了!

    坑四:官方示例AsyncProducer代码错误

    错误信息截图
    错误信息截图

    问题的原因是主线程提前关闭,导致异步线程受到影响,所以可以用CountDownLatch来解决,修改后代码如下:

    public class AsyncProducer {
    
      public static void main(String[] args) throws Exception {
        //Instantiate with a producer group name.
        DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
        // Specify name server addresses.
        producer.setNamesrvAddr("192.168.75.132:9876");
        //Launch the instance.
        producer.start();
        producer.setRetryTimesWhenSendAsyncFailed(0);
        int messageCount  = 100;
     
        final CountDownLatch countDownLatch  = new CountDownLatch(messageCount);
        for (int i = 0; i < messageCount; i++) {
          final int index = i;
          //Create a message instance, specifying topic, tag and message body.
          Message msg = new Message("TopicTest",
              "TagA",
              "OrderID188",
              "Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));
          producer.send(msg, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
              countDownLatch.countDown();
              System.out.printf("%-10d OK %s %n", index,
                  sendResult.getMsgId());
            }
            @Override
            public void onException(Throwable e) {
              countDownLatch.countDown();
              System.out.printf("%-10d Exception %s %n", index, e);
              e.printStackTrace();
            }
          });
        }
        countDownLatch.await();
        //Shut down once the producer instance is not longer in use.
        producer.shutdown();
      }
    }
    

    重新运行该类,发现问题终于解决了。

    enter description here
    enter description here

    补充一下RocketMQ可视化控制台的搭建步骤

    1. 下载源代码,github地址为:https://github.com/apache/rocketmq-externals
    2. 进入目录rocketmq-console,运行命令 mvn clean package -DskipTests=true得到jar包文件rocketmq-console-ng-1.0.1.jar
    3. 上传rocketmq-console-ng-1.0.1.jar,使用nohup命令启动即可。
    4. 游览器访问http://ip:8080即可看到web管理界面,如下图。

    enter description here
    enter description here

    四、总结

    原本以为就搭个环境跑个demo很快就能完成,没想到遇到了这么多坑,不过也收获很多。

    参考资料:
    https://blog.csdn.net/wangmx1993328/article/details/81536168
    https://my.oschina.net/u/3476125/blog/897429
    https://blog.csdn.net/jessDL/article/details/86646086

  • 相关阅读:
    从零实现一个http服务器
    服务器端编程心得(七)——开源一款即时通讯软件的源码
    服务器端编程心得(六)—— 关于网络编程的一些实用技巧和细节
    服务器编程心得(五)—— 如何编写高性能日志
    以芯片直读方式得到的Android全盘镜像解析——DOS分区
    一款开源数据恢复工具——scalpel
    以芯片直读方式得到的全盘镜像解析及ext4日志区域解析——GPT分区
    Linux程序设计之shell程序设计
    算法——蛮力法之最近对问题和凸包问题
    算法——蛮力法之顺序查找和蛮力字符串匹配
  • 原文地址:https://www.cnblogs.com/2YSP/p/11616376.html
Copyright © 2011-2022 走看看