ActiveMQ 简介

Apache 下的开源消息队列中间件

功能

  1. ActiveMQ 是消息队列技术,为解决高并发问题而生
  2. ActiveMQ 生产者消费者模型(生产者和消费者可以跨平台、跨系统)
  3. ActiveMQ 支持如下两种消息传输方式
    a.点对点模式,生产者生产了一个消息,只能由一个消费者进行消费
    b.发布/订阅模式,生产者生产了一个消息,可以由多个消费者进行消费

基本概念

ActiveMQ 支持两种消息队列模式

  1. 点对点(point to point, queue)
  2. 发布/订阅(publish/subscribe,topic)

两者最大的差别在于 是否能重复消费

Queue

点对点:Queue,不可重复消费

消息生产者生产消息发送到 queue 中,然后消息消费者从 queue 中取出并且消费消息。

消息被消费以后,queue 中不再有存储,所以消息消费者不可能消费到已经被消费的消息。

Queue 支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费、其它的则

不能消费此消息了。

当消费者不存在时,消息会一直保存,直到有消费者消费

activemq官网下载 active mq_docker

Topic

发布/订阅:Topic,可以重复消费

消息生产者(发布)将消息发布到 topic 中,同时有多个消息消费者(订阅)消费该消息。

和点对点方式不同,发布到 topic 的消息会被所有订阅者消费。

当生产者发布消息,不管是否有消费者。都不会保存消息

activemq官网下载 active mq_spring_02


Jms 规范里的两种 message 传输方式 Topic 和 Queue,两者的对比如下表:

activemq官网下载 active mq_activemq官网下载_03

activemq官网下载 active mq_点对点_04

安装(docker)

基于 dockers 的容器化搭建,前提主机安装 docker

搜索镜像

docker search activemq

activemq官网下载 active mq_activemq官网下载_05

下载镜像

docker pull webcenter/activemq

查看镜像

docker images

activemq官网下载 active mq_点对点_06

启动容器

docker run -d --name activemq -p 61616:61616 -p 8161:8161 docker.io/webcenter/activemq

映射端口 61616, 8161

测试

http://ip:8161/admin/

默认密码 admin

如下为启动成功

activemq官网下载 active mq_activemq官网下载_07

查看 queue

activemq官网下载 active mq_点对点_08


队列消息名,队列中的待处理消息数,消费者数量,历史消息数,历史处理消息数

查看 topic

activemq官网下载 active mq_activemq官网下载_09


发布的消息名,消费者数量,历史消息数,收到发布消息的数量

JAVA API 操作

样例为 springboot 下整合 activemq,将商品信息同步索引库的消息塞入 queue 中,使用点
对点的方式处理消息

pom 依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
//topic 模式
<dependency>
	<groupId>org.apache.activemq</groupId>
	<artifactId>activemq-pool</artifactId>
	<version>5.15.0</version>
</dependency>

application.yml 配置

spring:
	activemq:
		broker-url: tcp://172.16.23.195:61616

Java 代码

消息生产者

创建一个同步索引的消息,并将消息塞入 queue 队列

@Autowired
private JmsTemplate jmsTemplate;
private Destination destination;
destination = new ActiveMQQueue("item.sync");
jmsTemplate.send(destination, new MessageCreator() {
	@Override
	public Message createMessage(Session session) throws JMSException {
		TextMessage textMessage =
		session.createTextMessage(type+","+String.valueOf(id));
		return textMessage;
	}
});

消息消费者

// 使用 JmsListener 配置消费者监听的队列,其中 message 是接收到的消息
@JmsListener(destination = "item.sync")
public void onMessage(Message message) {
try {
	//从消息中取商品 id
	TextMessage textMessage = (TextMessage) message;
	log.info("得到消息:"+textMessage.getText());
	String[] text = textMessage.getText().split(",");
	Long itemId = new Long(text[1]);
	//等待事务提交
	Thread.sleep(1000);
	//更新索引
	....业务代码

实现效果

先去前台查询商品,我们输入 r,但是没有查到任何商品

activemq官网下载 active mq_docker_10


编辑商品,修改了某个商品名,增加了 r 这个字母

activemq官网下载 active mq_点对点_11


编辑商品后调用消息生产者往queue里插入消息,将新的商品名索引同步消息插入,pending

message 和 enqueued 都有新增

activemq官网下载 active mq_docker_12


等一会再刷新页面,发现 pending 为 0,dequeued 增加到和 enqueued 相同,说明队列消

息已经被消费者处理完成

activemq官网下载 active mq_点对点_13


再查询前台可以看到索引库更新成功

activemq官网下载 active mq_docker_14