提高系统可用性常用的一些方法,有缓存、异步、重试、幂等、补偿、熔断、降级、限流。
缓存
缓存的速度,比数据库快很多,添加缓存是简单有效的做法。
注意缓存与数据库的一致性,数据表记录变更时记得处理缓存。
Redis缓存的示例,详情见:https://blog.csdn.net/sinat_32502451/article/details/132819596
异步
耗时比较高的功能,可以异步处理。
常用的异步有线程池异步, MQ异步。
线程池异步,详情见:https://blog.csdn.net/sinat_32502451/article/details/133039624
CompletableFuture多任务异步,详情见:https://blog.csdn.net/sinat_32502451/article/details/133955576
重试
访问第三方系统,有时会超时,或者失败,可以进行重试。重试几次,有可能就成功了。
SpringBoot中使用@Retryable注解进行重试。
详情见:https://blog.csdn.net/sinat_32502451/article/details/133774582
重试需要保证幂等性。
幂等性
保证幂等性,有几种常用的方法:
- 唯一索引。
比如订单id使用唯一索引,在插入相同的订单id时,会报错。 - 状态机制。版本号机制。
如果涉及状态变更,可以利用乐观锁,sql如下。
update tt_order set status = 2 where status = 1 and id = 'abc'
-
唯一id 放到 mysql中。
执行业务逻辑后,将唯一id放到mysql中,收到请求先查一下唯一id是否存在,如果存在就不执行业务逻辑。 -
高并发的场景。可以把唯一id放到redis。
执行业务逻辑后,将唯一id放到redis中,收到请求先查一下唯一id是否存在,如果存在就不执行业务逻辑。
补偿
比如请求第三方系统,第三方系统没有回调时,可以主动调用查询接口。
或者是在接口中处理业务逻辑,有些没有执行成功,可以通过定时任务再次执行业务逻辑,进行补偿。
熔断
服务熔断: 在分布式架构中,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。
雪崩效应:是一种因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程。
熔断可以避免服务雪崩。
常用的熔断:SpringCloud Hystrix 、 Sentinel
降级
服务降级:当服务器压力剧增的情况下,根据实际业务情况及流量,对一些非核心的服务和页面不进行处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
为了保证重要或基本的服务能正常运行,可以将一些不重要或不紧急的服务或任务延迟使用或暂停使用。
限流
限流:限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理。
单机版的RateLimiter限流,详情见 : https://blog.csdn.net/sinat_32502451/article/details/134107321
分布式限流,可以使用 Redis配置lua脚本,或者是 Sentinel 限流。