云上高可用系统-韧性设计模式

news2024/11/18 5:52:03

一、走近韧性设计模式

(一)基本概念

韧性设计模式是一系列在软件工程中用于提高系统韧性的设计原则、策略、实践和模式。韧性(Resilience)在这里指的是系统对于各种故障、异常和压力的抵抗能力,以及在遭受这些挑战后能够快速自我恢复的能力。韧性设计模式旨在确保系统在面对不可避免的故障时,能够保持高可用性、可靠性和性能。

这些设计模式不仅关注系统的开发阶段,还包括系统的部署、运维和监控阶段,形成了一个全面的韧性设计理念。通过采用这些模式,可以降低系统遭受故障时的影响,并在出现问题时快速、自动地进行恢复。

一些常见的韧性设计模式整合如下:

模式描述应用场景
重试模式 (Retry Pattern)在面对临时性故障时,系统自动尝试重新执行失败的操作。网络问题、服务瞬时不可用等。
断路器模式 (Circuit Breaker Pattern)在系统检测到连续的失败请求时,断开对失败服务的请求,避免连锁故障。避免对故障服务的过度请求,提高整体系统稳定性。
超时模式 (Timeout Pattern)为每个操作设置最大执行时间,避免长时间等待导致资源浪费。防止系统在某个操作上无限期阻塞。
限流模式 (Rate Limiting Pattern)控制系统在一定时间内的请求速率,防止系统过载。防止大量请求导致系统资源耗尽。
负载均衡模式 (Load Balancer Pattern)将请求分发到多个相同的服务实例,提高系统的扩展性和稳定性。均衡系统负载,避免单一节点故障影响整体服务。
舱壁模式 (Bulkhead Pattern)将系统的不同模块隔离开来,避免一个模块的故障影响其他模块。确保故障在一个区域内隔离,不会波及整个系统。
异步消息模式 (Asynchronous Messaging Pattern)通过消息队列将系统的不同组件解耦,提高系统的弹性和可恢复性。降低组件之间的依赖,减少同步调用风险。
灾备模式 (Disaster Recovery Pattern)设计系统的备份和恢复策略,以应对灾难性故障。数据中心故障、自然灾害等情况下确保系统可用性。
自愈模式 (Self-Healing Pattern)系统能够自动检测并恢复从故障中恢复的能力。监控系统状态,自动修复故障。
版本控制模式 (Feature Toggling / Feature Flags Pattern)通过动态切换系统的特性,使得可以在运行时开启或关闭功能。灰度发布、紧急关闭某个功能等。

这些模式的综合应用能够帮助构建更具韧性的系统,提高系统的可用性和稳定性。在云上部署和运行的环境中,韧性设计尤为重要,因为这些环境更容易受到各种因素的影响。

(二)“拥抱故障”理念

对故障和事故的定义如下:

定义例子
故障(Failure):系统不能执行预期功能的状态。宕机、请求超时、内存溢出等。
事故(Accident):故障是系统最终用户可感知的,或者造成了业务损失的情况。下单服务不可用,导致订单损失约10万单。

在故障与事故的定义中,系统不能执行预期功能的状态被定义为故障,而当故障对系统最终用户可感知,或者造成了业务损失时被定义为事故。

在大规模系统中,故障是常态。尤其在管理数千个实例的大规模系统中,宕机、系统出现Bug、请求失败、网络中断等都是经常发生的情况,而不是例外。因此,一个具备韧性的系统需要在部分故障的情况下仍能够正常运行,即使面对较大规模的故障,系统也能够提供大部分的服务。

“拥抱故障”的理念强调了开发者需要在系统的全生命周期中考虑系统如何应对故障,确保系统在故障发生时的状态是符合预期的。这并不意味着构建一个能够抵御任何故障的完美系统,而是要知道并接受系统能够在哪些情况下抵御故障,在哪些情况下会降级,以及在哪些情况下无法抵御。

韧性和成本在大多数情况下是矛盾的。在不那么关键的系统中,为了保证在罕见的自然灾害下的可用性而花费数倍的成本可能得不偿失。因此,理性的做法是在“保证高可靠所花费的成本”和“因停服而造成的潜在损失”之间找到一个合理的平衡点。

