Steeltoe之Circuit Breaker篇

在分布式系统中,服务发生异常是很正常的现象。为了处理这类“例外”,可以采取不同的应对策略,断路器模式即是其中一种方法。这个模式的主要特点是其可以阻断失败的级联影响,不会因为一个服务的失败导致其它关联服务一并失败。

在Spring Cloud生态系统中有Hystrix类库可以提供这个模式的解决方案,而在.NET世界里也有Steeltoe这个开源项目能够提供助力。

Package

对于ASP.NET Core,使用Steeltoe.CircuitBreaker.HystrixCore类库。

对于Console/ASP.NET 4.x,使用Steeltoe.CircuitBreaker.HystrixBase类库。

而如果有需求使用Hystrix的Dashboard,还需要增加Steeltoe.CircuitBreaker.Hystrix.MetricsEventsCore类库。

Service

建立一个Service类与接口,其中会调用试水Spring Cloud Hystrix一文中的服务端应用程序。

public interface IMessageService
{
    Task<string> GetMessage();
}
public class MessageService : IMessageService
{
    private readonly IHttpClientFactory _httpClientFactory;
    public MessageService(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }
    public async Task<string> GetMessage()
    {
        var client = _httpClientFactory.CreateClient();
        var result = await client.GetStringAsync("http://localhost:8200/message");
        return result;
    }
}

Command

建立一个继承HystrixCommand的Command类,重写其RunAsync与RunFallbackAsync方法,分别用于正常场合下对Service的调用与异常情况下的特别处理。

public class MessageCommand : HystrixCommand<string>
{
    private readonly IMessageService _messageService;
    public MessageCommand(IHystrixCommandOptions options, IMessageService messageService) : base(options)
    {
        _messageService = messageService;
    }

    public async Task<string> GetMessage()
    {
        return await ExecuteAsync();
    }

    protected override async Task<string> RunAsync()
    {
        return await _messageService.GetMessage();
    }

    protected override async Task<string> RunFallbackAsync()
    {
        return await Task.FromResult("Woo, bad luck!");
    }
}

Controller

Controller的Action方法里调用Command的对应方法。

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly MessageCommand _command;
    public ValuesController(MessageCommand command)
    {
        _command = command;
    }

    // GET api/values
    [HttpGet]
    public async Task<string> Get()
    {
        return await _command.GetMessage();
    }
}

Startup.cs

配置类中通过依赖注入方式注册HttpClientFactory及已定义的Service。如果需要使用仪表盘的话,还要追加注册AddHystrixMetricsStream。同时使用UseHystrixRequestContextUseHystrixMetricsStream

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient();
        services.AddSingleton<IMessageService, MessageService>();
        services.AddHystrixCommand<MessageCommand>("Message", Configuration);
        services.AddMvc();

        services.AddHystrixMetricsStream(Configuration);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHystrixRequestContext();

        app.UseMvc();

        app.UseHystrixMetricsStream();
    }
}

当应用程序启动后,如果Spring Cloud的服务端正常工作的话,页面会显示如下结果:

如果把服务端停止的话,页面则会显示另外的结果:

使用仪表盘的话,则可以看到更直观的数据(这里使用的也是上文中现成的客户端服务,已带有仪表盘功能):

posted @ 2018-09-24 18:27  Ken.W  阅读(518)  评论(1编辑  收藏  举报