1、下载mq http://activemq.apache.org/components/classic/download/

2、解压后在bin目录下 cmd 执行命令 activimq start 启动mq

3、浏览器访问http://localhost:8161/ 进入mq后台页面,默认账号为admin 密码为admin

4、点击 create 创建队列,创建俩个队列,一个订单队列,用于下单成功后通知发货系统,一个出仓队列,用于发货完成之后通知仓库系统

5、开始写代码,首先注入依赖,代码如下:

<!--springboot集成的mq依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!--消息队列连接池-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.0</version>
</dependency>
<!--springboot自带的mq工具-->
<dependency>
<groupId>org.messaginghub</groupId>
<artifactId>pooled-jms</artifactId>
<version>1.0.3</version>
</dependency>

6、增加mq的基本配置,打开yml文件,增加如下配置,代码如下:

ActiveMQ相关配置

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

不使用Spring Boot内部的ActiveMQ,连接我们自己的MQ服务器

in-memory: false

使用连接池

pool:
enabled: true

连接池最大连接数

max-connections: 100

空闲连接的过期时间,30秒

idle-timeout: 30000

是否采取订阅模式,false,先采取点对点模式

jms:
pub-sub-domain: false

7、在springboot的启动类中加入注解@EnableJms,表示启用mq

8、模拟创建一个下单业务,然后将订单信息发送到订单队列中,代码如下:

/**
* 向ActiveMQ推送消息
* @return 操作码
* */
@RequestMapping(value = "/push")
public Object pushMessage(){
    // 创建订单
Orders orders = new Orders();
orders.setOrderNo("T" + UUIDUtils.getOrderIdByUUId());
orders.setPayNo("P" + UUIDUtils.getOrderIdByUUId());
//点对点模式,将消息写入register-queue队列,若队列不存在会自动创建
messagingTemplate.convertAndSend("register-queue", JSONObject.toJSONString(orders));
//需要引入fastjson依赖
return JSON.parseObject("{\"message\":\"push a message success\",\"messageCode\":200}");
}

其中messagingTemplate对象需要注入,代码如下:

//注入Spring Boot自带的mq工具类
@Autowired private JmsMessagingTemplate messagingTemplate;

此业务处理完成之后,我们会看到mq的register-queue队列中出现了一条消息

9、接下来我们去写发货系统,发货系统需要做的事情是,拿到订单队列的订单信息,根据这个信息去处理发货(更新订单状态为出仓中等业务)

10、发货处理完成之后,我们需要将要出仓的商品信息发送到出仓队列中,等待出仓队列去处理,发货代码如下:

import com.alibaba.fastjson.JSONObject;
import com.example.pay.domain.Goods;
import com.example.pay.domain.Orders;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;

/**
* 类名: ActiveMQListener
* 功能: 队列消息监听,听到即消费
* 创建日期: 2020/3/15 0015 14:21
* 说明:
*/
@Component
public class ActiveMQListener {

/**
* 将反馈信息写入到return-register队列,供生产者回调
* @return 返回给生产者的信息
* */
@JmsListener(destination = "register-queue") // 监听register-queue队列
@SendTo("return-register") // 发送消息给return-register队列
public Object listenQueue(String message){
Orders orders = JSONObject.parseObject(message, Orders.class);
System.out.println("【发货系统】 获取到订单的订单号为:" + orders.getOrderNo());
Goods goods = new Goods();
goods.setGoodId(2);
goods.setGoodSub(orders.getPayNo());
System.out.println("【发货系统】 已开始处理发货流程");
goods.setGoodDesc("【发货系统】 已处理完成,请求出仓");
return JSONObject.toJSONString(goods);
}
}

此时,出仓队列中就有了一条要出仓的商品等信息,注意:我们的发货业务是在项目启动时就在监听订单队列的

11、此时出仓系统监听到了出仓队列中的信息,那么我们去拿到信息后,去处理出仓,代码如下:

/**
* 此方法用于接收消费者、订阅者的反馈,比如返回是否执行成功,再决定其他的提交、回滚、重试操作
* */
@JmsListener(destination = "return-register")
public void returnMsgOne(String message){
Goods goods = JSONObject.parseObject(message, Goods.class);
System.out.println(goods.getGoodDesc());
System.out.println("【仓库系统】 已收到" + goods.getGoodSub() + "号的出仓请求");
System.out.println("【仓库系统】 已出仓");
}

此时我们的这一流程就已经走完了,如出仓后还有后续操作,那么可以继续去增加对应的队列,去发送、接收消息,处理对应的信息
当然也可以如注释当中所写的,A队列用于业务数据传输,B队列只作为反馈成功与否信息传输,根据自己的业务去设计队列的使用。

12、启动、运行,结果如下:

【发货系统】 获取到订单的订单号为:T2105236649
【发货系统】 已开始处理发货流程
【发货系统】 已处理完成,请求出仓
【仓库系统】 已收到P2141432032号的出仓请求
【仓库系统】 已出仓