zoukankan      html  css  js  c++  java
  • 重新整理 .net core 实践篇————熔断与限流[三十五]

    前言

    简单整理一下熔断与限流,跟上一节息息相关。

    正文

    polly 的策略类型分为两类:

    1. 被动策略(异常处理、结果处理)

    2. 主动策略(超时处理、断路器、舱壁隔离、缓存)

    熔断和限流通过下面主动策略来实现:

    1. 降级响应

    2. 失败重试

    3. 断路器

    4. 舱壁隔离

    Policy 类型 状态 说明
    CircuitBreaker(断路器) 有状态 共享失败率,以决定是否熔断
    Bulkhead(舱壁隔离) 有状态 共享容量使用情况,以决定是否执行动作
    Cache(缓存) 有状态 共享缓存的对象,以决定是否命中
    其他策略 无状态

    先来看一下熔断,什么是熔断呢?

    熔断就是让我们的上游服务器一段时间内对下游服务器不进行调用。

    这里解释一下上游服务器和下游服务器,比如说A调用B,那么A就是上游服务器,B就是下游服务器。

    那么为什么要熔断呢?比如说A调用B,现在A调用B 10次有8次是错误的,那么这个时候就要想一件事,代码没有变过,那么肯定是量变成了质变。

    这时候B之所以不可用,那么是因为请求太多了,处理不过来(比如内存升高了,io 99%了等)。

    那么这个时候A就不进行调用了,隔一段时间后再进行调用。也就是A对B的这条线进行了熔断处理。

    services.AddHttpClient("GreeterClient").AddPolicyHandler(Policy<HttpResponseMessage>
    	.Handle<HttpRequestException>().CircuitBreakerAsync(handledEventsAllowedBeforeBreaking: 10,
    		durationOfBreak: TimeSpan.FromSeconds(10), 
    		onBreak: (r, t) =>
    		{
    			// 熔断的时候处理事件
    		},
    		onReset: () =>
    		{
    			// 恢复的时候的处理
    		},onHalfOpen: () =>
    		{
    			// 恢复之前进行处理
    		}));
    

    CircuitBreakerAsync 表示断路器,这个用来实现熔断的。

    handledEventsAllowedBeforeBreaking 表示失败10次,进行熔断。

    durationOfBreak 熔断的事件

    其他几个事件上面做了备注。

    其实上面这种不常用,因为限制比较死,比如说10次就熔断。

    一般都是百分比来计算的。

    services.AddHttpClient("GreeterClient").AddPolicyHandler(Policy<HttpResponseMessage>
    	.Handle<HttpRequestException>().AdvancedCircuitBreakerAsync(
    		failureThreshold:0.8,
    		samplingDuration:TimeSpan.FromSeconds(10),
    		minimumThroughput:100,
    		durationOfBreak: TimeSpan.FromSeconds(10),
    		onBreak: (r, t) =>
    		{
    			// 熔断的时候处理事件
    		},
    		onReset: () =>
    		{
    			// 恢复的时候的处理
    		}, onHalfOpen: () =>
    		{
    			// 恢复之前进行处理
    		}));
    

    failureThreshold 表示失败的比例

    samplingDuration 表示失败的时间

    failureThreshold 和 samplingDuration一般是组合起来用的,表示是10秒内失败次数要有80%就会熔断。

    minimumThroughput 表示10秒类必须有100个请求才会出根据其他的条件进行熔断判断。

    上面就是熔断了,那么什么是服务降级呢?

    网上的一段话是这样的:服务降级是指 当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心业务正常运作或高效运作。

    这段话的感觉好像是关闭某些服务一样,而且比较绕。

    个人理解是服务降级是指降低了原有的服务体验,都属于服务降级。

    熔断其实也是一种服务降级,但是单纯的熔断就降级的有点厉害了。

    比如我去买东西,然后店直接关门了,服务体验下降了,体验降得比较厉害。

    但是如果去买东西,店没有关闭,而是有一排服务员,告诉你现在因为供销商没到货买不到了,这体验是不是好点,这也是服务降级。

    那么就看下第二种情况的服务降级怎么实现吧。

    var breakPolicy = Policy<HttpResponseMessage>
       .Handle<HttpRequestException>().AdvancedCircuitBreakerAsync(
    	   failureThreshold: 0.8,
    	   samplingDuration: TimeSpan.FromSeconds(10),
    	   minimumThroughput: 100,
    	   durationOfBreak: TimeSpan.FromSeconds(10),
    	   onBreak: (r, t) =>
    	   {
    		   // 熔断的时候处理事件
    	   },
    	   onReset: () =>
    	   {
    		   // 恢复的时候的处理
    	   }, onHalfOpen: () =>
    	   {
    		   // 恢复之前进行处理
    	   });
    
    var message = new HttpResponseMessage()
    {
    	Content = new StringContent("不要慌,老板没有跑路,只是和老婆的妹妹出去了,要等一下!")
    };
    
    var fallback = Policy<HttpResponseMessage>.Handle<BrokenCircuitException>().FallbackAsync(message);
    
    var fallbackBreak = Policy.WrapAsync(fallback, breakPolicy);
    
    services.AddHttpClient("GreeterClient").AddPolicyHandler(fallbackBreak);
    

    上面代码就是当熔断后,过来的请求会有BrokenCircuitException异常,那么捕获到BrokenCircuitException异常,那么就告诉用户店没有倒闭,等一下就好。

    这种就是比较优雅的降级。

    上面这种var fallbackBreak = Policy.WrapAsync(fallback, breakPolicy); 就是将几个policy组合在一起,然后给某个或者某些HttpClient 增加该组合策略,比如Policy.WrapAsync(fallback, breakPolicy,xxx,yyy)等。

    接下来解释一下限流。

    为什么要限流呢? 如果没有限流其实熔断的意义是不大的。

    为什么这么说呢? 比如说公司有1百万请求,然后这个时候熔断了,但是这100w请求还在啊,只有恢复服务,服务器又要进行熔断,一下子就瞬间爆炸。

    var bulk = Policy.BulkheadAsync<HttpResponseMessage>(
    	maxParallelization:30,
    	maxQueuingActions:20,
    	onBulkheadRejectedAsync:context=>Task.CompletedTask);
    
    var message = new HttpResponseMessage()
    {
    	Content = new StringContent("你没有抢到号码,下次再来。")
    };
    
    var fallbackBulk = Policy<HttpResponseMessage>.Handle<BulkheadRejectedException>().FallbackAsync(message);
    
    var fallbackBreak = Policy.WrapAsync(bulk, fallbackBulk);
    

    上面这个就是限流了。

    maxParallelization 表示可以并发处理30个请求,maxQueuingActions表示如果并发处于30,那么会加入到队列中,队列中最大能存20个。

    如果队列中也存不下,那么就会抛出BulkheadRejectedException这种拒绝异常,一但出现异常,第二个策略就捕获到了,然后给出一些友好的提示。

    下一节,网关。

  • 相关阅读:
    【C++ 系列笔记】03 C++ 面向对象进阶
    【C++ 系列笔记】02 C++ 面向对象基础
    【C++ 系列笔记】01 C++ 与 C
    【JavaScript】简单取随机数 ~~(Math.random() * number)
    英语测试
    Linux指令入门
    RE-攻防世界 T3 insanity
    PWN-攻防世界 level0
    ISCC不会的理论题
    kali linux配置ssh
  • 原文地址:https://www.cnblogs.com/aoximin/p/14967945.html
Copyright © 2011-2022 走看看