河北省建设机械会网站首页,技工外包网,中职网页设计与制作教材,农家乐网站建设大纲1.云原生系统的弹性模式resiliency pattern 1.1 服务故障的雪崩效应 1.2 回应之前云原生--弹性请求的疑问#xff1f;2. 弹性模式#xff1a;作用在下游请求消息上3. 短期中断的响应码4. Polly经典策略5. Golang 断路器模式德国哲学家尼采说过#xff1a;那些杀… 大纲1.云原生系统的弹性模式resiliency pattern 1.1 服务故障的雪崩效应 1.2 回应之前云原生--弹性请求的疑问2. 弹性模式作用在下游请求消息上3. 短期中断的响应码4. Polly经典策略5. Golang 断路器模式德国哲学家尼采说过那些杀不死我的东西只会让我更加强大。hi好久不见马甲哥之前意译并连载了《Microsoft Cloud-native toc.pdf》部分内容•什么是云原生•现代云原生设计理念•.NET微服务•谈到云原生绕不开容器化•支撑性服务 自动化能力01云原生系统的弹性模式结合最近的工作经验本次继续聊一聊云原生的弹性模式 (resilience not scale) 这也是回应《现代云原生设计理念》中“在分布式体系结构中当服务B不响应来自服务A的网络请求会发生什么当服务C暂时不可用其他调用C的服务被阻塞时该怎么办”由于网络原因或自身原因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一旦失败定义结构化的行为一般将弹性策略作用到各种请求消息上(外部客户端请求或后端服务请求)。其目的是补偿暂时不可用的服务请求。03 短期中断的响应码Http Status code原因404not found408request timeout429two many requests502bad gateway503service unavailable504gateway timeout正确规范的响应码能帮助开发者尽快确认故障。执行故障策略时也能有的放矢比如只重试那些由失败引起的操作对于403UnAuthorized不可重试。Kubernetes探针踩坑记04 Polly的经典策略•Retry对网络抖动/瞬时错误可以执行retry策略(预期故障可以很快恢复)•Circuit Breaker为避免无效重试导致的故障传播在特定时间内如果失败次数到达阈值断路器打开(在一定时间内快速失败); 同时启动一个timer断路器进入半开模式(发出少量请求,请求成功则认为故障已经修复进入关闭状态重置失败计数器。)
services.AddHttpClient(small)//降级.AddPolicyHandler(PolicyHttpResponseMessage.HandleInnerException().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(PolicyHttpResponseMessage.HandleException() .CircuitBreakerAsync(3, // 打开断路器之前失败的次数TimeSpan.FromSeconds(20), // 断路器的开启的时间间隔(ex, ts) //熔断器开启{Console.WriteLine($服务断路器开启异常消息{ex.Exception.Message});Console.WriteLine($服务断路器开启的时间{ts.TotalSeconds}s);}, () { Console.WriteLine($服务断路器重置); }, //断路器重置事件() { Console.WriteLine($服务断路器半开启(一会开一会关)); } //断路器半开启事件))//重试.AddPolicyHandler(PolicyHttpResponseMessage.HandleException().RetryAsync(3))// 超时 .AddPolicyHandler(Policy.TimeoutAsyncHttpResponseMessage(TimeSpan.FromSeconds(2))); ☹️当一个应用存在多个Http调用按照上面的经典写法代码中会混杂大量重复、与业务无关的口水代码思考如何优雅的对批量HttpClient做弹性策略。这里提供两个实践① 博客园驰名博主edisonchou: 使用AOP框架动态织入Polly② CSDN某佚名大牛使用反射加配置实现的PollyHttpClientServiceCollectionExtension扩展类 支持在配置文件指定HttpClientName05 Golang的断路器go get github.com/sony/gobreakerfunc NewCircuitBreaker(st Settings) *CircuitBreaker 实例化断路器对象 参数如下type Settings struct {Name stringMaxRequests uint32 #半开状态允许的最大请求数量默认为0允许1个请求Interval time.DurationTimeout time.Duration # 断路器进入半开状态的间隔默认60sReadyToTrip func(counts Counts) bool # 切换状态的逻辑OnStateChange func(name string, from State, to State)
}
下面这个示例演示了请求谷歌网站,失败比例达到60%就切换到打开状态同时开启60sTimer,到60s进入“半开”状态(允许发起一个请求)如果成功 断路器进入关闭状态失败则重新进入“打开”状态并重置60sTimerpackage main
import (fmtio/ioutillognet/httpgithub.com/sony/gobreaker
)
var cb *gobreaker.CircuitBreaker
func init() {var st gobreaker.Settingsst.Name HTTP GETst.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))
}
总结 本文记录了云原生系统的弹性模式通过预设策略直面失败补偿暂时不可用的请求、避免故障传播 这对于实现微服务高可用、弹性容错相当重要。•https://blog.csdn.net/weixin_44588495/article/details/106361934•https://blog.csdn.net/qq_26900081/article/details/108071374•https://www.cnblogs.com/edisonchou/p/9159644.html•https://docs.microsoft.com/en-us/dotnet/architecture/cloud-native/application-resiliency-patterns•https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker更多干货及最佳实践关注并星标我们后台回复cloud-native获取微软云原生技术白皮书今天因为你的点赞让我元气满满 ✍️本文永久链接在这里