5

重新整理 .net core 实践篇————熔断与限流[三十五]

 2 years ago
source link: https://www.cnblogs.com/aoximin/p/14967945.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

重新整理 .net core 实践篇————熔断与限流[三十五]

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

polly 的策略类型分为两类:

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

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

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

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这种拒绝异常,一但出现异常,第二个策略就捕获到了,然后给出一些友好的提示。

下一节,网关。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK