资讯详情

聊聊高可用的 11 个关键技巧

大家好,我是Tom哥

大型互联网架构设计,注重一个四件套结合拳法,高并发高性能高可用高扩展

如果能掌握这四个方面,在日常工作中应对大厂面试和架构方案设计基本上不是问题。

今天,Tom哥就带大家学习下高可用有哪些设计技巧?

一、系统拆分

有句古话 牵一发动全身。

面对庞然大物,如果没有合理的分工分层。任何小错误都会被无限放大,导致巨大的灾难。

万物相通,回到我们的软件架构。

早期的系统是单一的系统,如电子商务业务、会员、商品、订单、物流、营销等模块都积累在一个系统中。每个假期都有一个大的促销活动,当系统扩展时,一个扩展,一个挂全挂。只要接口有问题,整个系统就不可用。

鸡蛋不能放在篮子里,没有人能承受这种连带风险。

因此,系统拆分 成为更多人的选择。

慢慢地,我们现在看到的就有了微服务根据架构,将复杂的业务域按下DDD思想分为几个子系统,每个子系统负责独家业务功能,做好垂直建设,隔离各子系统之间的边界,减少风险蔓延。

二、解耦

高内聚、低耦合是软件开发的重要原则。

小到接口抽象MVC 分层,大到 SOLID 原则23种设计模式。核心是减少不同模块之间的耦合,避免影响整个系统的错误变化。

就以开闭原则例如,扩展是开放的,修改是关闭的。随着业务功能的迭代,如何每次更改都不会影响原始的旧代码。

Spring 框架为我们提供了一个重要的设计的好主意 AOP ,全称(Aspect Oriented Programming),面向切面编程。

核心是采用动态代理技术,通过增强字节码,在方法调用时拦截,以便在方法调用前后增加我们需要的额外处理逻辑。

当然,另一个重要的想法是事件机制,通过发布订阅模式,只需订阅相应的新需求事件通知,有针对性的消费。不会侵入原代码修改,会好很多吗?

三、异步

同步是指在执行请求时,如果需要一段时间才能返回信息,则该过程将继续等待,直到收到返回信息。

效率会大大降低,聪明人会想到 异步 方式。

异步可以完成非实时响应动作,线程不需要等待,而是继续执行以下逻辑。

如:线程池(ThreadPoolExecutor)、消息队列 都是这个原则

例如,用户在淘宝上下了购物订单,关心订单是否成功,以及后续的付款流程是否可以进行

对于并不特别关心其他业务动作,如短信通知、邮件通知、订单快照生成、超时任务记录创建等。

我们可以使用消息队列发布/订阅 机制,数据库插入订单记录后,发布消息 MQ,然后你可以知用户下单成功。

其它事情,不同的事情 Task 任务订阅信息异步处理,不相互干扰。

四、重试

重试主要体现在远程RPC调用,受 网络抖动线程资源堵塞 因此,请求不能及时响应。

为了提高用户体验,调用方可以通过 重试 方式再次发送请求,尝试获取结果。比过:浏览器的 F5 刷新机制也是如此。

尽管客户端收到了接口重试的双刃剑响应超时因此,我们无法确定服务端是否已经完成。如果盲目重试,可能会带来严重后果。例如:银行转账。

重试通常跟幂等如果一个接口支持组合使用 幂等,那你就可以随便重试了

关于的 幂等 的解决方案

五、补偿

我们知道并非所有的请求都能得到成功的回应。除上述内容外 重试 机制外,我们还可以采用补偿玩法,实现数据最终一致性

业务补偿按处理方向分为两部分:

  • 积极。多个操作构成分布式事务。如果部分成功或失败,我们将通过最大的努力机制失败将任务推向成功

  • 逆向。同样,我们也可以使用反向操作来恢复一些成功的任务初始状态

注:补偿操作有一个重要前提,业务可以在短时间内接受不一致的数据。

实现补偿的方法有很多:

1.存储相关数据,然后通过定期任务扫描提取,并借助反射机制触发执行

2.简单的消息中间件也可以用来构建业务消息体,由下游消费任务执行。如果失败,可以借助MQ重试机制,多次重试机制

六、备份

任何服务器都有停机的可能性。一旦数据存储并处于状态,如果发生故障,数据丢失,后果是我们无法承受的。

所以,容灾备份它已成为互联网的基本能力。

那么如何备份,不同的框架有不必要的玩法。 Redis 为例:

Redis 借助 RDBAOF 实现两台服务器之间的数据同步

  • RDB,全数据同步

  • AOF,同步增量数据,回放日志

主节点挂了怎么办?

哨兵机制在这里引入。哨兵机制可实现主从库的自动切换,有效解决故障转移问题。整个过程分为监控、选主、通知三个阶段。

除了 Redis 除中间件外,其他常见件 MySQL、Kafka 消息中间件,HBase 、ES 等 ,所有涉及数据存储的介质都有备份机制。一旦主节点挂断,备份节点将被启用,以确保数据不会丢失。

