学习服务之间的调用,三个方法的演化

2019/04/10 10:10
阅读数 36

<h3>场景</h3> 业务场景:下单时扣减库存,由于比较简单,商品和库存都放到了一个上下文中 ![](https://img2018.cnblogs.com/blog/1297333/202002/1297333-20200228161951357-200947944.png) 学习多个上下文之间的交互,协作,订单上下文生成订单时,扣减商品上下文中的库存 <h3>第一个方法</h3> 第一个方法的技术选型,Redis,WebApiClient,EF CORE, Polly, ExceptionLess,雪花算法 把商品的库存放到redis中,在redis中验证库存,redis中扣减库存,生成订单后使用WebApiClient调用商品上下文中扣减库存的接口 问题: 1,在redis中验证库存,扣减库存时,需要加上Look,多线程时,获取redis中的库存时不加锁获取的库存可能不正确 2,确保WebApiClient调用接口能成功,使用polly 如果掉接口异常,失败时,重试,重试过程中记录异常,和重试的次数,并发出通知。 3,性能不强,EF core 需要持久化订单的数据,使用WebApiClient调用商品上下文中的接口有网络开销 4,WebApiClient请求异常,失败时,Polly会进行重试,出现多次调用的问题,商品上下文接口必须做幂等 5,如何保证不超卖,执行扣减库存修改语句是带上库存必须大于0的条件 <h3>第二个方法</h3> 第二个方法的技术选型,Redis,CAP,Rabbitmq,EF CORE, Polly,ExceptionLess,雪花算法 把商品的库存放到redis中,在redis中验证库存,redis中扣减库存,生成订单时开启事务,使用CAP来发送消息到EventBus,商品上下文订阅,扣减库存 问题: 1,如果保证消息不丢,使用CAP,CAP是基于本地消息表的方式来实现的组件,发送消息和消费消息都已本地事务的方式记录了发送和消费的情况,如果失败 会进行重试,重试一定的次数,可以人工干预解决问题,也可以做补偿事件, 2,订阅消息时可能出现异常,CAP会进行重试,同一消息会出现多次消费的问题,商品上下文接口必须做幂等 3,CAP在发送,消费消息时都会已本地事务的方式,写入一条信息到数据库表中,进行了2次IO的交付 <h3>第三个方法</h3> 第三个方法的技术选型,Redis,Rabbitmq,CAP,EF CORE, Polly,ExceptionLess,雪花算法 之前看过一句话,<code style="color:red">读多写少用缓存,写多读少用队列</code>,我们可能使用队列来提高我们的处理能力,队列可以堆积消息,所以要使用消息队列 使用CommandService来发送Command,DomainEventService来发送事件,CAP具有EventBus的功能,但是多了2次IO的交互,使用自己简单封装Rabbitmq来写CommandService 事件会改变我们系统的状态,代表已经发生过的事实,比较重要,为了确保安全选择了CAP 当前端调用我们接口时在Controller中使用CommandService发送command到EventBus,commandHandler订阅消息,在redis中验证库存,redis中扣减库存,生成订单时开启事务 使用DomainEventService来发送消息到EventBus,商品上下文订阅,扣减库存 问题: 1,CommandService的实现,参考Rabbitmq官网的demo以及文档,参考CAP源码 2,使用队列后,没有获取到返回值,通过记录日志,查看消息的消费情况 3,大大增强了框架的复杂性,查错比较复杂 4,Rabbitmq没有使用集群,web也没有使用集群,数据没有集群,目前对于集群的学习比较浅

原文出处:https://www.cnblogs.com/lifeng618/p/12378067.html

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部