原本UI會直接call後端的service,現在插入一個command將UI跟service解耦,同時在command中判斷service是否異常決定是否要執行callbackㄝ, 以及丟出監測的資料
首先加入nuget package
在appsettings.json加入設定
"hystrix": {
"stream": {
"validate_certificates": false
},
"command": {
"FortuneService": {
"threadPoolKeyOverride": "FortuneServiceTPool"
}
}
在Startup.cs加入HystrixCommand跟Dashboard用的設定
public void ConfigureServices(IServiceCollection services) {
.........................................
.........................................
// Add services for Hystrix
services.AddHystrixCommand<GetProductCommand>("ProductService", Configuration);
services.AddHystrixCommand<GetProductsCommand>("ProductService", Configuration);
services.AddHystrixMetricsStream(Configuration);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
IApplicationLifetime appLifetime) {
........................................
........................................
app.UseHystrixRequestContext();
app.UseHystrixMetricsStream();
}
Sample code是用非同步寫的,這邊改用同步來寫。
在資料夾Services底下新增一個GetProductCommand.cs來處理依據ID取值的request
public class GetProductCommand : HystrixCommand<string>
{
private readonly IHystrixCommandOptions options;
private readonly IProductService productService;
private int id;
public GetProductCommand(IHystrixCommandOptions options, IProductService productService) : base(options) {
this.options = options;
this.productService = productService;
IsFallbackUserDefined = true;
}
public string GetProduct(int id) {
this.id = id;
return Execute();
}
protected override string Run() {
return productService.GetValue(this.id);
}
protected override string RunFallback() {
return "Error";
}
}
在資料夾Services底下另新增一個GetProductsCommand.cs來處理取回全部Product的request
public class GetProductsCommand:HystrixCommand<string[]>
{
private readonly HystrixCommandOptions options;
private readonly IProductService productService;
public GetProductsCommand(HystrixCommandOptions options, IProductService productService) : base(options) {
this.options = options;
this.productService = productService;
IsFallbackUserDefined = true;
}
public string[] GetProducts() {
return Execute();
}
protected override string[] Run() {
return productService.GetValues();
}
protected override string[] RunFallback() {
return new string[] { "Error", "Error" };
}
}
將ValuesController更名為ProductsController然後注入command使用
[Route("api/[controller]")]
public class ProductsController : Controller
{
private readonly GetProductCommand getProductCommand;
private readonly GetProductsCommand getProductsCommand;
// GET: api/products
public ProductsController(GetProductCommand getProductCommand, GetProductsCommand getProductsCommand) {
this.getProductCommand = getProductCommand;
this.getProductsCommand = getProductsCommand;
}
[HttpGet]
public IEnumerable<string> Get()
{
return getProductsCommand.GetProducts();
}
// GET api/products/5
[HttpGet("{id}")]
public string Get(int id) {
Console.WriteLine("Execute Get Product");
return getProductCommand.GetProduct(id);
}
}
啟動APIGateway,不啟動ProdutsService這時候開browser會看到下面
證明fallback有作用
ps: 跟Dashboard的通訊又有問題了...抓到了在回頭修改文章....