云原生系统之弹性模式

简介: 本文记录了云原生系统的弹性模式:通过预设策略直面失败,补偿暂时不可用的请求、避免故障传播, 这对于实现微服务高可用、弹性容错相当重要。

01


云原生系统的弹性模式


结合最近的工作经验,本次继续聊一聊云原生的弹性模式 (resilience not scale), 这也是回应《现代云原生设计理念》中


“在分布式体系结构中,当服务B不响应来自服务A的网络请求会发生什么?

当服务C暂时不可用,其他调用C的服务被阻塞时该怎么办?”


a63be167f21c8796df8c1b3f033e07c1.png


由于网络原因或自身原因,B、C服务不能及时响应,服务A发起的请求将被阻塞(直到B、C响应),此时若大量请求涌入,服务A的线程资源将被消耗殆尽,服务A的处理性能受到极大影响,进而影响下游依赖的external clients/backend srv。


故障会传播,造成连锁反应,对整个分布式结构造成灾难性后果,这就是服务故障的“雪崩效应”。


当B、C服务不可用,下游客户端/backend srv能做什么?


客观上请求不通,执行预定的弹性策略:重试/断路?


02


弹性模式:作用在下游的请求消息上


弹性模式是系统面对故障仍然保持工作状态的能力,它不是为了避免故障,而是接受故障并尝试去面对它。


Polly是一个全面的.NET弹性和瞬时错误处理库,允许开发者以流畅和线程安全的方式表达弹性策略。


策略 场景 行为
Retry 抖动/瞬时错误,短时间内自动恢复 在特定操作上配置重试行为
Circuit Breaker 在短期内不大可能恢复 当故障超过阈值,在一段时间内快速失败
Timeout
限制调用者等待响应的时间
Bulkhead
将操作限制在固定的资源池,防止故障传播
Cache
自动存储响应
Bulkhead
一旦失败,定义结构化的行为


一般将弹性策略作用到各种请求消息上(外部客户端请求或后端服务请求)


其目的是补偿暂时不可用的服务请求。


f53b753df4e84f126f871b086c088199.png



03


短期中断的响应码


Http Status code 原因
404 not found
408 request timeout
429 two many requests
502 bad gateway
503 service unavailable
504 gateway timeout


正确规范的响应码能帮助开发者尽快确认故障。


执行故障策略时,也能有的放矢,比如只重试那些由失败引起的操作,对于403UnAuthorized不可重试。


04


Polly的经典策略


Retry:对网络抖动/瞬时错误可以执行retry策略(预期故障可以很快恢复),


Circuit Breaker:为避免无效重试导致的故障传播,在特定时间内如果失败次数到达阈值,断路器打开(在一定时间内快速失败);        


同时启动一个timer,断路器进入半开模式(发出少量请求,请求成功则认为故障已经修复,进入关闭状态,重置失败计数器。)


services.AddHttpClient("small")        //降级        .AddPolicyHandler(Policy<HttpResponseMessage>.HandleInner<Exception>().FallbackAsync(new HttpResponseMessage(),async b =>        {           // 1、降级打印异常          Console.WriteLine($"服务开始降级,上游异常消息:{b.Exception.Message}");          // 2、降级后的数据          b.Result.Content= new StringContent("请求太多,请稍后重试", Encoding.UTF8, "text/html");          b.Result.StatusCode = HttpStatusCode.TooManyRequests;          await Task.CompletedTask;        }))        //熔断                                                              .AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>()            .CircuitBreakerAsync(              3,    // 打开断路器之前失败的次数              TimeSpan.FromSeconds(20), // 断路器的开启到半开模式的时间间隔              (ex, ts) =>  //熔断器开启              {                  Console.WriteLine($"服务断路器开启,异常消息:{ex.Exception.Message}");                  Console.WriteLine($"服务断路器开启的时间:{ts.TotalSeconds}s");              },               () => { Console.WriteLine($"服务断路器重置"); },   //断路器重置进入关闭模式              () => { Console.WriteLine($"服务断路器半开启"); }  //断路器半开启事件            )        )        //重试        .AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().RetryAsync(3))       // 超时        .AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(2)));


