高可用(一)系统设计

参考:javaguide.cn

文章目录

    • 高可用及其评价指标?
    • 导致系统不可用的情况?
    • 提高系统可用性的方法?
      • 1 注重代码质量:
      • 2 使用集群:
      • 3 限流:
        • 单机限流:
        • 分布式限流:
      • 4 降级和熔断:
        • 降级:
        • 熔断:
      • 5 超时和重试:
      • 6 异步调用:
      • 7 增加缓存:
      • 8 容灾备份和异地多活:
      • 灰度发布:(金丝雀发布)

高可用及其评价指标?

可用性是指系统提供服务的能力,高可用是指系统即使在发生一些未知故障时仍然能够提供服务的能力,使用多少个9来评判一个系统的可用性,即系统可正常提供服务的时间与系统运行时间的比例。

导致系统不可用的情况?

系统遭到攻击、硬件故障、网络故障、并发量激增、代码问题等。

提高系统可用性的方法?

1 注重代码质量:

养成CodeReview的习惯,避免内存泄漏、循环依赖等问题。
使用代码分析工具:
sonarqube使用教程、alibaba/arthas诊断工具、idea自带的代码分析工具。

2 使用集群:

避免单点故障,例如mysql集群、redis集群、zk集群等。

3 限流:

何为限流,为什么做限流:
限流就是对请求的速率进行限制,避免瞬时的大量请求击垮软件系统。毕竟,软件系统的处理能力是有限的。如果说超过了其处理能力的范围,软件系统可能直接就挂掉了。
监控应用流量的QPS或并发线程数等指标,当达到指定阈值时对流量进行控制。

限流算法:
计数器算法(固定窗口、滑动窗口-不太理解)、漏桶算法、令牌桶算法

限流实现:

单机限流:

Google Guava 自带的限流工具类 RateLimiter 。 RateLimiter 基于令牌桶算法,可以应对突发流量。
Resilience4j 不仅提供限流,还提供了熔断、负载保护、自动重试等保障系统高可用开箱即用的功能。并且,Resilience4j 的生态也更好,很多网关(spring cloud gateway)都使用 Resilience4j 来做限流熔断的。
因此,在绝大部分场景下 Resilience4j 或许会是更好的选择。如果是一些比较简单的限流场景的话,Guava 或者 Bucket4j 也是不错的选择。

分布式限流:

借助中间件限流 :可以借助 Sentinel 或者使用 Redis 来自己实现对应的限流逻辑。
网关层限流 :是比较常用的一种方案。不过,通常网关层限流通常也需要借助到中间件/框架
就比如 Spring Cloud Gateway 的分布式限流实现RedisRateLimiter就是基于 Redis+Lua 来实现的,再比如 Spring Cloud Gateway 还可以整合 Sentinel 来做限流。
如果你要基于 Redis 来手动实现限流逻辑的话,建议配合 Lua 脚本来做。网上也有很多现成的脚本供你参考,就比如 Apache 网关项目 ShenYu 的 RateLimiter 限流插件就基于 Redis + Lua 实现了令牌桶算法/并发令牌桶算法、漏桶算法、滑动窗口算法。

4 降级和熔断:

降级:

降级就是为了解决资源不足和访问量增加的矛盾。在有限的资源情况下,为了能抗住大量的请求(服务器压力剧增时),就需要对系统做出一些牺牲。放弃一些功能,保证整个系统能平稳运行
如何降级:
强一致性变成最终一致性;停止访问不重要的功能,从而释放出更多的资源;简化功能流程,把一些功能简化掉,比直接停止访问更好。
降级需要考虑的问题:
对业务进行仔细的梳理和分析,哪些是核心流程必须保证的,哪些是可以牺牲的;考虑什么指标下能进行降级,吞吐量、响应时间、失败次数等达到一个阈值才进行降级处理。

熔断:

熔断模式可以防止应用程序不断地尝试可能超时和失败的服务,能达到应用程序执行而不必等待下游服务修正错误服务。熔断一般是指当依赖的外部接口出现故障时,断绝和外部接口之间的关联
高可用(一)系统设计_第1张图片
熔断器能够记录容易出错的操作调用发生的错误次数,并根据失败率,自我决定是否继续调用还是熔断。

注:常用的流量控制熔断降级框架是Netflix Hystrix和alibaba Sentinel。

5 超时和重试:

请求时长超出某个阈值得不到响应时,抛出异常。
合理设置失败重试的次数。

6 异步调用:

异步调用借助消息队列,在用户请求完成之后就返回结果,异步处理请求,待处理完成后,再通过短信或者邮件通知。为了可用性,允许系统返回中间状态,牺牲强一致性,保证最终一致性。

7 增加缓存:

如果系统并发量很高,当突然有大量请求直接打到数据库上,可能会导致数据库宕机,此时可以给数据库加缓存。比如redis最大的特点就是速度快,将热点数据存入内存,极大地提高并发量。

8 容灾备份和异地多活:

传统灾备:做好重要数据的备份。建立多个完全相同的系统,当某个地方的系统挂掉,切换到另外的系统,继续提供服务。
异地多活:在异地部署多个服务,所有站点同时对外提供服务,即多活。

同城灾备:抵御「机房」级别的风险。
异地多活:抵御「城市」级别的风险。

参考:异地多活

灰度发布:(金丝雀发布)

逐步发布。
灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
灰度期:灰度发布开始到结束期间的这一段时间,称为灰度期。
每天只发布一部分,持续几天才把整个集群发布完毕。观察是否运行稳定、有无故障,期间如果发现问题,只需回滚已经发布的部分。

你可能感兴趣的:(分布式,java,微服务,分布式)