ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

你永远想象不到,一个光鲜亮丽的Application,有多么肮脏的Code

2021-07-02 11:32:49  阅读:197  来源: 互联网

标签:polly Code return 光鲜亮丽 重试 Application AddTransientHttpErrorPolicy new policyBuil


前言

简单整理一下polly 重试。

正文

在开发程序中一般都有一个重试帮助类,那么polly同样有这个功能。

polly 组件包:

polly 功能包

polly.Extensions.Http 专门针对http的扩展包

Miscrosoft.Extension.Http.Polly 看到这个名字,那么99%是针对官方.net core的扩展包,是HttpClientFactory 的扩展。

polly有下面一些功能:

  1. 失败重试

  2. 服务熔断

  3. 超时处理

  4. 舱壁处理

  5. 缓存策略

  6. 失败降级

  7. 组合策略

其他都好理解,但是舱壁处理 是什么呢?

这个是限流功能,服务定义最大的流量和队列,避免请求量过大而崩溃。

组合策略,就是对上面的功能可以自由组合。

polly 使用步骤:

  1. 定于要处理的异常类型和返回值

  2. 定义要处理的工作

  3. 使用定义的策略来执行代码

polly的源代码:

https://github.com/App-vNext/Polly

polly 针对http的扩展包:

https://github.com/App-vNext/Polly.Extensions.Http

适合polly 重试的场景:

1.服务"失败"是短暂的,可自愈的。

针对这种http请求,无状态的是非常适用的。

2.服务是"幂等"的,重复调用不会产生副作用

这个幂等可以简单为多次执行,并不会影响到最初达到的效果。

比如说个人查询,查询多次的话,效果是相同的。具体幂等可以百度一下,不过觉的看下https://baike.baidu.com/item/%E5%B9%82%E7%AD%89/8600688?fr=aladdin就够了,因为有些人讲的神乎其神。

具体场景:

  1. 服务闪断

  2. 部分节点不可用

在使用重试过程中,最好达到下面几个要求:

  1. 设置失败次数

  2. 设置有步长策略的失败等待间隔

  3. 设置降级响应

  4. 设置断路器

前面说过polly 是针对httpClientFactory 的扩展,那么其融合性其实是非常好的。

比如说,grpc当监听到AddTransientHttpErrorPolicy错误的时候,那么可以启动对应的策略进行重试,RetryAsync就是polly的扩展,里面设置重试次数20次。

services.AddGrpcClient<Helloworld.Greeter.GreeterClient>(options =>
{
	options.Address = new Uri("https://localhost:5001");
}).ConfigurePrimaryHttpMessageHandler(provider =>
{
	var handle = new SocketsHttpHandler();
	handle.SslOptions.RemoteCertificateValidationCallback = (a, b, c, d) => true;
	return handle;
}).AddTransientHttpErrorPolicy(p=>p.RetryAsync(20));

看下AddTransientHttpErrorPolicy,其实个人感觉RetryAsync倒是没有必要去看,看AddTransientHttpErrorPolicy 是为了知道啥时候会触发这个重试,以及知道如何去定义我们自己的Policy。

AddTransientHttpErrorPolicy:

public static IHttpClientBuilder AddTransientHttpErrorPolicy(
	this IHttpClientBuilder builder, 
	Func<PolicyBuilder<HttpResponseMessage>, IAsyncPolicy<HttpResponseMessage>> configurePolicy)
{
	if (builder == null)
	{
		throw new ArgumentNullException(nameof(builder));
	}

	if (configurePolicy == null)
	{
		throw new ArgumentNullException(nameof(configurePolicy));
	}
	
	var policyBuilder = HttpPolicyExtensions.HandleTransientHttpError();

	// Important - cache policy instances so that they are singletons per handler.
	var policy = configurePolicy(policyBuilder);

	builder.AddHttpMessageHandler(() => new PolicyHttpMessageHandler(policy));
	return builder;
}

从名字中可以看到HandleTransientHttpError就是处理异常的。

public static PolicyBuilder<HttpResponseMessage> HandleTransientHttpError()
{
  return Policy<HttpResponseMessage>.Handle<HttpRequestException>().OrTransientHttpStatusCode();
}

这里表示HttpRequestException 会触发,或者OrTransientHttpStatusCode一些状态码下会触发,看下OrTransientHttpStatusCode。

OrTransientHttpStatusCode:

public static PolicyBuilder<HttpResponseMessage> OrTransientHttpStatusCode(
  this PolicyBuilder<HttpResponseMessage> policyBuilder)
{
  if (policyBuilder == null)
	throw new ArgumentNullException(nameof (policyBuilder));
  return policyBuilder.OrResult(HttpPolicyExtensions.TransientHttpStatusCodePredicate);
}

查看HttpPolicyExtensions.TransientHttpStatusCodePredicate:

 private static readonly Func<HttpResponseMessage, bool> TransientHttpStatusCodePredicate = (Func<HttpResponseMessage, bool>) (response => response.StatusCode >= HttpStatusCode.InternalServerError || response.StatusCode == HttpStatusCode.RequestTimeout);

这里面表示 HttpStatusCode.InternalServerError(500)和 HttpStatusCode.RequestTimeout(408) 会进行重试。

同样可以设置间隔时间进行重试:

services.AddGrpcClient<Helloworld.Greeter.GreeterClient>(options =>
{
	options.Address = new Uri("https://localhost:5001");
}).ConfigurePrimaryHttpMessageHandler(provider =>
{
	var handle = new SocketsHttpHandler();
	handle.SslOptions.RemoteCertificateValidationCallback = (a, b, c, d) => true;
	return handle;
}).AddTransientHttpErrorPolicy(p=>p.WaitAndRetryAsync(20,i=>TimeSpan.FromSeconds(2)));

还可以使用WaitAndRetryForever 表示一直重试,直到成功,看需求。

同样也可以自定义一些状态或者一些情况,做一些事情:

var reg = services.AddPolicyRegistry();

reg.Add("retryforever", Policy.HandleResult<HttpResponseMessage>(message =>
{
	return message.StatusCode == System.Net.HttpStatusCode.Created;
}).RetryForever());

services.AddHttpClient("GreeterClient").AddPolicyHandlerFromRegistry("retryforever");

上面表示针对GreeterClient客户端,增加一些retryforever的处理策略。

后面会介绍这种策略架子是如何实现的,在细节篇。

那通过Polic就可以针对不同场景,进行定义不同的策略,做出一些相应。看项目需求,这里就不多介绍了,每个项目都不一样。

下一节polly熔断。

分类: .net core(web)

标签:polly,Code,return,光鲜亮丽,重试,Application,AddTransientHttpErrorPolicy,new,policyBuil
来源: https://www.cnblogs.com/zy2580/p/zy2580.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有