ActiveMQ在电商项目(生产环境)的应用

一、概览

1. 本文目的:

   分析生产级别的电商项目,是怎么使用ActiveMQ的。

二、代码分析

1. Config:

   ① 基本参数

    amq.brokerURL=tcp://127.0.0.1:61616
    amq.userName=admin
    amq.password=admin
    amq.destination=weimei2.activemq
    amq.sessionCacheSize=100

   ② Bean的配置:主要配置JMS相关的ActiveMQ连接的工厂类、消息转换器、消息队列、监听器、队列模板。

    <bean id="jmsConnectionFactoryExtend" class="org.springframework.jms.connection.CachingConnectionFactory">
        <property name="targetConnectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                <property name="brokerURL" value="${amq.brokerURL}"/>
                <property name="userName" value="${amq.userName}"/>
                <property name="password" value="${amq.password}"/>
            </bean>
        </property>
        <property name="sessionCacheSize" value="${amq.sessionCacheSize}"/>
    </bean>
    
    <!-- converter -->
    <bean id="jmsMessageConverter"
          class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
          
    <!-- queue -->
    <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
        <constructor-arg ref="jmsConnectionFactoryExtend"/>
        <property name="pubSubDomain" value="false"/>
        <property name="messageConverter" ref="jmsMessageConverter"/>
    </bean>

    <!-- listener -->
    <bean id="jmsListenerContainerFactory"
          class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
        <property name="connectionFactory" ref="jmsConnectionFactoryExtend"/>
    </bean>

    <!-- template -->
    <bean id="jmsMessagingTemplate" class="org.springframework.jms.core.JmsMessagingTemplate">
        <property name="jmsTemplate" ref="jmsQueueTemplate"/>
    </bean>
2. Producer:

   ① 作用:把消息投送到注入的目的地。

    /**
     *生产者
     */
    @Component
    public class AMQProducer {
    
        @Autowired
        private JmsMessagingTemplate jmsMessagingTemplate;
    
        @Value("${amq.destination}")
        public String destination;
    
        public void sendMessage(Object payload, Map<String, Object> header) {
            jmsMessagingTemplate.convertAndSend(destination, payload, header);
        }
    
        public void sendMessage(String destination,Object payload, Map<String, Object> header) {
            jmsMessagingTemplate.convertAndSend(destination, payload, header);
        }
    }

   ② 业务应用:举例,用户取消订单后重新计算佣金接口。在后续介绍消费者工作原理时,会说明怎么消费这条消息。

 /**
  * 取消订单重新计算佣金,发送消息
  * @param orderId
  */
 private void reCalculateCommision(Long orderId){
     AMQProducer aMQProducer = (AMQProducer) ApplicationContextHelper.getBean("AMQProducer");
     //发送消息重新计算推广佣金
     Map<String,Object> header = new HashMap<>();
     header.put("bizType","COMMISION_RECALC");
     header.put("orderId",orderId);
     aMQProducer.sendMessage("",header);
 }

   :将消息生产投送到消息队列后,生产者的工作就算完成了。

3. Consumer:

   ① 利用JmsListener监听消息队列指定目的地的消息

/**
 * 消费者
 */
@EnableJms
@Component
@Slf4j
public class AMQConsumer {
    @Autowired
    ApplicationContext ctx;
    /**
     * 消息处理
     *
     * @param message
     */
    @JmsListener(containerFactory = "jmsListenerContainerFactory", destination = "${amq.destination}")
    public void onMessage(Message message) {
        log.error("========================进入消费者===========================>");
        Map<String, Handler> handlers = ctx.getBeansOfType(Handler.class);
        if (CollectionUtils.isEmpty(handlers)) {
            log.debug(" No message handler,activemq message discard.");
            return;
        }
        // 遍历所有的handlers,根据message类型匹配一个handler处理
        for (Map.Entry<String, Handler> entry : handlers.entrySet()) {
            Handler tHandler = entry.getValue();
            if (tHandler == null) {
                continue;
            }
            tHandler.handle(message);
        }
    }
}

   ② 消息处理接口,有多个实现类

/**
 * 消息处理接口
 */
public interface Handler {
    void handle(Message t) throws JMSException;
}

   ③ 消息处理具体业务方法(就是上文处理取消订单重新计算佣金消息的方法)

/**
 * 消费处理退单计算佣金方法
 */
@Override
    public void handle(Message t) throws JMSException {
        //消息类型不为退单重新佣金计算退出
        if (!HandlerConstants.MSG_BIZ_TYPE_COMMISION_RECALC.equals(t.getStringProperty(AMQConstants.BIZ_TYPE))) {
            return;
        }
        log.error("===================>进入重新计算佣金消费者进行消费======");
        //boss修改价格重新计算佣金
        String changePriceOrderIdStr = t.getStringProperty("changePriceOrderId");
        if(!Objects.isNull(changePriceOrderIdStr)){
            log.error("===================>boos修改价格重新计算佣金======");
            Long changePriceOrderId = t.getLongProperty("changePriceOrderId");
            //改价
            changePrice(changePriceOrderId);
        }
     }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值