(三)避免重大事故关键方向

理解故障和事故的不可避免性后,确实需要通过一系列工作来尽量减小事故的发生概率和降低事故造成的损失。

主要的关键方向如下:

  1. 降低事故发生的概率: 通过健康检查、冗余、负载均衡等手段,预防已知故障的发生,提高系统的可用性。这是一种常见的做法,可以有效降低系统出现常见故障的概率。

  2. 减少故障时长: 在故障发生时,关键是尽快恢复系统的正常状态。快速检测故障、自动切换到备用系统、采用断路器模式等手段都有助于减少故障时长,从而降低损失。

  3. 减小故障影响范围: 在大规模系统中,故障可能只影响系统的一部分。通过设计系统的舱壁模式、服务隔离等,可以限制故障的影响范围,避免故障在整个系统中扩散。

以上三个方向共同作用,有助于降低事故的发生概率,缩短故障时长,减小故障造成的损失。另外,在大规模系统中,事故定级是一个常见的做法,通过事故定级,可以更有针对性地采取措施,提高系统的韧性。

二、保持简单的架构

KISS原则(Keep It Simple and Stupid,或者Keep It Simple, Stupid)是一项设计原则,强调在设计和开发中应保持简单性。这个原则的核心思想是,大多数系统如果保持简单而不是变得复杂,则效果最佳。KISS原则起源于美国海军,在20世纪60年代提出,并后来在计算机科学和软件工程领域广泛应用。

无论采用哪种表述,“保持简单”是KISS原则的核心含义。原则强调设计和实现应该简明直观,避免引入不必要的复杂性。这并不是要求完全排斥复杂性,而是要在确保必要功能的同时,尽量避免使系统变得难以理解、维护和扩展的复杂性。

(一)同质化部署

同质化部署是一种部署策略,它指的是在部署时将系统的所有组件集成在一起,然后部署到系统的每个实例上。这意味着系统的每个实例上运行的应用是完全一样的,所有组件被打包成一个整体。这种部署方式的集成方式一般包括一起编译打包成二进制程序或JAR包,也可以封装成包含所有组件的镜像。

同质化部署的好处在于简化了部署和运行时系统的复杂度。在部署时,不需要为每个组件准备不同的构建和部署脚本,也不必关注不同组件在启动过程中的依赖关系。在运行时,由于所有实例都是相同的,处理问题实例的替代变得更加容易。如果某个实例宕机或者出现容量问题,可以使用其他的实例来替代,而且这个热切换过程不需要拉起新的实例,速度很快,也更容易做到无感知切换。

(二)最少关键依赖原则

最少关键依赖原则是软件设计中的一项原则,强调在设计和实现系统时,应该尽量减少系统对外部组件、服务或库的依赖。核心思想是降低系统受到外部变化的影响,提高系统的稳定性和可维护性。

假设我们正在设计一个健身软件,用户可以通过该软件制定训练计划、记录健身数据等。健身软件中的用户数据直接依赖外部身体数据传感器和第三方社交媒体平台。软件在用户训练时,直接获取身体数据传感器的数据,并将健身记录分享到第三方社交媒体平台。

问题分析:

  • 系统直接依赖外部身体数据传感器和第三方社交媒体平台,增加了软件对这两个外部组件的耦合性。
  • 如果身体数据传感器或社交媒体平台发生变化,需要修改健身软件,可能导致软件其他部分的不稳定性。

应用最少关键依赖原则:

  • 重新设计健身软件,引入中间层或者服务代理。
  • 软件不再直接依赖外部身体数据传感器和第三方社交媒体平台,而是通过中间层或服务代理来与这两个服务通信。
  • 中间层或服务代理负责与外部服务进行交互,并将结果传递给健身软件。

具体实现方案:

  • 引入数据同步服务:通过引入数据同步服务,将身体数据传感器的数据同步到软件的数据存储中。健身软件直接从数据存储中获取用户的身体数据,降低了对传感器的直接依赖。

  • 使用社交媒体 API:通过引入社交媒体 API,软件通过 API 与社交媒体平台通信,将用户的健身记录分享到平台。这样,软件不再直接依赖特定的社交媒体平台实现。

(三)简化部署

