系统容错的想法

0.系统设计中很大一部分工作是 考虑当发生失败时如何处理. 通过对应的解决方案,规避掉各种异常,使系统健壮, 可以很好的容错, 最终得到一个高可用的服务.

1.善用缓存

  • 理财业务,对于用户的收益数据,是实时去DB中查询的, 当DB发生故障时, 如果没有备份数据源,用户将看不到收益,如果使用redis做缓存,则可以作为备用数据,展示给用户,避免用户投诉
  • 使用redis时,如果redis也挂了,需要考虑本地是否有数据,如果业务场景允许一段时间的脏数据,可以使用本地内存或者二级cache先扛住,如果业务不同意脏数据, 那需要快速失败,就直接
    告诉用户失败了,稍后再重试
  • 通常用户看到失败后,都会不断的重试,反而给业务后台带来更大的压力,造成消息堆积雪崩, 针对这种情况必须做好流量控制,快速失败的方案,前后端都可以做控制. 系统设计重点要考虑异常如何处理.

2.主动重试

  • 建立自动重试的机制,这样可以避免频繁的人工介入,尤其是针对服务极其不稳定的合作方,更需要如此,以减少我们的工作量.

3.必须优化掉DB慢查询

  • 慢查询非常危险,必须要确认表中有索引,如果没有,当并发超高时,将会造成DB cpu飙升,程序无法响应,用户发现请求失败后,就会继续不断的发请求上来,最后服务雪崩了.

4.引入异步处理

  • 对于耗时很长的任务,可以拆分成异步操作,先快速的返回给上游,让上游继续做其它事情,或者上游收到响应后,尝试查询几次后,就接着继续做后面的事情。
    从用户体验上比单纯的让用户一直等待好很多.

5.程序执行顺序

  • 在异常情况下,程序的执行顺序会给系统带来问题,比如有处理重试任务的应用,如果代码设计时,是在系统重启后,马上处理失败的任务,则有可能把正常请求堵死,反而导致更多的失败发生.

6.清晰的日志

  • 涉及到多个系统之间的调用时,需要有一个统一的字段,串联起整个交易,这样方便运维查获日志,定位问题,以及监控.

7.流量控制

8.降级开关

9.旁路

10.消息驱动的模式

11.高并发场景下锁的使用需要非常谨慎

12.压力测试非常重要

  • 服务的处理能力是一定的,我们需要压到这个处理能力,这样可以知道服务器最大的tps是多少. 同时,我们需要得到,在用户可容忍的处理时间内,服务器的处理能力tps可以达到多少. 我来详细说明下.
  • 通常,测试会使用不同的并发数,去压测服务. 100 200 500 ....等等. 假设我们服务有100个线程,每个线程处理一个任务需要100ms, (当然这个数值,我们在压测没结束前是不知道的), 那这个服务处理能力就是1000/s,
    当测试给的并发数小于1000时, 整个服务1s内是可以处理完所有请求.
    当只有100个并发/s时,这些请求不用等待,马上得到了处理, 所以大家的耗时都是100ms
    当只有200个并发/s时,前100个马上得到了处理,后100个需要等100ms, 所以平均耗时是 (100 + 200) / 2 = 150ms
    ...
    当有1000个并发/s时,把他们分成10组,每组100个,则有耗时100ms的,也有耗时1s的,最终平均耗时(1000 + 100) / 2 = 550ms
    从压测报告中看,服务器的处理能力一直在增长,从100tps,增长到 1000tps,但是单个请求的耗时,也在增长,从100ms增长到550ms.
    如果我们认为让用户等550ms,处理一个请求,可以接受,那我们可以认为该服务可以达到1000tps的处理能力.
    如果我们认为让用户等100ms,处理一个请求,可以接受,那实际上,该服务的处理能力就只有100tps,

当测试给的并发数大于1000时,比如测试使用1500个并发/s,那服务器每秒只能处理1000个,所以必然会有500个,只能等前面的都处理完了才可以. 这样排队的人越来越多(每过1秒,就会多出500个排队的人), 压测报告的表现就是
服务器的处理能力 一直是1000/s, 但是单个请求的耗时,越来越长. 所以遇到这种情况,就表示服务器已经达到了极限. 越往后压,单个用户的处理时长就越大,因为排队的人越来越多了.

posted @ 2018-05-03 15:29  JinleiZhang  阅读(155)  评论(0编辑  收藏  举报