node使用ActiveMQ

1. 和ActiveMQ的缘分

之前也断断续续使用一些第三方IM SDK,也听说过心跳包和socketIO之类的东西。

维护时间较长的就是socket项目就是node中间层里面,使用到了ActiveMQ,至于原因是:中间层融合了多个后台,向前端提供统一的接口。其中一个后台,是比较靠近底层,类似于统一数据平台。所以每次它那边更新数据以后,中间层这边也要同步更新(且该平台每次数据更新,其它几个平台数据也需要跟着更新)。

技术总监一开始提议使用ActiveMQ。因为公司java后台项目通知java后台项目更新数据,利用的都是ActiveMQ。不过因为一开始没有使用过,担心会对项目产生什么影响,所以提出了几个骚操作:① 统一平台那边来写接口,直接操作node中间层的mongodb数据库就可以,但是那边的同事说这样很麻烦。②后来又说他那边来调用我的接口,但是他还要也要做特殊处理。不过第② 种作为了一种备选方案。

而中间层这边更新数据,需要通知统一平台的时候,则采用了中间层在操作mognodb数据的同时,调用统一平台相关接口的方案。

2. 初识ActiveMQ

2.1 下载

ActiveMQ官网下载,可以看到node的下载

在这里插入图片描述

2.2 STOMP协议的简单了解

上图可以看到,供node使用的activemq 版本是 STOMP 协议( Protocol)的。之前写过一篇http1.1 和http2 和 ServiceWorker 里面有提及如何通过f12的network 查看接口的Protocol。 http协议可能听说过,那么stomp协议是什么呢?
图片来源
在这里插入图片描述
图片来源
在这里插入图片描述
这里不做过多网络协议方面的探讨,可以简单理解stomp是一种通信协议。同时注意61616和61613这2个端口

2.3 Queue和Topic

在这里插入图片描述从上面的下载页截图上可以看到。有4个链接:2个发送,2个接受。中间层node项目作为数据接受方,选择Receive,那么选择Queue还是Topic呢。先来看下这2个分别是什么

Queue (点对点)支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费、其它的则不能消费此消息了。当消费者不存在时,消息会一直保存,直到有消费消费

图片来源
在这里插入图片描述
通过和后台沟通后得知,公司项目activemq统一使用的都是 Queue。 点击Receive Queue 进去可看到有一个简单的小demo在这里插入图片描述

2.4 stompit项目文档

官网的demo过于简单,可以查看
stompit的npm地址
stompit的github地址
如果觉得还不够详细,可以查看
stompit手册

项目则通过npm 下载即可
在这里插入图片描述

3. 线上出现问题

在本地和测试环境,测试的时候,没有什么问题。但是上线以后,却出现了2个大问题

3.1 无法连接

上线以后通过pm2 restart项目的时候发现,项目启动不了,查看pm2 logs 发现 mq一直连接不上。

在2.1 的图里面可以看到,activemq的node版和java版本的协议和接口是不一样的。在2.2 的图里面可以看到,activemq默认端口是61616和61613

java使用的activemq端口是默认的61616端口。
而node使用使用的activemq端口是默认的61613端口

最后在运维(已离职)的帮助下,启动成功
在这里插入图片描述

3.2 消费者莫名其妙

3.2.1 莫名消失

启动成功以后,通过activemq监控台,发现node消费者过一段时间自己就消失了。node这边也没有收到断开消息,不过mq那边有重连日志。即mq 消费者变为0,而客户端没有接收到通知的问题。

WARN | Transport Connection to: tcp://xxxx:xxxfailed: java.net.SocketException: 连接超时 (Read failed) | org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ Transport: tcp:///xxxx:xxx@61613

node这边也有重连,但是因为重连是写在断开回调里面的。所以没有监听到断开,自然也没有执行重新。更诡异的是,在测试的时候发现,白天一般半小时消费者就没有了。而晚上一般一晚上都不会断开,18点下班的时候重启项目后,等早上8点才断开???? 这东西是上的夜班???

3.2.2 莫名增加,拒不消失

更更诡异的是 偶尔多出几个消费者,疑似中间层没有关闭干净 (有时候即使关闭中间层了,消费者还是有一个,而且这个消费者可以正常消费消息)。

3.2.3 查询资料

