既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
复制代码
注册服务
ln -s /opt/activemq/bin/activemq /etc/init.d/activemqchkconfig --add activemq
复制代码
启动服务
service activemq start
![](https://img-blog.csdnimg.cn/img_convert/df8b0c25fd4611d2bdf25f581133ea2b.png)
关闭服务
service activemq stop
通过 netstat 查看端口
![](https://img-blog.csdnimg.cn/img_convert/129ba585ace83982cebf9c00ee2ee6a5.png)
activemq 两个重要的端口,一个是提供消息队列的默认端口:61616
另一个是控制台端口 8161
通过控制台测试
启动消费端
![](https://img-blog.csdnimg.cn/img_convert/009e7b3df416fefa91979abda5b5cce3.png)
进入网页控制台
![](https://img-blog.csdnimg.cn/img_convert/355cd88f90364f0ec72e144b0b305090.png)
**账号/密码默认: admin/admin**
**点击 Queues**
![](https://img-blog.csdnimg.cn/img_convert/04cc9cb1edb98c244bb54c77eeb918b8.png)
![](https://img-blog.csdnimg.cn/img_convert/7176e89fe44e5e6aecb5a2180f92ad1a.png)
![](https://img-blog.csdnimg.cn/img_convert/720e8aad72bbc1ae0c3bfc6c36abec6c.png)
**观察客户端**
![](https://img-blog.csdnimg.cn/img_convert/654e4c976013362687253fdab3f97cd7.png)
#### 在 Java 中使用消息队列
**3.1 在 gmall-service-util 中导入依赖坐标**
org.springframework.bootspring-boot-starter-activemqorg.slf4jslf4j-log4j12org.apache.activemqactivemq-pool5.15.2org.slf4jslf4j-log4j12
复制代码
**3.2 producer 端**
public static void main(String[] args) {ConnectionFactory connect = new ActiveMQConnectionFactory(“tcp://192.168.67.163:61616”);try {Connection connection = connect.createConnection();connection.start();//第一个值表示是否使用事务,如果选择true,第二个值相当于选择0Session session = connection.createSession(true, Session.SESSION_TRANSACTED);Queue testqueue = session.createQueue(“TEST1”);MessageProducer producer = session.createProducer(testqueue);TextMessage textMessage=new ActiveMQTextMessage();textMessage.setText(“今天天气真好!”);producer.setDeliveryMode(DeliveryMode.PERSISTENT);producer.send(textMessage);session.commit();connection.close();} catch (JMSException e) {e.printStackTrace();}}
复制代码
**3.3 consumer**
public static void main(String[] args) {ConnectionFactory connect = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD,“tcp://192.168.67.163:61616”);try {Connection connection = connect.createConnection();connection.start();//第一个值表示是否使用事务,如果选择true,第二个值相当于选择0Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);Destination testqueue = session.createQueue(“TEST1”);MessageConsumer consumer = session.createConsumer(testqueue);consumer.setMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message) {if(message instanceof TextMessage){try {String text = ((TextMessage) message).getText();System.out.println(text);//session.rollback();} catch (JMSException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}});}catch (Exception e){e.printStackTrace();}}
复制代码
**3.4 关于事务控制**
![](https://img-blog.csdnimg.cn/img_convert/b8a65ed84cd2637542247b7f2b40a081.png)
**3.5 持久化与非持久化**
**通过** producer.setDeliveryMode(DeliveryMode.***PERSISTENT***) 进行设置
持久化的好处就是当 activemq 宕机的话,消息队列中的消息不会丢失。非持久化会丢失。但是会消耗一定的性能。
#### 四 与 springboot 整合
**1 配置类 ActiveMQConfig**
@Configurationpublic class ActiveMQConfig {@Value(“ s p r i n g . a c t i v e m q . b r o k e r − u r l : d i s a b l e d " ) S t r i n g b r o k e r U R L ; @ V a l u e ( " {spring.activemq.broker-url:disabled}")String brokerURL ;@Value(" spring.activemq.broker−url:disabled")StringbrokerURL;@Value("{activemq.listener.enable:disabled}”)String listenerEnable;@Beanpublic ActiveMQUtil getActiveMQUtil() throws JMSException {if(brokerURL.equals(“disabled”)){return null;}ActiveMQUtil activeMQUtil=new ActiveMQUtil();activeMQUtil.init(brokerURL);return activeMQUtil;}//定义一个消息监听器连接工厂,这里定义的是点对点模式的监听器连接工厂@Bean(name = “jmsQueueListener”)public DefaultJmsListenerContainerFactory jmsQueueListenerContainerFactory(ActiveMQConnectionFactory activeMQConnectionFactory ) {DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();if(!listenerEnable.equals(“true”)){return null;}factory.setConnectionFactory(activeMQConnectionFactory);//设置并发数factory.setConcurrency(“5”);//重连间隔时间 factory.setRecoveryInterval(5000L);factory.setSessionTransacted(false);factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);return factory;}@Beanpublic ActiveMQConnectionFactory activeMQConnectionFactory ( ){ActiveMQConnectionFactory activeMQConnectionFactory =new ActiveMQConnectionFactory( brokerURL);return activeMQConnectionFactory;}}
复制代码
#### 2 工具类 ActiveMQUtil
public class ActiveMQUtil {PooledConnectionFactory pooledConnectionFactory=null;public ConnectionFactory init(String brokerUrl) {ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerUrl);//加入连接池pooledConnectionFactory=new PooledConnectionFactory(factory);//出现异常时重新连接pooledConnectionFactory.setReconnectOnException(true);//pooledConnectionFactory.setMaxConnections(5);pooledConnectionFactory.setExpiryTimeout(10000);return pooledConnectionFactory;}public ConnectionFactory getConnectionFactory(){return pooledConnectionFactory;}}
复制代码
#### 五 在支付业务模块中应用
**1 支付成功通知**
支付模块利用消息队列通知订单系统,支付成功
在支付模块中配置 application.properties
spring.activemq.broker-url=tcp://mq.server.com:61616
复制代码
在 PaymentServiceImpl 中增加发送方法:
public void sendPaymentResult(String orderId,String result){ConnectionFactory connectionFactory = activeMQUtil.getConnectionFactory();Connection connection=null;try {connection = connectionFactory.createConnection();connection.start();Session session = connection.createSession(true, Session.SESSION_TRANSACTED);Queue paymentResultQueue = session.createQueue(“PAYMENT_RESULT_QUEUE”);MapMessage mapMessage=new ActiveMQMapMessage();mapMessage.setString(“orderId”,orderId);mapMessage.setString(“result”,result);MessageProducer producer = session.createProducer(paymentResultQueue);producer.send(mapMessage);session.commit();
复制代码
producer.close();session.close();connection.close();} catch (JMSException e) {e.printStackTrace();}}
复制代码
在 PaymentController 中增加一个方法用来测试
@RequestMapping(“sendResult”)@ResponseBodypublic String sendPaymentResult(@RequestParam(“orderId”) String orderId){paymentService.sendPaymentResult(orderId,“success” );return “has been sent”;}
复制代码
在浏览器中访问:
![](https://img-blog.csdnimg.cn/img_convert/69c69551b76f21a80265e3ca588bcc44.png)
查看队列内容:有一个在队列中没有被消费的消息。
![](https://img-blog.csdnimg.cn/img_convert/ee899c1289887e02a7669600c9d89480.png)
![](https://img-blog.csdnimg.cn/img_convert/32b2c845dd50a33320305cad821a5893.png)
![](https://img-blog.csdnimg.cn/img_convert/492ff15c2117f872f594025540a80de8.png)
**2 订单模块消费消息**
application.properties
spring.activemq.broker-url=tcp://mq.server.com:61616activemq.listener.enable=true
复制代码
订单消息消息后要更新订单状态,先准备好订单状态更新的方法
public void updateProcessStatus(String orderId , ProcessStatus processStatus, Map<String,String>… paramMaps) {OrderInfo orderInfo = new OrderInfo();orderInfo.setId(orderId);orderInfo.setOrderStatus(processStatus.getOrderStatus());orderInfo.setProcessStatus(processStatus);//动态增加需要补充更新的属性if (paramMaps != null && paramMaps.length > 0) {Map<String, String> paramMap = paramMaps[0];for (Map.Entry<String, String> entry : paramMap.entrySet()) {String properties = entry.getKey();String value = entry.getValue();try {BeanUtils.setProperty(orderInfo, properties, value);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}orderInfoMapper.updateByPrimaryKeySelective(orderInfo);}
复制代码
消息队列的消费端
@JmsListener(destination = “PAYMENT_RESULT_QUEUE”,containerFactory = “jmsQueueListener”)public void consumePaymentResult(MapMessage mapMessage) throws JMSException {String orderId = mapMessage.getString(“orderId”);String result = mapMessage.getString(“result”);if(!“success”.equals(result)){orderService.updateProcessStatus( orderId , ProcessStatus.PAY_FAIL);}else{orderService.updateProcessStatus( orderId , ProcessStatus.PAID);} orderService.sendOrderResult(orderId);}
复制代码
**3 订单模块发送减库存通知**
订单模块除了接收到请求改变单据状态,还要发送库存系统
查看看《库存管理系统接口手册》中【**减库存的消息队列消费端接口**】中的描述,组织相应的消息数据进行传递。
@Transactionalpublic void sendOrderResult(String orderId){OrderInfo orderInfo = getOrderInfo(orderId);Map<String, Object> messageMap = initWareOrderMessage(orderInfo);String wareOrderJson= JSON.toJSONString(messageMap);Session session = null;try {Connection conn = activeMQUtil.getConnection();session = conn.createSession(true, Session.SESSION_TRANSACTED);Queue queue = session.createQueue(“ORDER_RESULT_QUEUE”);MessageProducer producer = session.createProducer(queue);TextMessage message =new ActiveMQTextMessage();message.setText(wareOrderJson);producer.send(message);updateProcessStatus(orderInfo.getId(), ProcessStatus.NOTIFIED_WARE);session.commit();producer.close();conn.close();} catch (JMSException e) {e.printStackTrace();}}
复制代码
针对接口手册中需要的消息进行组织
public Map<String,Object> initWareOrderMessage( OrderInfo orderInfo ) {//准备发送到仓库系统的订单String wareId = orderInfo.getWareId();HashMap<String, Object> hashMap = new HashMap<>();hashMap.put(“orderId”, orderInfo.getId());hashMap.put(“consignee”, orderInfo.getConsignee());hashMap.put(“consigneeTel”, orderInfo.getConsigneeTel());hashMap.put(“orderComment”, orderInfo.getOrderComment());hashMap.put(“orderBody”, orderInfo.getOrderSubject());hashMap.put(“deliveryAddress”, orderInfo.getDeliveryAddress());hashMap.put(“paymentWay”, “2”);//1 货到付款 2 在线支付hashMap.put(“wareId”,wareId);List<HashMap<String, String>> details = new ArrayList<>();List orderDetailList = orderInfo.getOrderDetailList();for (OrderDetail orderDetail : orderDetailList) {HashMap<String, String> detailMap = new HashMap<>();detailMap.put(“skuId”, orderDetail.getSkuId());detailMap.put(“skuNum”, “” + orderDetail.getSkuNum());detailMap.put(“skuName”, orderDetail.getSkuName());details.add(detailMap);}hashMap.put(“details”, details);return hashMap;}
复制代码
**4 消费减库存结果**
给仓库系统发送减库存消息后,还要接受减库存成功或者失败的消息。
![img](https://img-blog.csdnimg.cn/img_convert/ee68946984b928c00074dcef42ef97de.png)
![img](https://img-blog.csdnimg.cn/img_convert/731089419de727b7b41389e3e5c6f82d.png)
![img](https://img-blog.csdnimg.cn/img_convert/c112d6846bf53fe47ce7fc9660354553.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**
OCRfrUP-1715631748349)]
[外链图片转存中...(img-TAYj3TAZ-1715631748349)]
[外链图片转存中...(img-fucljYam-1715631748349)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**