Java架构-如何设计实现真正的响应式微服务系统?( 二 )


异步和非堵塞能够降低共享资源比如数据库表等的竞争,避免大量使用事务机制造成的死锁和数据库连接池耗尽 。
使用异步和非堵塞,会降低快速访问冲击缓慢的后端系统,比如大量的并行峰值访问会立即打趴巍峨的ORacle数据库 。在一个大型系统在,存在各种不同处理效率的子系统,如何在快与慢之间协调,异步系统往往扮演重要的协调身份 。
引入了响应式编程可以帮助处理好一台机器内多线程问题,而响应式系统则是带给我们多台机器之间的分布式协调高效处理,实现弹性和伸缩性 。
响应式系统是基于异步消息传递,能够在空间和时间两个维度上解耦 。能够实现从CPU核到Socket 到容器到服务器到数据中心的透明化处理方式 。
真正微服务系统应该是响应式编程+响应式系统,每个微服务都需要被设计为一个分布式的微系统,
首先,将无状态行为从有状态的实体中分离出来,形成命令或事件,事件代表行为,实体代表结构,这样行为和结构才能分别各自扩展伸缩 。因为扩展无状态行为比扩展有状态的实体要容易得多 。
基于事件的持久化
JIM Gray说:覆盖式更新(update-in-place)是设计师是原罪,它违反了传统几百年来的会计记账实践 。
Pat Helland说:真相是日志Log,数据库只是日志子集的缓存 。
对于建立一种可伸缩的持久存储系统来说,事件日志才是正道 。
CRUD增删改查已经死了,只能留下增读两个操作CR,更新和删除UD应该放入坟墓 。
事件溯源Event Sourcing是一种CR,通过事件建模,能够让你注重系统中的来龙去脉,时间成为系统关键因素 。
通过事件日志记录事件按时间发生的顺序,一旦发生事件就不断新增追加到事件日志,其他使用者只要根据时间顺序不断读取这些事件,再执行这些事件代表的动作,事件代表因,事件执行后自然会产生结果 。
同时,事件日志避免了面向对象和关系数据库的不匹配阻抗问题 。让对象归对象,让数据库归数据库,
对象用于命令执行写操作,而数据库用于查询读操作,通过CQRS分离读写操作 。使用事件日志同步读写两个系统的数据 。
如何协调不同聚合之间的交互呢?通过事件驱动的工作流,比如有三个聚合:订单、支付和库存,下订单时,需要支付系统支付钞票,然后从库存出货,其中交互流程是这样:
1. 开始订单处理
2. 订单系统发出保留订购商品的命令给库存系统
3. 库存系统接受命令后,检查是否有库存,如果有执行保留该商品命令,发出商品被保留的事件
4. 订单系统因为事先订阅了商品被保留的事件,因为通过Kafka等事件流总线会接受到商品被保留的事件,
5. 订单系统然后向支付系统发出扣款支付的命令
6. 支付系统接受到扣款命令后,如果能够扣款,执行扣款,发出已经支付的事件 。
7. 订单系统因为也事先订阅了支付系统的事件,将接受到已经支付的事件 。
8. 订单系统向库存系统发出发货命令 。
9. 库存系统接受发货命令,将之前预先保留的商品进行真正出库,发出商品装运事件 。
10. 订单系统因为也事先订阅了库存系统的事件,将接受到商品已经出库装货的事件 。
11. 订单系统确认整个订单完成 。
分布式事务怎么处理?
Pat Helland说,两段提交的分布式事务其实是一种反高可用性的协议 。
使用最终一致性的事务协议是一种猜测、抱歉试错和补偿的协议 。比如Saga模式,Saga协调器能够知道长事务运行中所有事务步骤,如果任何一个步骤,比如上面库存系统出错,Saga协调器将会采取补偿回退之前所有步骤 。
总结:不要建立微单系统,微服务其实是分布式微系统,积极拥抱响应式设计原则,拥抱事件第一的DDD和事件持久化方案 。

【Java架构-如何设计实现真正的响应式微服务系统?】


推荐阅读