在很多系统中,启动新实例时的初始化配置脚本、安装动态链接库以及从外部服务获取初始化配置等操作会导致启动速度变慢,且容易出错。这种做法在容器化部署的环境下可以通过简化部署来优化。

具体实践中,可以将这些初始化操作从首次启动阶段迁移到更早期的构建阶段,使用 Dockerfiles 或 Docker Compose 在构建镜像的过程中完成初始化工作。这种方式可以显著提高启动速度,尤其是在扩容和故障恢复的场景下。

三、冗余、无状态和幂等

冗余、无状态和幂等这三个基础的韧性模式是在设计可靠系统时的重要原则,通常被视为基础或必要条件。

(一)冗余:普适基础

冗余是提升系统可用性的一种最简单且有效的方法。在高可用架构的设计中,采用冗余设计意味着引入多个相同或相似的系统组件实例,以降低单点故障的影响,提升系统的整体可用性。冗余的方式可以涵盖硬件层面、软件层面、数据层面等。

(二)无状态服务

无状态服务是指服务在处理请求时不依赖于本地存储数据,而是通过外部存储或其他服务获取所需的信息。这种设计模式对单次请求的处理不依赖于其他请求,每个请求都包含处理所需的全部信息,或者可以从外部获取。

  • 不依赖本地存储: 无状态服务不在本地存储数据,而是从外部获取所需的信息。这使得服务可以更容易水平扩展,因为每个服务实例都是相同的,而不需要考虑本地数据的同步和共享问题。

  • 独立请求处理: 单次请求的处理不依赖于其他请求的状态,每个请求都是独立的。这样的设计适用于绝大部分在线业务服务,特别是那些数据保存在远程数据库中且请求之间没有明显关联的场景。

  • 存储计算分离: 无状态服务的状态数据被下沉到外部存储系统,实现了存储和计算的分离。这使得集群管理和调度更加简单,支持更灵活的负载均衡和水平扩展。

考虑一个健身软件的案例,该软件需要记录用户的运动数据。在传统有状态的设计中,每个服务实例可能会维护用户的运动数据状态,而在无状态设计中,用户的运动数据被存储在外部的分布式数据库中,服务实例通过API从数据库获取用户的运动数据。这样设计可以实现水平扩展,任意服务实例都可以处理任意用户的请求,而不依赖于本地存储数据。同时,用户的运动数据可以被多个服务实例同时访问,需要注意并发控制的问题。

(三)幂等性

在计算机科学中,幂等性是指一个操作的多次执行和一次执行具有相同的效果。换句话说,无论操作执行多少次,系统的状态都与执行一次时的状态相同。这个概念对于分布式系统和网络通信中的操作非常重要,因为在这些场景下,由于各种原因可能会导致请求的重复执行。

为什么需要幂等性:

在负载均衡和分布式系统中,由于网络不稳定性、超时、重试等原因,同一个请求可能被发送到不同的服务实例上。如果某个操作不是幂等的,那么在请求失败后的重试可能会导致系统状态的变化,进而引起不一致的问题。幂等性的设计可以确保即使请求被重复执行,对系统状态的影响也是相同的,从而防止因为重试而引发的副作用。

幂等性的实现方法:

  1. 业务逻辑设计: 最好的方式是从业务逻辑上入手,设计具备天然幂等性的操作。这意味着无论执行多少次,结果都是相同的。例如,创建订单服务可以设计成只有在订单号不存在时才创建订单,如果订单号已存在,则返回已存在的订单,这样无论多次执行都只会有一个订单记录。

  2. 唯一标识和检查: 使用唯一标识来防止重复操作。每个请求可以携带一个唯一标识,服务在处理请求时先检查该标识是否已经处理过,如果处理过则直接返回结果,避免重复执行。

  3. 幂等键: 引入幂等键(Idempotence Key),客户端在每次请求时都携带一个唯一的键,服务端通过这个键来判断请求是否已经处理过。这样,即使同一个请求被发送多次,服务端通过幂等键就能够判断出重复请求并进行幂等性处理。

通过保证操作的幂等性,系统可以更好地适应分布式环境和不稳定的网络条件,确保在各种情况下都能够维持一致的状态。

四、松耦合设计

