如何利用HttpClientFactory实现简单的熔断降级
前言
在2.1之后,有不少新东西,其中httpclientfactory算是一个。httpclientfactory涉及的东西也不算少,三四种clients , 请求中间件,与polly的结合,生命周期等。
steeltoe的组件升级到2.1后,不少示例代码已经使用httpclientfactory了。当然这是个题外话。
这里主要讲的是与polly的结合,来完成简单的熔断降级。在这之前,还是先看看关于httpclientfactory最简单的用法。
httpclientfactory的简单使用
用个简单的控制台程序来演示
这里就只是获取一下状态码,没有获取实际的内容。
static async task<string> basicusage() { var servicecollection = new servicecollection(); servicecollection.addhttpclient(); var services = servicecollection.buildserviceprovider(); var clientfactory = services.getservice<ihttpclientfactory>(); var client = clientfactory.createclient(); var request = new httprequestmessage(httpmethod.get, "https://www.github.com"); var response = await client.sendasync(request).configureawait(false); return response.statuscode.tostring(); }
其实主要的操作就是addhttpclient,然后通过httpclientfactory创建一个httpclient对象,有了httpclient对象,下面的操作应该就不用多说了。
然后在main方法调用
console.writeline($"basicusage, statuscode = {basicusage().getawaiter().getresult()}");
用法感觉并没有太多的差别。下面来看看与polly的结合。
httpclientfactory和polly的结合
polly的wiki页面已经有了这两者结合使用的文档了。
https://github.com/app-vnext/polly/wiki/polly-and-httpclientfactory
其实现在对于我们来说,要想对http请求使用polly的一些特性已经非常的简单了。
我们在使用的时候要添加microsoft.extensions.http.polly的nuget包。
先来看看使用polly的三种扩展方法
扩展方法 | 说明 |
---|---|
addtransienthttperrorpolicy | 主要是处理http请求的错误,如http 5xx 的状态码,http 408 的状态码 以及system.net.http.httprequestexception异常。 |
addpolicyhandler | 自定义,和传统定义polly的方式保持一致 |
addpolicyhandlerfromregistry | 从policy集合(也是自定义的)里面选择自己想要的。 |
后面的操作,是用的addpolicyhandler。
由于我们要实现熔断降级,所以,我们必不可少的要用到circuitbreakerpolicy和fallbackpolicy,同时为了方便演示,再加个timeoutpolicy。
由于涉及到多个policy,所以我们必须要确定他们的执行顺序!
polly的wiki页面有个示例,还配了一幅很详细的时序图。
一句话来说就是最先起作用的,还是最后添加的那个。
下面就新建一个api项目,用来演示一下。
修改configureservices方法,具体如下
public void configureservices(iservicecollection services) { var fallbackresponse = new httpresponsemessage(); fallbackresponse.content = new stringcontent("fallback"); fallbackresponse.statuscode = system.net.httpstatuscode.toomanyrequests; services.addhttpclient("cb", x => { x.baseaddress = new uri("http://localhost:8000"); x.defaultrequestheaders.add("user-agent", "httpclientfactory-test"); }) //fallback .addpolicyhandler(policy<httpresponsemessage>.handle<exception>().fallbackasync(fallbackresponse, async b => { logger.logwarning($"fallback here {b.exception.message}"); })) //circuit breaker .addpolicyhandler(policy<httpresponsemessage>.handle<exception>().circuitbreakerasync(2, timespan.fromseconds(4), (ex, ts) => { logger.logwarning($"break here {ts.totalmilliseconds}"); }, () => { logger.logwarning($"reset here "); })) //timeout .addpolicyhandler(policy.timeoutasync<httpresponsemessage>(1)); services.addmvc().setcompatibilityversion(compatibilityversion.version_2_1); }
然后是在控制器去使用。
[route("api/[controller]")] [apicontroller] public class valuescontroller : controllerbase { private static int mycount = 0; private readonly ihttpclientfactory _clientfactory; public valuescontroller(ihttpclientfactory clientfactory) { this._clientfactory = clientfactory; } // get api/values/timeout [httpget("timeout")] public actionresult<ienumerable<string>> timeout() { if (mycount < 3)//模拟超时 { system.threading.thread.sleep(3000); } mycount++; return new string[] { "value1", "value2" }; } // get api/values [httpget("")] public async task<string> getasync() { var client = _clientfactory.createclient("cb"); var request = new httprequestmessage(httpmethod.get, "/api/values/timeout"); var response = await client.sendasync(request); var content = await response.content.readasstringasync(); return content; } }
效果如下
前面几次请求,会因为超时或熔断,从而我们得到的结果是fallback。
过了4秒钟后再请求,由于没有超时,正常拿到了结果,所以熔断器会被reset。
来看看日志
比较清晰的看到了所有的操作。
总结
总体来说,httpclientfactory还是很不错的。尤其是它可以直接使用polly相关的特性。
部分示例代码: httpclientfactorydemo
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
推荐阅读
-
C#利用DesignSurface如何实现简单的窗体设计器
-
如何利用IDEA搭建SpringBoot项目整合mybatis实现简单的登录功能
-
如何利用HttpClientFactory实现简单的熔断降级
-
C#利用DesignSurface如何实现简单的窗体设计器
-
如何利用Node.js实现MVC框架的简单实例分析
-
如何利用html+css+JavaScript来实现简单的图片切换特效
-
如何利用IDEA搭建SpringBoot项目整合mybatis实现简单的登录功能
-
如何利用js实现一个简单的拼图游戏
-
如何利用html+css+JavaScript来实现简单的图片切换特效
-
如何利用Node.js实现MVC框架的简单实例分析