当前位置: 移动技术网 > IT编程>开发语言>.net > 如何利用HttpClientFactory实现简单的熔断降级

如何利用HttpClientFactory实现简单的熔断降级

2018年08月08日  | 移动技术网IT编程  | 我要评论

定制婚礼蛋糕,卡拉蜂下载,水泄不通造句

前言

在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

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对移动技术网的支持。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网