在软件设计中,耦合度是指两个模块之间相互依赖的程度。松耦合(Low Coupling)是一种设计原则,旨在降低系统内部组件之间的依赖关系,从而提高系统的灵活性和可维护性。低耦合的系统中,一个模块的变化不太可能影响到其他模块,模块之间的关联性较弱。

五、Event Sourcing:全异步架构模式

六、最终一致

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1417829.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue实现获取系统当前年月日时分秒星期

(壹)博主介绍 &#x1f320;个人博客&#xff1a; 尔滨三皮⌛程序寄语&#xff1a;木秀于林&#xff0c;风必摧之&#xff1b;行高于人&#xff0c;众必非之。 (贰)文章内容 <!-- 获取系统当前时间 --> <template><div class"currentTimeBox"><…

增存量市场大爆发!国产通信中间件「反攻」

梳理2023年智能驾驶的发展脉络可见&#xff0c;消费者对智能驾驶的认可度和接受度越来越高&#xff0c;带动高速NOA迈向了规模化普及新阶段&#xff0c;城市NOA初露锋芒。 从更长远的行业变革周期来看&#xff0c;智能驾驶的技术迭代还在继续&#xff0c;叠加电子电气架构的深…

【hcie-cloud】【23】容器编排【k8s】【Kubernetes常用工作负载、Kubernetes调度器简介、Helm简介、缩略词】【下】

文章目录 单机容器面临的问题、Kubernetes介绍与安装、Kubernetes对象的基本操作、Kubernetes YAML文件编写基础Kubernetes常用工作负载Kubernetes常用工作负载简介创建一个无状态nginx集群无状态工作负载Deployment说明无状态工作负载Deployment常见操作创建一个有状态的MySQL…

Notepad 将多行转换成字符串,合并成一行

notepad 将多行转换成字符串&#xff0c;合并成一行 (1) 快捷键 ctrl H &#xff0c;选择 【替换】&#xff0c; (2) 【查找目标】&#xff0c;输入 \r\n &#xff0c; 这个正则表达式的含义是 换行回到行首&#xff0c;相当于 windows的 enter 键&#xff1a; \r&#xff…

Redis 学习笔记 2:Java 客户端

Redis 学习笔记 2&#xff1a;Java 客户端 常见的 Redis Java 客户端有三种&#xff1a; Jedis&#xff0c;优点是API 风格与 Redis 命令命名保持一致&#xff0c;容易上手&#xff0c;缺点是连接实例是线程不安全的&#xff0c;多线程场景需要用线程池来管理连接。Redisson&…

Hinton、LeCun、Bengio、清华马维英等人当选2023 ACM Fellow!

大家好我是二狗。 美国当地时间1月24日&#xff0c;美国计算机学会&#xff08;ACM&#xff09;正式宣布了2023年 ACM Fellow的名单&#xff0c;今年一共有68名科学家入选。 其中包括万维网的发明人、2016年度图灵奖得主蒂姆伯纳斯李&#xff08;Tim Berners-Lee &#xff09…

Go语言基础之单元测试

1.go test工具 Go语言中的测试依赖go test命令。编写测试代码和编写普通的Go代码过程是类似的&#xff0c;并不需要学习新的语法、规则或工具。 go test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内&#xff0c;所有以_test.go为后缀名的源代码文件都是go …

使用CyberRT写第一个代码

0. 简介 计算框架是自动驾驶系统中的重中之重&#xff0c;也是整个系统得以高效稳定运行的基础。为了实时地完成感知、决策和执行&#xff0c;系统需要一系列的模块相互紧密配合&#xff0c;高效地执行任务流。由于各种原因&#xff0c;这些模块可能位于不同进程&#xff0c;也…

ArcGIS雨涝风险模拟

所谓雨涝模拟分析&#xff0c; 就是模拟降雨量达到一定强度&#xff0c; 城市的哪些区域容易被淹没形成内涝。 雨涝模拟更重要的是提前预测&#xff0c; 可在预测结果的基础上进行实地勘察&#xff0c; 为项目规划、风险防控等工作提供指导作用。 雨涝模拟的原理和思想多种…

MyBatis概述与MyBatis入门程序

