事物中调用RPC

2020-04-17  本文已影响0人  snakeSkin

事物中调用RPC

RPC的设计和使用核心是design for failure,从这个角度介绍一下事物中调用RPC,谈谈我自己的理解。

1.场景

一个事物中可能包含N个RPC调用,可能因为各种原因,RPC会调用失败,而事物又不能一直等待,因此需要做系统上的涉及保证系统能正常使用。

2.服务使用方策略

2.1.超时重试

因为RPC请求肯定都是会设置超时的,如果不设置可能造成链路阻塞,但是超时的原因多种多样,有些可能仅仅因为网络抖动。

因此重试是必不可少的,对于不同的服务可以采取不同的超时策略。

可以通过业务异常进行区分判断

对于这样的超时可以直接执行failfast,或者降级返回mock数据。

基本上是需要根据异常情况进行是否重试,或者事物补偿/人工处理,通常来说对实时性有要求的重试会在固定时间间隔发起。

这样的重试可以采用指数退避的方式,即第一次等N 第二次等2N...这样的方式,不会对下游造成太大压力

2.1.1.如何重试

重试是Design for failure的重要部分

常用的方式有:

2.2.幂等设计

2.2.1.是不是需要幂等

首先要明确的是不是所有请求都需要做幂等操作的,因为幂等是需要代价的(通常都依赖存储层唯一键,和全局唯一id).类似Restful接口中DELETE GET HEAD等都不需要增加幂等操作,同样RPC也一样,对数据状态不影响的请求不应该过多的增加幂等。

2.2.2.如何保证幂等

通常来说RPC需要带一个全局id(可以考虑snowflake),在接收方将id保存到数据库中,如果id冲突说明已经有此id,即消息是重复的。

2.3.对某些服务进行服务降级

降级是针对相对不重要的服务的,如果是重要服务是不能进行降级的。降级是从整体负载考虑的,因此就需要为服务定优先级,确定优先级之后才能合理的进行降级分配。

2.3.1.对非核心链路服务降级

降级一般有两种方式,自动方式和手动方式,这边主要聊一下自动方式。

2.3.1.1.自动降级

通常来说自动降级需要失败记录的配合:

等等。。。

2.3.1.2.降级方式

一般来说的降级方式是进行mock返回

2.3.对不重要的服务进行熔断

降级是从整体资源分配的考虑上来考虑的,大多数是因为为了应对即将到来的大流量或者弹性的hold住大流量。而系统往往还会遇到下游系统故障导致无法正确返回的问题。这样就需要增加熔断机制,来保证不会造成压力传递,导致雪崩。

2.3.1.熔断怎么做

断路器状态有以下几个

2.4.事物回滚(补偿机制)

这一步通常是最后才考虑的,因为随着链路的深入,事物补偿的代价变得很大,不过如果必须走到这一步也只能做,同样也有不同策略:

因为补偿通常都是有状态有上下文的,因此需要保存上个状态的数据,可以通过以下两种模式保存

2.4.1.本机保存

直接本机保存补偿数据

2.4.2.持久化保存

持久化保存也是通常的使用方案,(这里不纠结是使用mysql还是redis,存储层的高可用不在这边讨论)

2.5.人工处理

如果补偿失败,则会触发人工处理,因为补偿失败意味着这个事物进退两难了,至少这个请求已经脱离系统控制。这时候就需要适合的监控报警方式。

至于如何进行人工处理不在本文讨论内容,各自系统都需要自己解决。无外乎数据修修补补,bug修复。

3.服务提供方策略

3.1.服务限流

光是调用方做处理实际上是不够的,还需要服务自身尽量保证自己不会被压力压垮,因此需要用限流的方式拒绝一些流量,来保证自己服务不会被打挂.

3.1.1.常见的限流策略

上一篇 下一篇

猜你喜欢

热点阅读