设为首页 加入收藏

TOP

微服务架构-利用事件驱动实现最终一致性(二)
2019-10-09 11:15:08 】 浏览:105
Tags:服务 架构 利用 事件 驱动 实现 最终 一致性
ssage message, Session session){ try { if (message instanceof ActiveMQObjectMessage){ MqStockMsg result = new MqStockMsg(); ActiveMQObjectMessage objectMessage=(ActiveMQObjectMessage)message; MqOrderMsg msg = (MqOrderMsg)objectMessage.getObject(); Integer updateCount = stockMapper.updateNumByStockId(msg.getStockId(),msg.getGoodCount()); if (updateCount >= 1){ result.setSuccess(true); result.setOrderId(msg.getId()); }else { result.setSuccess(false); } // 手动ack,使消息出队列,不然会不断消费 message.acknowledge(); // 发送库存锁定消息到MQ jmsProducer.sendStockLockedMsg(result); } } catch (JMSException e) { log.error("接收订单创建消息报错:"+e.getMessage()); } }

仔细的朋友可能会看到:message.acknowledge(),即手动确认消息。因为在保证库存服务的逻辑能正常执行后再确认消息已消费,可以保证消息的投递可靠性,万一在库存服务执行时报出异常,我们可以做到重新消费该下单消息。
3、订单服务接收到Stock Locked事件,将订单的状态改为“已确认”
Order Change
代码:

/**
 * 判断是否还有库存,有库存更新订单状态为1,无库存更新订单状态为2,并且通知用户(WebSocket)
 * @param message
 */
@JmsListener(destination = STOCK_LOCKED,containerFactory = "myListenerContainerFactory")
@Transactional(rollbackFor = Exception.class)
public void receiveStockLockedMsg(Message message, Session session){
    try {
        if (message instanceof ActiveMQObjectMessage){
            ActiveMQObjectMessage objectMessage=(ActiveMQObjectMessage)message;
            MqStockMsg msg = (MqStockMsg)objectMessage.getObject();
            if (msg.isSuccess()){
                Order updateOrder = new Order();
                updateOrder.setId(msg.getOrderId());
                updateOrder.setOrderStatus(1);
                orderMapper.updateByPrimaryKeySelective(updateOrder);
                log.info("订单【"+msg.getOrderId()+"】下单成功");
            }else {
                Order updateOrder = new Order();
                updateOrder.setId(msg.getOrderId());
                updateOrder.setOrderStatus(2);
                orderMapper.updateByPrimaryKeySelective(updateOrder);
                // 通知用户库存不足,订单被取消
                log.error("订单【"+msg.getOrderId()+"】因库存不足被取消");
            }
            // 手动ack,使消息出队列,不然会不断消费
            message.acknowledge();
        }
    } catch (JMSException e) {
        log.error("接收库存锁定消息报错:"+e.getMessage());
    }
}

同样,这里我们也是会利用手动确认消息来保证消息的投递可靠性。
至此,已经全部搞定了。我们看一下和正常的服务调用对比如何:

1、订单服务不再直接依赖于库存服务,而是将下单事件发送到MQ中,让库存监听。
2、订单服务能真正的作为一个模块独立运行。
3、解决了并发问题,而且MQ的队列处理效率非常的高。

但是也存在下面的问题:

1、用户体验改变了:因为使用事件机制,订单是立即生成的,可是很有可能过一会,系统会提醒你没货了。。这就像是排队抢购一样,排着排着就被通知没货了,不用再排队了。
2、数据库可能会存在很对没有完成下单的订单。

最后,如果真的要考虑用户体验,并且不想数据库存在很多不必要的数据,该怎么办?
那就把订单服务和库存服务聚合在一起吧。解决当前的问题应当是首先要考虑的,我们设计微服务的目的是本想是解决业务并发量。而现在面临的却是用户体验的问题,所以架构设计也是需要妥协的。
最主要是,我们是经过思考和分析的,每个方案能做到哪种程度,能应用到哪种场景。正所谓,技术要和实际场景结合,我们不能为了追求新技术而生搬硬套。

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇设计模式-行为型-迭代器模式 下一篇设计模式-行为型-模板模式

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目