Chaos Monkey,是Netflix工程师创建的一种故障注入系统,它会随机在生产实例中引发各种各样的故障或异常,以确保它们的系统能够在这样的情况下存活,而不会对客户造成任何影响。
可见,Chaos Monkey可以提高系统的安全和可用性。
那如何在.NET中用优雅的方式实现故障注入呢?
Simmy
Simmy是Polly团队发布的一个混沌工程和故障注入工具,它允许你在通过Polly执行代码的任何位置引入一个或多个故障注入策略。
Simmy提供了以下类型的故障注入策略:
异常策略,在你的系统中注入异常;
结果策略,控制返回的结果类型;
延迟策略,类似Netflix的Latency Monkey,执行远程调用时注入巨大的延迟,模拟一个节点甚至整个服务宕机的情况;
行为策略,允许在调用之前注入任何额外的行为;
下面我们就来演示一下,具体如何使用Simmy。
实现Chaos Monkey
假设,我们的API提供天气预报,而具体的天气信息来自于“中国天气网”,也就是说我们依赖于第三方。
如果第三方出现故障,我们应该要有一定的保障措施。
1.实现功能
新建ASP.NET Core Web API项目,在Startup.cs中添加如下代码:
public void ConfigureServices(IServiceCollection services)
{...services.AddHttpClient("Weather", client =>{client.BaseAddress = new Uri("http://www.weather.com.cn/");client.DefaultRequestHeaders.Add("Accept", "application/json");client.Timeout = TimeSpan.FromSeconds(2);});
}
修改WeatherForecastController.cs,代码如下:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{private readonly IHttpClientFactory _httpClientFactory;public WeatherForecastController(IHttpClientFactory httpClientFactory){_httpClientFactory = httpClientFactory;}[HttpGet]public async Task<string> Get(){var client = _httpClientFactory.CreateClient("Weather");string result = await client.GetStringAsync("data/sk/101200101.html");return result;}
}
运行后,返回结果正常:
2.引入Simmy
添加nuget包Polly.Contrib.Simmy
和Microsoft.Extensions.Http.Polly
,修改Startup.cs代码:
public void ConfigureServices(IServiceCollection services)
{...IAsyncPolicy<HttpResponseMessage> chaosPolicy = MonkeyPolicy.InjectLatencyAsync<HttpResponseMessage>(with =>with.Latency(TimeSpan.FromSeconds(5))//50%的几率出现故障.InjectionRate(.5)//默认关闭.EnabledWhen(GetChaosEnabled));services.AddHttpClient("Weather", client =>{client.BaseAddress = new Uri("http://www.weather.com.cn/");client.DefaultRequestHeaders.Add("Accept", "application/json");client.Timeout = TimeSpan.FromSeconds(2);}).AddPolicyHandler(chaosPolicy);
}public static bool ChaosEnabled = false;
private static Task<bool> GetChaosEnabled(Context context, CancellationToken ct)
{return Task.FromResult(ChaosEnabled);
}
我们引入了延迟策略,但是现在我们还没有开启。
3.设置开关
添加ChaosController.cs,代码如下:
[ApiController]
[Route("[controller]")]
public class ChaosController : ControllerBase
{[HttpGet]public async Task<bool> Swich(){Startup.ChaosEnabled = !Startup.ChaosEnabled;return Startup.ChaosEnabled;}
}
这样,我们就可以控制是否启用策略了。
4.放出Monkey
首先,访问/Chaos/switch
,开启策略。
然后多访问几次WeatherForecast
,你就会看到如下页面:
Monkey出现了!
结论
现在,你应该已经修复了发现的问题。但是同时,你还需要部署一套监控工具,以便及时发现其他问题并定位它们的确切位置。
赶快添加其他策略,让你的Chaos Monkey军团更加壮大吧!
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!