MyBatis概述与MyBatis入门程序 一、MyBatis概述二、入门程序1.准备开发环境&#xff08;1&#xff09;准备数据库&#xff08;2&#xff09;创建一个maven项目 2.编写代码&#xff08;1&#xff09;打包方式和引入依赖&#xff08;2&#xff09;新建mybatis-config.xml配置⽂件…

基于springboo校园社团信息管理系统

摘要 随着高校规模的扩大和学生社团活动的日益丰富多彩&#xff0c;校园社团信息管理成为一个备受关注的问题。为了更有效地组织、管理和推动校园社团的发展&#xff0c;本文设计并实现了一套基于Spring Boot的校园社团信息管理系统。本系统以实现社团信息的集中管理和高效运营…

Pytest 识别case规则

一、Python测试框架&#xff0c;主要特点有以下几点&#xff1a; 简单灵活&#xff0c;容易上手&#xff1b;支持参数化&#xff1b;能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来做selenium/appnium等自动化测试、接口自动化测试&#xff08;pytestrequests…

uniapp将方法挂载到全局

前言 首先需要有一个自己封装的方法,话不多说,直接上代码! 方法文件(common.js) const getnav (page, type, param token) > {// type 判断是否 需要验证登录if (!page) return uni.showModal({title: 提示,content: 功能暂未开通~,showCancel: false})let user uni.g…

大模型视觉理解能力更进一步,谷歌提出全新像素级对齐模型PixelLLM

论文题目&#xff1a;Pixel Aligned Language Models 论文链接&#xff1a;https://arxiv.org/abs/2312.09237 项目主页&#xff1a;Pixel Aligned Language Models 近一段时间以来&#xff0c;大型语言模型&#xff08;LLM&#xff09;在计算机视觉领域中也取得了巨大的成功&a…

详解操作系统各章大题汇总(死锁资源分配+银行家+进程的PV操作+实时调度+逻辑地址->物理地址+页面置换算法+磁盘调度算法)

文章目录 第三章&#xff1a;死锁资源分配图例一例二 第三章&#xff1a;银行家算法第四章&#xff1a;进程的同步与互斥做题步骤PV操作的代码小心容易和读者写者混 1.交通问题&#xff08;类似读者写者&#xff09;分析代码 2.缓冲区问题&#xff08;第二个缓冲区是复制缓冲区…

探索Pyecharts关系图绘制技巧:炫酷效果与创意呈现【第42篇—python:Pyecharts水球图】

文章目录 Pyecharts绘制多种炫酷关系网图引言准备工作代码实战1. 基本关系网图2. 自定义节点样式和边样式3. 关系网图的层级结构4. 添加标签和工具提示5. 动态关系网图6. 高级关系网图 - Les Miserables 示例7. 自定义关系网图布局8. 添加背景图9. 3D 关系网图10. 热力关系网图…

CVPR——Latex模版下载

CVPR官网 -> AuthorGuidelines 链接&#xff1a;AuthorGuidelines

基于Java SSM框架实现学生就业服务平台系统项目【项目源码】

基于java的SSM框架实现学生就业服务平台系统演示 JSP技术介绍 JSP技术本身是一种脚本语言&#xff0c;但它的功能是十分强大的&#xff0c;因为它可以使用所有的JAVA类。当它与JavaBeans 类进行结合时&#xff0c;它可以使显示逻辑和内容分开&#xff0c;这就极大的方便了学生…

Python笔记15-实战小游戏飞机大战(中)

文章目录 创建第一个敌机创建一群敌机创建多行敌机让敌机移动射杀敌机生成新的敌机群结束游戏有敌机到达屏幕底端游戏结束 在上一篇基础上继续 本示例源码地址 点击下载 创建第一个敌机 在屏幕上放置外星人与放置飞船类似。每个外星人的行为都由Alien 类控制&#xff0c;我们…

[Python图像处理] 使用OpenCV创建深度图

使用OpenCV创建深度图 双目视觉创建深度图相关链接双目视觉 在传统的立体视觉中,两个摄像机彼此水平移动,用于获得场景上的两个不同视图(作为立体图像),就像人类的双目视觉系统: 通过比较这两个图像,可以以视差的形式获得相对深度信息,该视差编码对应图像点的水平坐标的…