.NET Core微服务之基于Steeltoe使用Hystrix熔断保护与监控
Tip: 此篇已加入.NET Core微服务基础系列文章索引
=> Steeltoe目录快速导航:
1. 基于Steeltoe使用Spring Cloud Eureka
2. 基于Steeltoe使用Spring Cloud Zuul
3. 基于Steeltoe使用Spring Cloud Hystrix
一、关于Spring Cloud Hystrix

在微服务架构中,我们将系统拆分为很多个服务,各个服务之间通过注册与订阅的方式相互依赖,由于各个服务都是在各自的进程中运行,就有可能由于网络原因或者服务自身的问题导致调用故障或延迟,随着服务的积压,可能会导致服务崩溃。为了解决这一系列的问题,断路器等一系列服务保护机制出现了。
断路器本身是一种开关保护机制,用于在电路上保护线路过载,当线路中有电器发生短路时,断路器能够及时切断故障电路,防止发生过载、发热甚至起火等严重后果。
针对上述问题,Spring Cloud Hystrix 实现了断路器、线路隔离等一系列服务保护功能。它也是基于 Netflix 的开源框架 Hystrix 实现的,该框架的目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix 具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。

二、快速集成Hystrix实现熔断保护
2.1 准备工作
这里仍然基于第一篇的示例进行修改,各个项目的角色如下表所示:
| 微服务项目名称 | 项目微服务中的角色 |
| eureka-service | 服务发现&注册(Spring Boot) |
| zuul-service | API网关 (Spring Boot) |
| agent-service | 服务提供者 (ASP.NET Core) |
| client-service | 服务提供者 (ASP.NET Core) |
| premium-service | 服务提供者&服务消费者 (ASP.NET Core) |
所有相关服务注册到Eureka之后的服务列表:

这里仍然假设premium-service要调用client-service的接口,我们想要模拟的效果就是针对client-service的调用进行熔断保护。
要使用Hystrix,需要对服务添加依赖包:
PM> Install-Package Steeltoe.CircuitBreaker.HystrixCore
2.2 为PremiumService添加Hystrix相关类与配置
(1)增加一个HystrixCommand : ClientServiceCommand
public class ClientServiceCommand : HystrixCommand<string>
{
IClientService _clientService;
ILogger<ClientServiceCommand> _logger;
private int _clientId; public ClientServiceCommand(IHystrixCommandOptions options, IClientService clientService,
ILogger<ClientServiceCommand> logger) : base(options)
{
_clientService = clientService;
_logger = logger;
IsFallbackUserDefined = true;
} public async Task<string> GetClientName(int clientId)
{
_clientId = clientId;
return await ExecuteAsync();
} protected override async Task<string> RunAsync()
{
var result = await _clientService.GetClientName(_clientId);
_logger.LogInformation("Run: {0}", result);
return result;
} protected override async Task<string> RunFallbackAsync()
{
_logger.LogInformation("RunFallback");
return await Task.FromResult<string>("Sorry, the service is unavaliable now. Please try again later.");
}
}
根据Steeltoe官方文档说明,每个Command都必须继承HystrixCommand或HystrixCommand<T>,然后实现这个RunAsync方法与RunFallbackAsync方法。可以看出,RunAsync方法是实现原有业务逻辑,而RunFallbackAsync方法则是受保护降级后的方法,这里简单地输出了一句提示信息“Service is unavaiable. Please try again later.”。
另外,Steeltoe提供了一个快速的HystrixCommand的写法,见下面这个示例代码,全部在构造函数里面搞定:
public class HelloWorldCommand : HystrixCommand<string>
{
public HelloWorldCommand(string name)
: base(HystrixCommandGroupKeyDefault.AsKey("HelloWorldGroup"),
() => { return "Hello" + name; },
() => { return "Hello" + name + " via fallback"; })
{
}
}
但是,这里不得不吐槽一下,在Java中对HystrixCommand的封装是注解级别,工作量小的不是真的不是太多,见下例Java代码:
@RestController
public class MovieController {
...... @HystrixCommand(fallbackMethod = "findByIdFallback")
@GetMapping(value = "/user/{id}")
public User findById(@PathVariable Long id) {
return restTemplate.getForObject("http://user-service/" + id, User.class);
} public User findByIdFallback(Long id){
User user = new User();
user.setId(-1L);
user.setUsername("Default User"); return user;
}
}
(2)改写Controller,使用ClientServiceCommand类替换原有ClientService
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private ClientServiceCommand _clientServiceCommand;
private ILogger<ValuesController> _logger;
public ValuesController(ClientServiceCommand clientServiceCommand, ILogger<ValuesController> logger)
{
_clientServiceCommand = clientServiceCommand;
_logger = logger;
}
......
// GET api/values/5
[HttpGet("{id}")]
public async Task<string> Get(int id)
{
_logger?.LogInformation($"api/values/{id}");
return await _clientServiceCommand.GetClientName(id);
}
}
这里不再直接使用ClientService实例,改为使用ClientServiceCommand实例,实际上是一个代理模式的应用。
(3)在启动类中添加Hystrix相关配置
public class Startup
{
...... public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IClientService, ClientService>();
// Add Steeltoe Discovery Client service
services.AddDiscoveryClient(Configuration);
// Add Steeltoe handler to container
services.AddTransient<DiscoveryHttpMessageHandler>();
// Configure a HttpClient
services.AddHttpClient("client-api-values", c =>
{
c.BaseAddress = new Uri(Configuration["Services:Client-Service:Url"]);
})
.AddHttpMessageHandler<DiscoveryHttpMessageHandler>()
.AddTypedClient<IClientService, ClientService>();
// Add Steeltoe Hystrix Command
services.AddHystrixCommand<ClientServiceCommand>("ClientService", Configuration); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
}
2.3 快速验证
(1)同时启动所有微服务,然后访问PremiumService的相关接口,正常情况下,能够正常返回调用ClientService接口的结果

(2)关闭ClientService,然后再次PremiumService的相关接口,这时会返回受保护降级后的Fallback结果

三、快速集成Hystrix Dashboard实现指标监控
摘抄一句蟋蟀的话:在实际应用中,我们需要对 Hystrix 断路器进行监控,比如熔断请求有多少等等,Spring Cloud 中的实现有 Turbine 进行收集,数据展示的话使用 Hystrix Dashboard。
3.1 快速构建一个Hystrix Dashboard服务
(1)创建一个Spring Boot项目:这里版本是Spring Boot 1.5.15.RELEASE,Spring Cloud Edgware.SR3
(2)pom.xml中添加相关依赖包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
(3)启动类中添加EnableHystrixDashboard注解
@SpringBootApplication
@EnableHystrixDashboard
public class DashboardServiceApplication {
public static void main(String[] args) {
SpringApplication.run(DashboardServiceApplication.class, args);
}
}
(4)必要的配置(application.yml)
server:
port: 5010 spring:
application:
name: hystrix-dashboard-service
3.2 快速在ASP.NET Core中集成Hystrix Metrics
(1)安装Hystrix Dashboard相关包
PM>Install-Package Steeltoe.CircuitBreaker.Hystrix.MetricsEventsCore
(2)改写PremiumService启动类添加相关的Metrics配置
public class Startup
{
...... public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IClientService, ClientService>();
// Add Steeltoe Discovery Client service
services.AddDiscoveryClient(Configuration);
// Add Steeltoe handler to container
services.AddTransient<DiscoveryHttpMessageHandler>();
// Configure a HttpClient
services.AddHttpClient("client-api-values", c =>
{
c.BaseAddress = new Uri(Configuration["Services:Client-Service:Url"]);
})
.AddHttpMessageHandler<DiscoveryHttpMessageHandler>()
.AddTypedClient<IClientService, ClientService>();
// Add Steeltoe Hystrix Command
services.AddHystrixCommand<ClientServiceCommand>("ClientService", Configuration); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); // Add Hystrix Metrics to container
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();
} // Add Steeltoe Discovery Client service
app.UseDiscoveryClient(); app.UseMvc(); // Start Hystrix metrics stream service
app.UseHystrixMetricsStream();
}
}
(3)启动Premium-Service,查看URL:http://localhost:8030/hystrix/hystrix.stream

上图中我们会看到不断实时刷新的 Hystrix 指标监控数据了,但显示并不友好,我咋知道这些指标是啥玩意儿啊!因此,还是让我们在仪表盘中来看看吧。
3.3 快速验证
(1)启动Hystrix Dashboard服务,输入URL:http://localhost:8030/hystrix/hystrix.stream,然后点击按钮“Monitor Stream”

(2)由于ClientServiceCommand尚未起任何作用,所以第一次得到的数据如下:

(3)多次请求ClientService,然后关闭ClientService,再多次请求,这时熔断保护已启动
(4)再次查看Hystrix Dashboard,可以看到以下数据:触发了3次熔断保护

关于Hystrix Dashboard的仪表盘数据属性说明,可以参考下面这张图(From 园友寻找风口的猪 的《Hystrix Dashboard仪表盘》):

