由于前几天感冒了,断更了几天,希望大家多穿点儿,出门戴好口罩,别感冒。上班的第一天,同事因为RabbitMQ中间件启动异常就找到了我,让我帮忙给看一下,因为这台机器是开发环境,整个小组开发调试都用这个消息中间件接收消息,平时都正常的,突然就起不来,令人匪夷所思,下面我就针对该异常的排查过程和具体问题做一个记录。
背景
开发环境RabbitMQ中间件起不来,领导急得团团转。由于公司采用Docker容器化方式部署,在平时都是好好的,只需要按照之前规定好的,拉镜像、起容器,今天突然容器启动都启动不起来,这很令人费解。但既然找到我这了,当然要查个彻底。
关注公众号【可为编程】回复【面试】领取年度最新面试题大全!!!
Docker角度
我先以docker 角度出发,从以下几个方面查询:
首先查看镜像
docker images
发现镜像正常,版本号正常,拉取镜像没问题。随后我检查了容器状态
docker ps -a
查看到容器的状态为created状态,处于正在创建状态,这就很奇怪,怎么没有运行呢?随后我又看了环境变量和RabbitMQ的start.sh脚本,发现并没有异常,同时查看docker日志
docker logs -f rabbitmq
竟然日志为空,这种情况真是很少见,因此我决定,重启该服务器的Docker,一定注意,我这是开发环境,生产环境和开发环境在重启前都要做好数据备份,所有正在使用的用户停止发送通信请求,避免对业务造成影响。
重启之后发现仍然报错,之前的错误消失,出现了新的异常错误,端口5672被占用。
Error starting userland proxy: listen tcp4 0.0.0.0:5672: bind: address already in use.
Linux通信角度
既然已经发现了是端口占用的问题,那就在服务器上排查这个端口
netstat -pna | grep 5672
突然发现有很多5672的进程,这就很令人头痛,到底是哪个呢?这时间突然同事说他在这台机器上自己手动部署了一个非Docker版本的ActiveMQ,因为要兼容其他厂商的程序,自己随手就部署了一台。还能这样干?我一下子就有点开悟,赶紧查了一下,确实ActiveMQ正在运行中。
难道说是ActiveMQ与RabbitMQ端口冲突? 我再一次执行了查看端口的命令
lsof -i :5672 | grep LISTEN
因为netstat用于显示TCP、UDP的端口和进程等相关情况,同时显示网络连接、路由表和网络接口等信息,可以让用户得知目前都有哪些网络连接正在运作。而lsof用于查看进程打开的文件,打开文件的进程,进程使用的端口号(TCP、UDP)等信息。
java 28586 root 130u IPv6 109362066 0t0 TCP *:amqp (LISTEN)
果然,发现进程正是AMQP协议占用了,RabbitMQ和ActiveMQ底层都使用了AMQP协议,5672端口是AMQP(Advanced Message Queuing Protocol)协议的默认端口,它是一种面向消息的中间件协议,被设计用于分布式应用程序中的消息通信。在ActiveMQ中的/data/apache-activemq-5.15.9/conf/activemq.xml目录下我们能看到对应的协议端口号。
关注公众号【可为编程】回复【面试】领取年度最新面试题大全!!!
这里我就总结一下RabbitMQ和ActiveMQ的区别:
1、协议支持
RabbitMQ和ActiveMQ都支持AMQP协议,但ActiveMQ还支持其他多种协议,如OpenWire、STOMP、MQTT等。这使得ActiveMQ具有更大的灵活性,可以与不同类型的客户端进行通信。
2、可靠性和可用性
RabbitMQ和ActiveMQ在可靠性和可用性方面有所不同。RabbitMQ使用持久化消息和确认机制来实现可靠性,基本上不丢失消息,消息的时间处理上处于微秒级,同时提供了主从复制和镜像队列来实现高可用性。ActiveMQ使用持久化消息和事务支持来实现可靠性,同时提供了主从复制和网络连接故障转移来实现高可用性,会丢失消息,消息的时间处理上处于毫秒级。
3、集群和扩展性
RabbitMQ和ActiveMQ都支持集群和扩展性。RabbitMQ使用Erlang语言的分布式特性来实现集群,可以水平扩展并提供负载均衡。ActiveMQ使用基于共享存储的主从复制来实现集群,可以通过添加更多的节点来扩展。
4、消息选择模式
RabbitMQ和ActiveMQ在消息选择模式上也有所不同。RabbitMQ使用发布-订阅模式和路由模式来选择消息的消费者。发布-订阅模式适用于一对多的消息传递,路由模式适用于根据消息的路由键进行选择。ActiveMQ使用点对点模式和发布-订阅模式来选择消息的消费者。点对点模式适用于一对一的消息传递,发布-订阅模式适用于一对多的消息传递。
5、使用场景
RabbitMQ适用于需要严格消息传递保证和灵活路由规则的场景,例如金融交易系统、订单处理系统等。ActiveMQ适用于需要多种协议支持和高可用性的场景,例如异步通信、消息中间件集成等。
总结
其实这件事本身是没有啥问题的,只不过他部署在开发环境,同一台机器上面了,因此导致消息中间件启动不起来,耽误了开发进度,被组长一顿批评。所以大家在做事情的时候一定要先上报,先问一下看对其他地方有没有影响,对其他组件有没有影响,别耽误大家整体的开发进度,而且两种MQ本身就存在相同端口,还是同事对MQ的使用和自身特性不太了解,才犯此错误。