多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[熔断、隔离、重试、降级、超时、限流,高可用架构流量治理核心策略全掌握](https://mp.weixin.qq.com/s/yaCgQlZp1sfZhfJU_Qu67A) [高并发架构设计(三大利器:缓存、限流和降级)](https://mp.weixin.qq.com/s/1mBorW_B2xvJ_8FjE_JrCw) # 简介 高可用(High Availability, HA)方案是一种旨在保证系统在各种故障情况下仍能持续提供服务的设计策略。在分布式系统中,高可用主要通过冗余、负载均衡、数据备份与恢复、故障隔离和自动故障转移等手段实现。 以下是一些常见的高可用设计方案: 1. 冗余部署:(jar包和mysql) * 主从模式:关键服务或组件进行主从备份,主节点处理请求,当主节点出现故障时,从节点接管服务 * 集群模式:多台服务器组成集群,通过负载均衡技术分发请求,即使部分服务器宕机,其他服务器仍可继续提供服务。 2. 负载均衡: * 使用负载均衡器如Nginx、Ribbon等,根据预设策略将用户请求分发到不同的后端服务器,提高系统的并发处理能力和容错性。 3. 数据持久化与备份: * 数据库层面采用主从复制、集群、分区等技术,确保数据的可靠性与一致性,并定期进行备份以应对数据丢失风险。 * 对于分布式存储,可以使用副本集等方式提高数据安全性。 4.故障检测与隔离: * 健康检查:定期对各个服务进行健康状态检测,一旦发现异常,立即将其剔除出服务列表,避免影响整个系统的稳定性。 * 服务熔断与降级:如Hystrix、Sentinel等框架提供的熔断机制,当依赖的服务出现故障时,及时切断调用链,防止雪崩效应。 5.自动故障转移: * 在云环境下,可以通过云服务商提供的弹性伸缩、自动修复等功能实现自动故障转移。 * 在自建环境中,可通过心跳检测、ZooKeeper等工具进行服务注册与发现,以及主备切换。 6.异地多活/多数据中心: * 在地理上分散部署多个数据中心,每个中心都能独立对外提供服务,当某个数据中心发生故障时,流量可以迅速切换至其他数据中心。 7.强一致性的分布式事务: * 利用分布式事务解决方案如两阶段提交(2PC)、三阶段提交(3PC)、TCC、Saga等保证跨服务操作的一致性。 综合运用上述多种技术和策略,可以在最大程度上提升系统的稳定性和可用性,降低由于单点故障导致的服务中断风险。 # 主要涉及的技术 熔断:一种保护机制,当某个服务出现故障或响应超时时,为了防止整个系统出现雪崩效应,熔断机制会暂时停止对该服务的调用,并快速返回一个错误信息或备用方案,从而保护系统的稳定性和可用性。通过设置阈值和时间窗口,当服务的错误率或响应时间超过预设的阈值时,可以触发熔断,并在一段时间内拒绝请求。这可以减轻故障对系统的影响,提高系统的可用性。 降级:降级是在系统负载过高或出现异常情况时,临时关闭一些非关键的功能或服务,以保证核心功能的可用性。通过降级,可以将系统的负载降低到可接受的范围内,避免系统崩溃或无法响应。 限流:限流是控制系统流量的手段,可以限制并发请求的数量,以保护系统免受过载的影响。通过设置最大并发数或请求速率,可以防止系统被过多的请求压垮,保持系统的稳定性和可用性。 超时:设置合理的超时时间是保证系统可用性的重要手段。当服务请求超过预设的时间限制时,可以主动中断请求,避免长时间的等待导致系统资源浪费。通过合理设置超时时间,可以提高系统的响应速度和稳定性。 隔离:隔离是将不同的服务或模块之间的流量进行分离,以降低由于某个服务或模块故障而对整个系统产生的影响。通过隔离,可以将流量限制在一个有限的范围内,使故障局限在一个较小的区域,以保证系统的可用性。 重试:重试是当服务请求失败时,自动进行重试,以增加请求成功的概率。通过设置最大重试次数和重试策略,可以在服务不可用或响应延迟的情况下,尝试重新发送请求,以提高系统的可用性。但重试存在风险,它可能会解决故障,也可能会放大故障。 幂等:在处理网络请求、数据库操作、分布式系统等领域,幂等性是无论一个操作执行一次还是多次,结果都是相同的。重试可能会导致重复触发,出现脏数据,一般重试会和幂等结合使用。 多活策略(冗余部署):一种提高系统可用性和容错能力的策略,在系统多个节点或实例上同时运行应用程序,并确保每个节点或实例都能够处理请求,从而提高系统的整体可用性和容错能力,以确保在部分节点或服务器出现故障时,系统依然能够正常运行。 容灾备份:为了保障应用程序的稳定运行和数据安全,在出现故障或灾难时能够快速恢复业务和数据而采取的一系列措施。容灾备份包括数据备份、系统备份、容灾演练等多个方面。 负载均衡:提高系统性能和可靠性的关键策略,通过将请求分散到多个服务器或节点上,以确保系统能够高效、稳定地处理大量并发请求。 自动故障转移:在系统出现故障时,能够自动将业务从一个节点或实例转移到另一个健康的节点或实例上,以保证业务的连续性和系统的可用性。 ## 熔断 当某个服务出现故障或响应超时时,为了防止整个系统出现雪崩效应,熔断机制会暂时停止对该服务的调用,并快速返回一个错误信息或备用方案,从而保护系统的稳定性和可用性。 熔断的主要方式是使用断路器阻断对故障服务器的调用。 ### 主要作用: 1. 快速失败:当依赖的服务不稳定或响应超时时,熔断机制能够迅速判断并中断对该服务的调用,避免无谓的等待和资源浪费,防止整个系统出现雪崩效应。 2. 自动恢复:熔断机制会根据一定的算法和策略,动态地探测依赖服务的健康状况,当服务恢复稳定后,会自动解除熔断状态,恢复正常的服务调用。 3. 服务降级:在熔断期间,为了保证整体系统的可用性,可以采用服务降级的策略。即暂时舍弃一些非核心的功能或数据请求,直接返回一个预设的错误处理信息或备用方案。 ### 断路器有三种状态,关闭、打开、半打开。 * 关闭:默认状态,允许请求访问,同时会记录一定时间内的成功和失败次数,到达设置的错误率将切换为打开,拒绝请求访问。 * 打开:对请求返回错误信息或者执行降级处理逻辑,不会调用目标接口。 * 半打开:在进入打开状态后,会有一个超时时间,超过之后会进入半打开状态,此时会允许一定数量的请求去调用目标接口。 * 对成功执行的调用进行计数,达到配置的阈值后会认为目标服务恢复正常,此时熔断器回到“关闭”状态; * 如果有请求出现失败的情况,则回到“打开”状态,并重新启动超时计时器,再给系统一段时间来从故障中恢复。 当进入 打开 状态时会拒绝所有请求;进入 关闭 状态时瞬间会有大量请求,这时服务端可能还没有完全恢复,会导致熔断器又切换到 打开 状态;而 半打开 状态存在的目的在于实现了服务的自我修复,同时防止正在恢复的服务再次被大量打垮,所以是一种比较刚性的熔断策略。 阿里 sentinel 可以实现熔断,限流,降级 ## 降级 在系统负载过高或出现异常情况时,临时关闭一些非关键的功能或服务,以保证核心功能的可用性。 ### 主要作用包括: 1. 减轻负载压力:在系统负载过高或资源不足的情况下,通过降级非核心功能或服务,可以减轻系统的负载压力,避免系统崩溃或性能下降。 2. 保证核心业务:降级策略可以确保核心业务的正常运行,即使在一些非关键功能上做出妥协,也能保证整体业务的稳定性和可用性。 3. 灵活应对变化:降级策略可以根据实际情况进行灵活调整,例如根据系统负载、响应时间等指标动态地调整降级策略,以适应不同的业务场景和需求。 4. 降级属于有损操作。 阿里 sentinel 可以实现熔断,限流,降级 ### 降级策略: 1. 降低体验性 把高体验性改成低体验性,牺牲用户体验保证功能完整 2. 放弃非核心功能的功能 比如双十一退货退款功能停用 3. 降低一致性 点赞量,评论量等数据做成最终一致性,并且允许较长时间的不一致 4. 降低数据量 限制返回的数据量,数据只能指定月份查询 #### 自动降级 * 适合触发条件明确可控的场景,比如请求调用失败次数大于一定的阈值,服务接口超时等情况; * 对于一些旁路服务,服务负载过高也可以直接触发自动降级。 #### 手动降级 * 降级操作都是有损的,部分情况下需要根据对业务的影响程度进行手动降级; * 通常需要先制定降级的分级策略,影响面由浅至深。 ## 限流 限制并发请求的数量,以保护系统免受过载的影响。 阿里 sentinel 可以实现熔断,限流,降级 限流实现的两个关键点: 1.如何判断系统是否过载 - 资源使用率; - 请求成功率; - 响应时间; - 请求排队时间 2.过载时如何选择要丢弃的请求 - 按照主调方(客户端)的重要性来划分优先级 - 根据用户的重要性进行区分。 常见的限流算法: 1. 计数器限流 2. 滑动窗口限流 3. 漏桶限流 4. 令牌桶限流 ## 隔离 隔离是将不同的服务或模块之间的流量进行分离,以降低由于某个服务或模块故障而对整个系统产生的影响。 每个系统可以有自己独立的代码库,独立开发,独立发布。一旦出现故障,也不会相互干扰。 隔离最常见的微服务解决方案。 ### 动静隔离 系统的动态内容和静态内容分开处理 就是Nginx动静分离,将网站静态资源(HTML,JavaScript,CSS,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用服务器的请求。后台应用服务器只负责动态数据请求。 静态还可以把前端css、js、图片、文件等静态资源存储到 OSS 并通过 CDN 进行访问加速。 ### CDN加速 CDN的工作原理就是将您源站的资源缓存到位于全球各地的CDN节点上,用户请求资源时,就近返回节点上缓存的资源,而不需要每个用户的请求都回您的源站获取,避免网络拥塞、缓解源站压力,保证用户访问资源的速度和体验。 ### 读写隔离 将读操作和写操作分离到不同的服务或实例中处理 大部分的系统里读写操作都是不均衡的,写数据可能远远少于读数据; 业务上配置数据库的读写分离 比如我们系统有个专门对外共享数据的功能, 这个功能主要就是读,这时候单独弄成一个服务,核心功能也在这个服务里,尽量不与其他服务产生关联,数据库也读取备库,这样这个服务宕机也不会影响系统的其他核心功能 ### 核心隔离 核心隔离通常是指将资源按照 “核心业务”与 “非核心业务”进行划分,优先保障“核心业务”的稳定运行。 按照服务的核心程度进行分级,比如我们有些专题是领导使用,这样的就是非常核心的业务 核心业务部署到性能更好的服务器上 核心业务可以搭建多集群通过冗余资源来提升吞吐和容灾能力; 比如有个专题开发完成之后基本不动,但是这个专题是给上级单位领导看的大屏,这时候我们就是前端和后台全部与其他功能分开,重新写了一套并集群部署。 ### 热点隔离 针对高频访问数据(热点数据)的隔离策略 将访问频次最高的数据缓存起来,可以显著减少对后端存储服务的访问压力,同时提高数据访问的速度; 可以创建一个独立的缓存服务来存储和管理热点数据,实现热点数据的隔离。 ### 集群隔离 将某些服务单独部署成集群,或对于某些服务进行分组集群管理 比如有个专题开发完成之后基本不动,但是这个专题是给上级单位领导看的大屏,这时候我们就是前端和后台全部与其他功能分开,重新写了一套并集群部署。 ### 机房隔离 在不同的机房或数据中心部署和运行服务,实现物理层面的隔离 大型系统采用的,一般系统用不到 解决数据容量大、计算和 I/O 密集度高的问题,比如把北京的数据存储在北京的服务器,上海的存储在上海的服务器,这种区域化的数据管理能有效地分散流量和系统负载; 增强数据安全性和灾难恢复能力。通过在不同地理位置建立服务的完整副本(包括计算服务和数据存储),系统可以实现异地多活或冷备份。 ## 超时 当服务请求超过预设的时间限制时,可以主动中断请求,避免长时间的等待导致系统资源浪费。 ### 主要作用有以下几点: 1. 保护系统资源:由于各种不确定性的因素可能导致接口调用时间的不确定性,设置超时时间可以防止接口调用无限制地等待响应,从而避免系统资源的长时间占用和可能的系统崩溃。 2. 提高用户体验:对于与用户操作相关的接口,如果不设置超时时间,可能会出现长时间的无响应,这将严重影响用户的体验。 3. 保证业务连续性:在负载很高的系统中,大量调用耗时长的接口可能导致系统性能急剧下降,影响其他正常的业务。设置超时时间可以在一定程度上保证系统的业务连续性。 4. 协调不同服务:在微服务架构中,服务间的调用通常会设置超时时间。当某个服务出现故障或响应超时时,调用方可以根据超时时间做出相应的处理,比如重试、降级或熔断,从而协调不同服务之间的交互。 接口设置超时时间是一种有效的保护机制,可以提高系统的健壮性、用户体验和业务连续性。在实际应用中,需要根据具体业务场景和需求来合理设置超时时间。 无论是内部服务之间调用还是调用第三方接口都应设置超时时间,比如下载文件的连接超时时间和读取超时时间,如果是事务里调用了第三方接口,不设置这俩时间可能会导致事务一直无法提交最终耗尽数据库连接。 ## 重试 重试是当服务请求失败时,自动进行重试,以增加请求成功的概率。 网络是脆弱的,随时都可能会出现抖动,解决的办法之一就是重试。但重试存在风险,它可能会解决故障,也可能会放大故障。 > **重试一定要保证重复执行不会造成系统数据错误,保证幂等性。** 通过设置最大重试次数和重试策略,可以在服务不可用或响应延迟的情况下,尝试重新发送请求,以提高系统的可用性。但重试存在风险,它可能会解决故障,也可能会放大故障。 简单重试:可以在调用接口返回失败之后,系统简单地再调用一遍。这种策略通常适用于瞬态错误,如暂时的网络中断或服务重启。 复杂重试:可以设置重试次数已经重试间隔,spring-retry 组件 ## 幂等 在处理网络请求、数据库操作、分布式系统等领域,幂等性是无论一个操作执行一次还是多次,结果都是相同的。重试可能会导致重复触发,出现脏数据,一般重试会和幂等结合使用。 幂等设置主要是处理重复请求,保证多次重复请求获得预期结果一致 ### 主要作用: 1. 解决重试机制导致的重复:在网络请求或分布式系统中,由于网络波动、超时等原因,请求可能会被重复发送。幂等性可以确保即使请求被重复发送,系统也只会执行一次操作,防止重复操作导致的数据不一致问题。 2. 解决用户的重复操作:在Web应用中,用户可能会因为网络延迟或手抖或有意重复点击,会导致发送多个相同的请求,又或者太多用户执行同一操作导致并发太高。幂等性可以确保即使用户多次点击,系统也只会执行一次操作,优化用户体验。 ### 解决方案: 主要解决的是添加和编辑功能 唯一约束:比如注册用户时,用户名称是唯一的,数据库设置为唯一索引,在业务上做校验,都可以根据唯一性去处理 业务状态:比如审核功能,可以根据当前的业务状态去判断当前流程是否重复审核 版本号:表增加版本号字段,每次修改时,版本号字段都加1,版本号对应不上说明已经更新过了 Token机制:进入表单页面先去后台获取一个唯一令牌,提交时把令牌也带上,服务端校验,业务执行完删除令牌。 前端提交后禁用提交按钮:前端点击提交按钮后,直接把按钮禁用,也可以在提交后在vue的请求config配置全局loading效果。因为是纯前端实现,实现简单,适合要求低的小项目(有比没有强的那种项目,因为有些外包项目基本就没做幂等)。 全局唯一ID:根据业务的操作和内容生成一个全局ID,在执行操作前先根据这个全局唯一ID是否存在,来判断这个操作是否已经执行。 锁:分布式锁,数据库行锁,乐观锁等等,可以结合上面几种一块使用 ## 多活策略(冗余部署): 一种提高系统可用性和容错能力的策略,在系统多个节点或实例上同时运行应用程序,并确保每个节点或实例都能够处理请求,从而提高系统的整体可用性和容错能力,以确保在部分节点或服务器出现故障时,系统依然能够正常运行。 多活策略虽然可以提高系统的可用性和容错能力,但也会增加系统的复杂性和管理成本。 ### 主要作用: 1. 提高可用性:冗余部署能够在节点或服务器出现故障时,自动切换到其他正常运行的节点或服务器,从而确保系统始终可用。 2. 增强容错能力:冗余部署可以分散系统的负载,减少单点故障的风险。当某个节点或服务器出现故障时,其他节点或服务器可以接管其任务,保证业务的连续性。 3. 负载均衡:通过冗余部署,可以将请求分散到多个节点或服务器上,实现负载均衡,提高系统的处理能力和响应速度。 ### 方案 1. 多实例集群部署:在同一台物理机或虚拟机上部署多个应用程序实例,每个实例监听不同的端口或使用不同的配置文件。通过负载均衡器将请求分发到这些实例上,实现多活。 2. 容器化集群:利用容器技术(如Docker、Kubernetes)实现多活策略。通过容器编排工具创建和管理多个容器实例,每个容器实例运行一个应用程序。容器编排工具负责容器的调度、负载均衡和故障转移。 3. 微服务架构:将应用程序拆分为多个微服务,每个微服务独立部署和运行。每个微服务都可以有多个实例,通过服务注册与发现机制实现多活。 4. 数据库集群:对于数据库系统,可以采用多主复制或分布式数据库实现多活。多主复制允许多个节点同时写入数据,提高系统的可用性和性能。分布式数据库将数据分散存储在多个节点上,每个节点都可以处理读写请求。 5. 负载均衡器:使用负载均衡器将请求分发到多个应用程序实例上。负载均衡器可以根据一定的算法(如轮询、最小连接数等)将请求转发到不同的实例,实现负载均衡和多活。 ### 容灾备份 为了保障应用程序的稳定运行和数据安全,在出现故障或灾难时能够快速恢复业务和数据而采取的一系列措施。容灾备份包括数据备份、系统备份、容灾演练等多个方面。 ### 数据备份 数据备份是容灾备份的核心,主要包括对数据库、文件系统等关键数据的备份。备份的频率、存储周期、备份策略等需要根据业务需求和数据重要性来制定。 ### 系统备份 目前有很多服务器是搞得虚拟服务器,可以对其进行整体备份,使用的容器的话,也可以容器备份 ### 容灾演练 容灾演练是为了验证容灾备份的有效性而进行的模拟故障恢复操作。通过容灾演练可以发现备份数据的问题、优化备份策略、提高故障恢复能力。 ## 负载均衡 提高系统性能和可靠性的关键策略,通过将请求分散到多个服务器或节点上,以确保系统能够高效、稳定地处理大量并发请求。 ### 作用 1. 提高系统性能:负载均衡可以将请求分发到多个服务器上,使得每个服务器只处理部分请求,从而降低了单个服务器的负载,提高了系统的整体性能。 2. 增强系统可靠性:当某个服务器出现故障时,负载均衡器可以将其从服务器池中移除,将请求转发到其他正常的服务器上,保证了系统的可靠性。 3. 提高资源利用率:通过负载均衡,可以更加合理地利用服务器资源,避免了资源的浪费和瓶颈问题。 ### 方案 1. 软件负载均衡:使用专门的负载均衡软件,如Nginx、HAProxy等,将请求分发到多个应用服务器实例上。这些负载均衡软件通常具有丰富的负载均衡算法和配置选项,可以根据业务需求进行灵活配置。 2. 硬件负载均衡:使用专门的负载均衡硬件设备,如F5、Citrix等。这些设备通常具有高性能和稳定性,适用于大规模和高要求的系统。硬件负载均衡设备通常提供丰富的负载均衡策略、健康检查、会话保持等功能。 3. 反向代理:通过反向代理服务器(如Nginx、Apache等)实现负载均衡。反向代理服务器接收客户端的请求,然后根据负载均衡算法选择一个应用服务器实例进行转发。反向代理服务器还可以提供缓存、SSL终止等功能。 4. 容器化负载均衡:在容器化环境中,可以使用容器编排工具(如Kubernetes)提供的负载均衡功能。Kubernetes可以通过Service资源实现负载均衡,将请求分发到多个Pod实例上。此外,Kubernetes还支持Ingress资源,可以实现更高级别的负载均衡和访问控制。 ## 自动故障转移 在系统出现故障时,能够自动将业务从一个节点或实例转移到另一个健康的节点或实例上,以保证业务的连续性和系统的可用性。 ### 作用 1. 保证业务连续性:在系统出现故障时,自动故障转移机制能够快速将业务转移到其他健康的节点或实例上,确保业务不中断。 2. 提高系统可用性:通过自动故障转移,系统可以自动排除故障节点或实例,保证剩余的健康节点或实例能够继续处理请求。 3. 减少人工干预:自动故障转移机制能够自动处理故障转移过程,减少了人工干预的需要,降低了运维成本。 ### 方案 1. 使用负载均衡器:负载均衡器通常具有故障检测和健康检查功能,可以自动检测和排除故障节点或实例。当负载均衡器检测到某个节点或实例出现故障时,可以将其从服务器池中移除,并将请求转发到其他健康的节点或实例上。 2. 使用分布式系统框架:一些分布式系统框架(如Apache ZooKeeper、etcd等)提供了自动故障转移的功能。这些框架可以维护一个集群的状态,并在节点或实例出现故障时自动进行故障转移。例如,ZooKeeper可以通过选举新的Leader节点来实现自动故障转移。 3. 微服务架构:在微服务架构中,每个微服务都可以有多个实例,并且每个实例都可以注册到服务注册中心。当某个实例出现故障时,服务注册中心可以将其从服务列表中移除,并将请求转发到其他健康的实例上。这种机制可以实现微服务的自动故障转移。 4. 数据库自动故障转移:对于数据库系统,可以采用主从复制或集群的方式实现自动故障转移。当主节点出现故障时,从节点可以自动升级为主节点,并接管主节点的业务。一些数据库管理系统(如MySQL、PostgreSQL等)提供了自动故障转移的功能。