四、小结
本文简单介绍了一下Spring Cloud Hystrix这个熔断保护组件,并演示了如何基于Steeltoe OSS使用Hystrix实现熔断保护,并基于Hystrix Dashboard演示了如何收集和可视化地查看ASP.NET Core的熔断监控数据。对于Steeltoe OSS提供的Hystrix的组件的使用,相对于Java的Hystrix的注解封装,代码量稍微大一些。另外,关于Hystrix的一些更高级的使用,本文没有涉及,有兴趣的原有可以自行查看官方文档学习。
示例代码
Click => https://github.com/EdisonChou/Microservice.PoC.Steeltoe/tree/master/src/Chapter2-CircuitBreaker
参考资料
Steeltoe官方文档:《Steeltoe Doc》
Steeltoe官方示例:https://github.com/SteeltoeOSS/Samples
蟋蟀,《.NET Core 微服务架构 Steeltoe的使用》
周立,《Spring Cloud与Docker 微服务架构实战》
Sunday_Xiao,《服务熔断保护:Spring Cloud Hystrix》
寻找风口的猪 的《Hystrix Dashboard仪表盘》
.NET Core微服务之基于Steeltoe使用Hystrix熔断保护与监控的更多相关文章
- .NET Core微服务之基于Steeltoe使用Eureka实现服务注册与发现
Tip: 此篇已加入.NET Core微服务基础系列文章索引 => Steeltoe目录快速导航: 1. 基于Steeltoe使用Spring Cloud Eureka 2. 基于Steelt ...
- .NET Core微服务之基于Steeltoe集成Zuul实现统一API网关
Tip: 此篇已加入.NET Core微服务基础系列文章索引,本篇接上一篇<基于Steeltoe使用Eureka实现服务注册与发现>,所演示的示例也是基于上一篇的基础上而扩展的. => ...
- .NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置
Tip: 此篇已加入.NET Core微服务基础系列文章索引 => Steeltoe目录快速导航: 1. 基于Steeltoe使用Spring Cloud Eureka 2. 基于Steelt ...
- .NET Core微服务之基于Steeltoe使用Zipkin实现分布式追踪
Tip: 此篇已加入.NET Core微服务基础系列文章索引 => Steeltoe目录快速导航: 1. 基于Steeltoe使用Spring Cloud Eureka 2. 基于Steelt ...
- .NET Core微服务之基于Polly+AspectCore实现熔断与降级机制
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.熔断.降级与AOP 1.1 啥是熔断? 在广义的解释中,熔断主要是指为控制股票.期货或其他金融衍生产品的交易风险,为其单日价格波动幅度 ...
- .NET Core微服务之基于Ocelot实现API网关服务(续)
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.负载均衡与请求缓存 1.1 负载均衡 为了验证负载均衡,这里我们配置了两个Consul Client节点,其中ClientServic ...
- .NET Core微服务之基于Ocelot实现API网关服务
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.啥是API网关? API 网关一般放到微服务的最前端,并且要让API 网关变成由应用所发起的每个请求的入口.这样就可以明显的简化客户端 ...
- .NET Core微服务之基于Consul实现服务治理
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.Consul基础介绍 Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发 ...
- .NET Core微服务之基于Consul实现服务治理(续)
Tip: 此篇已加入.NET Core微服务基础系列文章索引 上一篇发布之后,很多人点赞和评论,不胜惶恐,这一篇把上一篇没有弄到的东西补一下,也算是给各位前来询问的朋友的一些回复吧. 一.Consul ...
随机推荐
- css3绘制三角形
将div的宽和高设置为0:利用border-width.border-style.border-color属性绘制不同位置边框的样式.将不需要展示的三角颜色填充为transparent透明即可,就能得 ...
- SpringCloud实战7-Config分布式配置管理
分布式环境下的统一配置框架,已经有不少了,比如百度的disconf,阿里的diamand 官方文档对spring Cloud Config的描述如下:: Spring Cloud Config为分布式 ...
- 11. 将博客部署到tomcat上
springboot项目既可以以jar运行,也可以做成war包放到服务器上,因为我的博客项目涉及到文件上传,所以按照jar的方式就不可行,需要部署到tomcat上,具体做法如下:1. 修改pom.xm ...
- testng生成自定义html报告
转自:https://blog.csdn.net/kdslkd/article/details/51198433 testng原生的或reportng的报告总有些不符合需要,尝试生成自定义测试报告,用 ...
- 如何修改Tomcat默认端口?
修改的原因: 关于8080端口:8080端口同80端口,是被用于WWW代理服务的,可以实现网页浏览,经常在访问某个网站或使用代理服务器的时候,会加上":8080"端口号.另外Apa ...
- bzoj 2428 均分数据 模拟退火
模拟退火 按照自己的思路打了,结果WA,发现退火最关键的就是初温,降温,和修改次数, 这个题还在外层带了一个循环,骚气 #include<cstdio> #include<iostr ...
- bzoj 3629 聪明的燕姿 约数和+dfs
考试只筛到了30分,正解dfs...... 对于任意N=P1^a1*P2^a2*......*Pn^an, F(N)=(P1^0+P1^1+...+P1^a1)(P2^0+P2^1+...+P2^a2 ...
- BZOJ_3343_教主的魔法_分块+二分查找
BZOJ_3343_教主的魔法_分块+二分查找 题意:教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列被编号为 ...
- POJ1038 Bugs Integrated, Inc 状压DP+优化
(1) 最简单的4^10*N的枚举(理论上20%) (2) 优化优化200^3*N的枚举(理论上至少50%) (3) Dfs优化状压dp O(我不知道,反正过不了,需要再优化)(理论上80%) (4) ...
- 记一次springboot项目,maven引发的悲剧(Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletCont)
maven下载大的项目的时候,jar包下载出错是常见的, 但是这种情况经常能看到,如java.lang.ClassNotFoundException这样的提示, 所以一直以来也觉得maven下载jar ...