如何设计一个高可用系统?要考虑哪些地方?

本文已经收录自笔者开源的 JavaGuide: https://github.com/Snailclimb (69k+Star【Java学习+面试指南】 一份涵盖大部分Java程序员所须要掌握的核心知识)若是以为不错的还,不妨去点个Star,鼓励一下!

一篇短小的文章,面试常常遇到的这个问题。本文主要包括下面这些内容:git

  1. 高可用的定义
  2. 哪些状况可能会致使系统不可用?
  3. 有些提升系统可用性的方法?只是简单的提一嘴,更具体内容在后续的文章中介绍,就拿限流来讲,你须要搞懂:何为限流?如何限流?为何要限流?如何作呢?说一下原理?。

什么是高可用?可用性的判断标准是啥?

高可用描述的是一个系统在大部分时间都是可用的,能够为咱们提供服务的。高可用表明系统即便在发生硬件故障或者系统升级的时候,服务仍然是可用的。程序员

通常状况下,咱们使用多少个 9 来评判一个系统的可用性,好比 99.9999% 就是表明该系统在全部的运行时间中只有 0.0001% 的时间都是可用的,这样的系统就是很是很是高可用的了!固然,也会有系统若是可用性不太好的话,可能连 9 都上不了。github

哪些状况会致使系统不可用?

  1. 黑客攻击;
  2. 硬件故障,好比服务器坏掉。
  3. 并发量/用户请求量激增致使整个服务宕掉或者部分服务不可用。
  4. 代码中的坏味道致使内存泄漏或者其余问题致使程序挂掉。
  5. 网站架构某个重要的角色好比 Nginx 或者数据库忽然不可用。
  6. 天然灾害或者人为破坏。
  7. ......

有哪些提升系统可用性的方法?

1. 注重代码质量,测试严格把关

我以为这个是最最最重要的,代码质量有问题好比比较常见的内存泄漏、循环依赖都是对系统可用性极大的损害。你们都喜欢谈限流、降级、熔断,可是我以为从代码质量这个源头把关是首先要作好的一件很重要的事情。如何提升代码质量?比较实际可用的就是 CodeReview,不要在意天天多花的那 1 个小时左右的时间,做用可大着呢!面试

另外,安利这个对提升代码质量有实际效果的宝贝:spring

  1. sonarqube :保证你写出更安全更干净的代码!(ps: 目前所在的项目基本都会用到这个插件)。
  2. Alibaba 开源的 Java 诊断工具 Arthas 也是很不错的选择。
  3. IDEA 自带的代码分析等工具进行代码扫描也是很是很是棒的。

2.使用集群,减小单点故障

先拿经常使用的 Redis 举个例子!咱们如何保证咱们的 Redis 缓存高可用呢?答案就是使用集群,避免单点故障。当咱们使用一个 Redis 实例做为缓存的时候,这个 Redis 实例挂了以后,整个缓存服务可能就挂了。使用了集群以后,即便一台 Redis 实例,不到一秒就会有另一台 Redis 实例顶上。数据库

3.限流

流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以免被瞬时的流量高峰冲垮,从而保障应用的高可用性。——来自 alibaba-Sentinel 的 wiki。segmentfault

4.超时和重试机制设置

一旦用户请求超过某个时间的得不到响应,就抛出异常。这个是很是重要的,不少线上系统故障都是由于没有进行超时设置或者超时设置的方式不对致使的。咱们在读取第三方服务的时候,尤为适合设置超时和重试机制。通常咱们使用一些 RPC 框架的时候,这些框架都自带的超时重试的配置。若是不进行超时设置可能会致使请求响应速度慢,甚至致使请求堆积进而让系统没法在处理请求。重试的次数通常设为 3 次,再屡次的重试没有好处,反而会加剧服务器压力(部分场景使用失败重试机制会不太适合)。后端

5.熔断机制

超时和重试机制设置以外,熔断机制也是很重要的。 熔断机制说的是系统自动收集所依赖服务的资源使用状况和性能指标,当所依赖的服务恶化或者调用失败次数达到某个阈值的时候就迅速失败,让当前系统当即切换依赖其余备用服务。 比较经常使用的是流量控制和熔断降级框架是 Netflix 的 Hystrix 和 alibaba 的 Sentinel。缓存

6.异步调用

异步调用的话咱们不须要关心最后的结果,这样咱们就能够用户请求完成以后就当即返回结果,具体处理咱们能够后续再作,秒杀场景用这个仍是蛮多的。可是,使用异步以后咱们可能须要 适当修改业务流程进行配合,好比用户在提交订单以后,不能当即返回用户订单提交成功,须要在消息队列的订单消费者进程真正处理完该订单以后,甚至出库后,再经过电子邮件或短信通知用户订单成功。除了能够在程序中实现异步以外,咱们经常还使用消息队列,消息队列能够经过异步处理提升系统性能(削峰、减小响应所需时间)而且能够下降系统耦合性。安全

7.使用缓存

若是咱们的系统属于并发量比较高的话,若是咱们单纯使用数据库的话,当大量请求直接落到数据库可能数据库就会直接挂掉。使用缓存缓存热点数据,由于缓存存储在内存中,因此速度至关地快!

8.其余

  1. 核心应用和服务优先使用更好的硬件
  2. 监控系统资源使用状况增长报警设置。
  3. 注意备份,必要时候回滚。
  4. 灰度发布: 将服务器集群分红若干部分,天天只发布一部分机器,观察运行稳定没有故障,次日继续发布一部分机器,持续几天才把整个集群所有发布完毕,期间若是发现问题,只须要回滚已发布的一部分服务器便可
  5. 按期检查/更换硬件: 若是不是购买的云服务的话,按期仍是须要对硬件进行一波检查的,对于一些须要更换或者升级的硬件,要及时更换或者升级。
  6. .....(想起来再补充!也欢迎各位欢迎补充!)

总结

如何设计高可用系统?

开源项目推荐

做者的其余开源项目推荐:

  1. JavaGuide:【Java学习+面试指南】 一份涵盖大部分Java程序员所须要掌握的核心知识。
  2. springboot-guide : 适合新手入门以及有经验的开发人员查阅的 Spring Boot 教程(业余时间维护中,欢迎一块儿维护)。
  3. programmer-advancement : 我以为技术人员应该有的一些好习惯!
  4. spring-security-jwt-guide :从零入门 !Spring Security With JWT(含权限验证)后端部分代码。

公众号

相关文章
相关标签/搜索