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“,记住我!