通过查询资料,了解了一些activemq消息的知识
图片来源
在这里插入图片描述
图片来源
在这里插入图片描述
图片来源
在这里插入图片描述
在这里插入图片描述

3.2.4 ActiveMQ的配置问题

发现有几篇文章提到消费者消失或自动断开是 ActiveMQ InactivityMonitor的问题:
使用ActiveMQ遇到了一个监听器方式的消费者一段时间会自动断开连接的问题

连接到activemq artemis时使用nodejs stompit的连接超时

配置网管.Stomp

但是运维和java的同事说,ActiveMQ的配置都是默认的。没有动过。过滤到修改配置牵涉项目很广,所以就放弃了尝试

3.2.6 莫名消失的解决

由于一开始参考的是activemq 官方的简易demo,加之后期不细心(非常不细心)。所以项目其实没有配置heart-beat
图片来源
在这里插入图片描述
在这里插入图片描述

从官方的说明来看,在 ActiveMQ 5.9.0 之前客户端如果没有配置heart-beat 是无法成功连接的。但是公司项目使用的5.14版本。所以不配置也没有什么问题。所以在项目里面配置heart-beat,也不好使

最后经过调试,发现和大部分文章里面提及的不同的是 当我配置heart-beart的y=0的时候,消费者就不会莫名消失了。

'heart-beat': '6000, 0',

图片来源
在这里插入图片描述
所以我测试问题的最终根源是activemq生产者 会接受消费者的 mq心跳,但是不会返回给消费者,或者可以理解为我们配置的接受心跳的参数不对,可能短了。

后来我循环java同事,他们没有配置过项目的心跳,都是使用默认的。 且从项目后期稳定性来说,已经运行1年多了,也再没有出现过消费者消失的现象。

只所以会尝试设置y=0,是因为在github上有一篇issue 和我这个问题类似,如何确保客户端断开连接
在这里插入图片描述
在这里插入图片描述

3.2.7 莫名增加,拒不消失的解决

关于消费者莫名增加,关闭消费者项目后,消费者仍然存在的问题。我问了java同事,他说java项目里面一般默认都设有连接池(ChannelPool)。在连接很多的情况下,连接池会自动处理的。 所以根据stompit手册.ChannelPool 的配置也使用了连接池。

项目重启了,问题得到了解决。java牛逼,java666

3.3 内存不足

在项目稳定 以后,还有一个小插曲。

由于node 使用activemq ,使用的是61613端口。所以有一些本地部署的时候,需要开通61613端口。又因为中间层项目和某个后台java项目放在一个服务器上面。所以偶尔java同事会不同意开该端口。 所以只能使用之前说的统一平台调用中间层接口的s方法。
在这里插入图片描述

3.4 感慨

node 比起老3p(jsp,asp,php)还是有点不成熟。特别是在一些基础建设方面。node的确不是银弹

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在Spring Boot中使用ActiveMQ,你需要添加ActiveMQ的依赖项并配置相关的参数。下面是使用ActiveMQ的步骤: 1. 首先,在`pom.xml`文件中添加ActiveMQ的依赖项: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> ``` 2. 在`application.properties`(或`application.yml`)文件中配置ActiveMQ的连接信息,例如: ```properties spring.activemq.broker-url= tcp://localhost:61616 spring.activemq.user= admin spring.activemq.password= password ``` 根据你的实际情况修改上述参数。 3. 创建一个消息生产者,发送消息ActiveMQ队列或主题。示例代码如下: ```java import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Component; import javax.jms.Queue; @Component public class MessageProducer { private final JmsTemplate jmsTemplate; private final Queue queue; public MessageProducer(JmsTemplate jmsTemplate, Queue queue) { this.jmsTemplate = jmsTemplate; this.queue = queue; } public void sendMessage(String message) { jmsTemplate.convertAndSend(queue, message); } } ``` 你可以使用`JmsTemplate`来发送消息到队列。 4. 创建一个消息消费者,从ActiveMQ队列或主题接收消息。示例代码如下: ```java import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class MessageConsumer { @JmsListener(destination = "myQueue") public void receiveMessage(String message) { System.out.println("Received message: " + message); } } ``` 使用`@JmsListener`注解来监听指定的队列,并在接收消息时执行对应的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值