分布式系统中故障不可避免,所以为了提高可用性一定要做弹力设计,也就是容错设计。
常见的容错手段有:
隔离分为两种,一种是以服务为种类来做隔离,另一种是以用户为种类来做分离。
服务维度的隔离是指不同的服务种类设计成独立的系统,比如电商平台,将用户注册登陆设计为一个系统,商品中心设计为另一系统,评论和社交设计为一个系统。这三个系统彼此相互独立,互不耦合,这三个系统的接入层、应用层和数据层都完全隔离的。这样一来,一个板块出了故障就不会影响到其他功能了。在分布式系统中,每个服务都应该有自己独立的数据库,多个服务间不应该共享数据库,否则出了问题很难定位。比如审核系统有很多字段,有些字段不同的服务都会去修改,若设计成多个服务共享一个hbase,那么一个字段状态不对了就很难排查到底是哪个服务把这个状态写错了。
将不同的用户进行分组,部署不同的实例。这样某些服务实例挂掉后,只会影响其对应的用户组,不会影响其他用户。比如秒杀用户不会影响其他的网购用户。不同的用户组的应用层和数据层可以独立部署,也可以共享数据。如果该用户组是非常重要的大客户,可以单独部署服务层和数据库。一般来说都是折中方案。
分布式系统很多时候是为了解决高吞吐的场景。此时,异步通信就比同步通信有更大的优势了。因为异步通信节省了很多调用时等待response的时间。
同步调用还会导致系统被最慢的那个服务拖垮,此外如果某个服务挂掉后会产生雪崩,导致其他服务也不能正常使用。异步调用可以将各个服务彻底解偶。
异步通信有三种方式:
业务方不断轮训、服务方回调通知、broker方式。前两种方式有一定偶尔,broker方式则完全解偶。
Broker方式就是EDA(事件驱动模式),服务间通过消息来完成交流和整个流程的驱动。
网络调用种有三种状态:成功、失败和超时。前两者是明确的,而超时是一种未知状态。
面对超时,client重试可能会导致副作用。为了解决副作用,一般有两种处理方式:
有些操作是有副作用的,比如http post表示新建。为了实现幂等,我们一般会把每个任务用唯一的识别码(雪花算法)表示,然后将结果存到存储种。这样不管是查询还是提供幂等接口都需要,也便于服务的扩展。
将服务从有状态到无状态的迁移是微服务的设计理念之一。这样做可以提高服务的伸缩性。将服务的状态存到第三方存储是通用的方法;而有状态服务的好处是数据本地化,响应时间比较快。有状态服务的数据可以通过gossip协议还有就是session-sticky。
此外分布式系统还要做好业务补偿,流程到某一步实在做不下去了要做好补偿。重试、限流、熔断、降级等也是必须的。
原文:https://www.cnblogs.com/howo/p/12650005.html