聊聊微服务的分布式通信

微服务目前比较热,可是微服务最难的仍是可靠性问题,由于一个系统微服务可能几百个,网络调用频繁,网络的容错性就很是重要,由于对于分布式系统,须要默认网络环境是不可靠的,丢包或堵塞等状况都是可能会发生的,这里面其实就是经典的拜占庭将军问题,两个将军想约定某个时候一块儿进攻,可是不能确保这个信息可否可靠地传递给对方,是路途耽误了仍是送信的人死了永远不可能送达,都没法肯定,网络之间的通信也是如此,A给B发个TCP数据包,这个数据包是由于网络繁忙暂时堵塞,仍是就是被丢弃了呢?双方都不知道。
固然有很多人使用Dubbo这样的开源分布式服务框架,Dubbo使用RPC实现服务之间同步调用,RPC实际是Java中一种远程调用方式,RPC也是没法避免网络通信问题,若是A服务更新了数据库,而调用B服务时网络出错,或者B服务内部调用数据库时出错,可是A服务中数据库已经更新,这就可能发生业务上二者数据库不一致了。
因此,只要涉及到分布式系统,包括分布式服务,分库分表,甚至Web这种浏览器前端与后端之间调用,都须要根据CAP定理进行权衡。
不少人习惯进行服务的同步调用,其实这是和一般方法调用习惯致使,分布式系统中同步调用好像很快,其实很是脆弱,网络容错性差,一旦网络堵塞,同步调用RPC就容易失败。 所以,在分布式系统中,异步调用好像是异步,没有同步快,实际是未必然,异步调用是CAP中的C强一致性和A可用性的妥协,使用最终一致性得到可用性的提升,同时又可以保证必定的网络容错性; 而RPC同步调用,则是选择了CAP中C和A,相似2PC分布式事务,可是网络容错性不好,网络稍微有点堵塞,RPC调用就会受到影响,若是RPC调用嵌套了好几个,某个点的网络堵塞会点爆整个调用链条的崩溃。
因此,微服务架构中,跟踪和恢复变得很是重要,固然这些经过专门的跟踪工具实现,可是这些都是过后控制了。
那么微服务之间的通信推荐使用异步方式,如何具体实现呢? 首先经过异步消息实现微服务之间调用,在架构设计是松耦合的,可见个人另一篇《软件架构的灵活设计》,另外,异步不表明性能慢,由于在分布式系统中,总体快慢是取决于最慢的那个环节,因此,总体性能是讲究效率的,并且这个性能快慢实际就是延迟与可用性问题,又回到前面CAP问题上。
那么异步消息传递在两个服务之间传递什么呢? 固然是传参,这样两个微服务之间经过服务调用进行参数传递,实现数据共享,没必要将彼此的数据库共享给对方访问,微服务拥有本身的独立数据库是微服务严格定义中的重要特征。
目前消息系统有三种消息传递方式: 有至少一次传递; 至多一次传递; 正好一次传递。
至少一次意思是一个消息至少传递一次以上,固然会形成消息内容重复冗余,可是可靠性提升了; 而至多一次是服务器的消息最多传递一次,若是再传递一次,就会形成负面影响,好比会重复执行一些下游的非幂等的服务。 正好一次是经过消息接收方发送确认收到的方式试图保障每次消息传递都能可靠传递完成,可是在理论上认为这是不可能的,由于这个发送、收到和确认的过程当中一旦出现问题,就没法保证传递完成。
其实若是咱们从另一个角度来看消息传递,从网络数据广播角度看,服务器之间实现原子广播是否可能? Kafka(卡夫卡)的创始人Jay Kreps发表过专门一篇文章谈论这个问题,他认为原子广播至关于consensus共识,由于共识多是分布式系统中研究最多的问题。 共识是否可能? 其实这是众所周知的算法主攻的问题,如Paxos和Raft已经在现代分布式系统实践中获得普遍实现。 最后他得出结论: 共识是现代分布式系统发展的支柱。 卡夫卡其中心抽象是分布式一致的日志,其实是您能够想象成最纯粹的相似于多方共识的模拟。 因此若是你不相信共识是可能的话,那么你也不相信卡夫卡是可能的,在这种状况下,你不用担忧卡夫卡的正好一次支持的可能性!
那么使用卡夫卡如何实现相似正好一次的消息传递? 关键是将偏移量和你要保存的状态经过JDBC事务或者JTA事务保存到数据库,失败恢复时从这个偏移量开始从卡夫卡中从新读取,保证了消息和你的业务状态数据的一致性。也实现了有效effectively地消息传递,,实际病不是严格意义上的正好一次,可是这在实践够用了,注意,可别使用完美主义看待这个问题,不然你永远得不到可行的解决方案。

本文分享自微信公众号 - 物流IT圈(exiter18)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。前端

相关文章
相关标签/搜索