七、多活策略

虽然有上面的备份策略,一切都好吗?

在一些极端情况下,如停电、火灾、地震、山洪等不可抗力因素,所有服务器都可能出现故障,无法提供外部服务,导致整体业务瘫痪。

为了降低风险,确保24小时服务的可用性,我们将使用它 多活策略

常见的多活方案有,同城双活两地三中心三地五中心异地双活异地多活

不同的方案有不同的技术要求、施工成本和运维成本。

整理了一份大厂常考面试题,这份pdf包括 Java基础、Java并发、JVM、MySQL、Redis、Spring、MyBatis、Kafka、与大家分享设计模式等面试题。 下载地址:百度云链接:https://pan.baidu.com/s/1XHT4ppXTp430MEMW2D0-Bg 提取码: s3ab

多活的技术方案复杂,有很多问题需要考虑。这里只是抛砖引玉,但要多展开

八、隔离

隔离属于物理层面的分割,将多个系统低耦合设计,独立部署,从物理上分离。

每个子系统都有自己独立的代码库,独立开发和发布。一旦出现故障,就不会相互干扰。当然,如果不同的子系统相互依赖,这种情况是特殊的,需要默认值或异常特殊处理,属于业务解决方案。

隔离是分布式技术的衍生物,是我们最常见的微服务解决方案。

将大型复杂系统分为多个微服务系统,通常由不同的团队开发、维护和独立部署,服务之间通过 RPC 远程调用。

隔离使系统之间的边界更加清晰,故障可以更加隔离,问题的发现和解决更快,系统的可用性更高

九、限流

高并发系统,如果遇到流量洪峰,超过了当前系统的承载能力。我们要怎么办?

一种方案,照单全收,CPU、内存、Load负载飚的很高,最后处理不过来,所有请求都超时无法正常响应。

另一种解决方案,“舍得,有舍有得”,多余的流量我们直接丢弃。

限流定义:

限制到达系统的并发请求数量,保证系统能够正常响应部分用户请求,而对于超过限制的流量,则通过拒绝服务的方式保证整体系统的可用性。

1、单机版限流

主要借助于本机内存来实现计数器,比如通过AtomicLong#incrementAndGet(),但是要注意之前不用的key定期做清理,释放内存。

纯内存实现,无需和其他节点统计汇总,性能最高。但是优点也是缺点,无法做到全局统一化的限流。

2、分布式限流

单机版限流仅能保护自身节点,但无法保护应用依赖的各种服务,并且在进行节点扩容、缩容时也无法准确控制整个服务的请求限制。而分布式限流,以集群为维度,可以方便的控制这个集群的请求限制,从而保护下游依赖的各种服务资源。

  • 整个系统一定时间内(比如每分钟)处理多少请求

  • 单个接口一定时间内处理多少流量

  • 单个IP、城市、渠道、设备id、用户id等在一定时间内发送的请求数

  • 如果是开放平台,则为每个appkey设置独立的访问速率规则

  • 计数器限流

  • 滑动窗口限流

  • 漏桶限流

  • 令牌桶限流

十、熔断

熔断,其实是对调用链路中某个资源出现不稳定状态时(如:调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。

熔断的主要方式是使用断路器阻断对故障服务器的调用

断路器有三种状态,关闭、打开、半打开。

1、关闭(Closed)状态:在这个状态下,请求都会被转发给后端服务。同时会记录请求失败的次数,当请求失败次数在一段时间超过一定次数就会进入打开状态。

2、打开(Open)状态:在这个状态下,熔断器会直接拒绝请求,返回错误,而不去调用后端服务。同时,会有一个定时器,时间到的时候会变成半打开状态。目的是假设服务会在一段时间内恢复正常。

3、半打开(Half Open)状态:在这个状态下,熔断器会尝试把部分请求转发给后端服务,目的是为了探测后端服务是否恢复。如果请求失败会进入打开状态,成功情况下会进入关闭状态,同时重置计数。

目前,市面流行的解决方案是阿里的开源框架 Sentinel,提供了Dashboard控制台用于定义资源以及规则配置

十一、降级

降级是系统保护的一种重要手段。

正如 “好钢用在刀刃上”,为了使有限资源发挥最大价值,我们会临时关闭一些非核心功能,减轻系统压力,并将有限资源留给核心业务。

比如电商大促,业务在峰值时刻,系统抵挡不住全部的流量时,系统的负载、CPU 的使用率都超过了预警水位,可以对一些非核心的功能进行降级,降低系统压力,比如把商品评价成交记录等功能临时关掉。弃车保帅,保证 创建订单订单支付 等核心功能的正常使用。

当然,不同业务、不同公司,处理方式也各不相同,需要结合实际场景,和业务方同学一块讨论,最后达成一个统一认可的降级方案。

标签: 久茂熔体变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台