Steeltoe之Circuit Breaker篇

发布日期:2019-10-27

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

在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的服务端正常工作的话,页面会显示如下结果:

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

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