☹️当一个应用存在多个Http调用,按照上面的经典写法,代码中会混杂大量重复、与业务无关的口水代码,


思考如何优雅的对批量HttpClient做弹性策略。


这里提供两个实践:


① 博客园驰名博主edisonchou: 使用AOP框架,动态织入Polly


② CSDN某佚名大牛,使用反射加配置实现的

PollyHttpClientServiceCollectionExtension扩展类, 支持在配置文件指定HttpClientName


05


Golang的断路器


go get github.com/sony/gobreaker

func NewCircuitBreaker(st Settings) *CircuitBreaker 实例化断路器对象, 参数如下:


type Settings struct {    Name          string    MaxRequests   uint32       #半开状态允许的最大请求数量,默认为0,允许1个请求    Interval      time.Duration    Timeout       time.Duration  # 断路器进入半开状态的间隔,默认60s    ReadyToTrip   func(counts Counts) bool   # 切换状态的逻辑    OnStateChange func(name string, from State, to State)}


0c52f36422c4e985165f26b306f41825.png


下面这个示例演示了:请求谷歌网站,失败比例达到60%,就切换到"打开"状态,同时开启60sTimer,到60s进入“半开”状态(允许发起一个请求),如果成功, 断路器进入"关闭"状态;失败则重新进入“打开”状态,并重置60sTimer


package mainimport (    "fmt"    "io/ioutil"    "log"    "net/http"    "github.com/sony/gobreaker")var cb *gobreaker.CircuitBreakerfunc init() {    var st gobreaker.Settings    st.Name = "HTTP GET"    st.ReadyToTrip = func(counts gobreaker.Counts) bool {        failureRatio := float64(counts.TotalFailures) / float64(counts.Requests)        return counts.Requests >= 3 && failureRatio >= 0.6    }    cb = gobreaker.NewCircuitBreaker(st)}// Get wraps http.Get in CircuitBreaker.func Get(url string) ([]byte, error) {    body, err := cb.Execute(func() (interface{}, error) {        resp, err := http.Get(url)        if err != nil {            return nil, err        }        defer resp.Body.Close()        body, err := ioutil.ReadAll(resp.Body)        if err != nil {            return nil, err        }        return body, nil    })    if err != nil {        return nil, err    }    return body.([]byte), nil}func main() {    body, err := Get("http://www.google.com/robots.txt")    if err != nil {        log.Fatal(err)    }    fmt.Println(string(body))}


总结


本文记录了云原生系统的弹性模式:通过预设策略直面失败,补偿暂时不可用的请求、避免故障传播, 这对于实现微服务高可用、弹性容错相当重要。

相关文章
|
4月前
|
Cloud Native 中间件 调度
云原生信息提取系统:容器化流程与CI/CD集成实践
本文介绍如何通过工程化手段解决数据提取任务中的稳定性与部署难题。结合 Scrapy、Docker、代理中间件与 CI/CD 工具,构建可自动运行、持续迭代的云原生信息提取系统,实现结构化数据采集与标准化交付。
163 1
云原生信息提取系统:容器化流程与CI/CD集成实践
|
6月前
|
人工智能 Cloud Native 容灾
深圳农商银行三代核心系统全面投产 以云原生架构筑牢数字化转型基石
深圳农商银行完成第三代核心系统全面上云,日均交易超3000万笔,峰值处理效率提升2倍以上。扎根深圳70余年,与阿里云共建“两地三中心”分布式云平台,实现高可用体系及全栈护航。此次云原生转型为行业提供可复制样本,未来将深化云计算与AI合作,推动普惠金融服务升级。
485 17
|
5月前
|
Cloud Native 安全 Linux
龙蜥操作系统:CentOS 谢幕之后,国产云原生系统的崛起之路
龙蜥操作系统(Anolis OS)是 CentOS 停止维护后,由阿里云等企业联合发起的开源项目。它以双内核架构和全栈优化为核心,提供无缝替代 CentOS 的方案,兼容主流生态并针对云计算场景深度优化。其技术亮点包括 RHCK 和 ANCK 双内核、性能优化、全栈安全及国密算法支持。龙蜥适用于云原生基础设施、企业级应用部署及开发环境,社区已吸引 200 多家单位参与。未来规划涵盖 AI 框架优化、RISC-V 架构适配及桌面环境构建,正重新定义云时代的操作系统边界。
1211 0
|
弹性计算 Cloud Native Serverless
云原生应用示例:智能物流管理系统
在电商行业的快速发展中,某企业借助阿里云服务构建了一个云原生智能物流管理系统。此系统基于微服务架构,利用ECS、Kubernetes、ESS及RDS等服务来支撑其核心功能,并采用Serverless函数计算FC处理前端需求,配合消息队列MQ确保通信顺畅。ARMS的应用实现了性能监测与故障快速响应。同时,通过PAI分析数据以提高物流效率,OSS与CDN则优化了文件存储与全球访问速度。此外,系统还整合了Docker及GitLab CI/CD以支持快速迭代,并通过WAF、SLS等工具保障了安全性和合规性,整体上提供了高效、智能且低成本的物流解决方案。
397 7
|
人工智能 Cloud Native 算法
|
运维 Cloud Native Devops
云原生架构的崛起与实践云原生架构是一种通过容器化、微服务和DevOps等技术手段,帮助应用系统实现敏捷部署、弹性扩展和高效运维的技术理念。本文将探讨云原生的概念、核心技术以及其在企业中的应用实践,揭示云原生如何成为现代软件开发和运营的主流方式。##
云原生架构是现代IT领域的一场革命,它依托于容器化、微服务和DevOps等核心技术,旨在解决传统架构在应对复杂业务需求时的不足。通过采用云原生方法,企业可以实现敏捷部署、弹性扩展和高效运维,从而大幅提升开发效率和系统可靠性。本文详细阐述了云原生的核心概念、主要技术和实际应用案例,并探讨了企业在实施云原生过程中的挑战与解决方案。无论是正在转型的传统企业,还是寻求创新的互联网企业,云原生都提供了一条实现高效能、高灵活性和高可靠性的技术路径。 ##
743 30
|
Kubernetes Cloud Native 持续交付
云原生技术:重塑现代应用开发与部署模式####
本文深入探讨了云原生技术的核心概念、发展历程及其在现代软件开发和部署中的关键作用。通过分析云原生架构的特点,如容器化、微服务、持续集成与持续部署(CI/CD),以及它如何促进应用的可伸缩性、灵活性和效率,本文旨在为读者提供一个关于云原生技术全面而深入的理解。此外,还将探讨实施云原生策略时面临的挑战及应对策略,帮助组织更好地把握数字化转型的机遇。 ####
|
Cloud Native Devops 持续交付
探索云原生架构:构建高效、灵活和可扩展的系统
本文将深入探讨云原生架构的核心概念、主要技术以及其带来的优势。我们将从云原生的定义开始,了解其设计理念和技术原则;接着分析容器化、微服务等关键技术在云原生中的应用;最后总结云原生架构如何助力企业实现数字化转型,提升业务敏捷性和创新能力。通过这篇文章,读者可以全面了解云原生架构的价值和应用前景。
|
运维 安全 Cloud Native
核心系统转型问题之保障云原生分布式转型中的基础设施和应用层面如何解决
核心系统转型问题之保障云原生分布式转型中的基础设施和应用层面如何解决
|
监控 Cloud Native 容灾
核心系统转型问题之API网关在云原生分布式核心系统中的功能如何解决
核心系统转型问题之API网关在云原生分布式核心系统中的功能如何解决

热门文章

最新文章