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類與介面,其中會呼叫 ofollow,noindex" target="_blank">試水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
。同時使用 UseHystrixRequestContext
與 UseHystrixMetricsStream
。
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的服務端正常工作的話,頁面會顯示如下結果:

如果把服務端停止的話,頁面則會顯示另外的結果:

使用儀表盤的話,則可以看到更直觀的資料(這裡使用的也是上文中現成的客戶端服務,已帶有儀表盤功能):
