57

.NET Core + Spring Cloud:熔断降级

 5 years ago
source link: http://beckjin.com/2019/02/23/aspnet-hystrix/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在微服务架构下,服务之间彼此隔离,服务之间的调用通过网络请求,在众多服务中,可能因为网络或服务本身的原因引起某些接口异常是很常见的现象,接口超时或报错在实际情况下偶发也属正常,但如果短时间内不断的出现并积压,就可能引起服务崩溃。

Hystrix 是 Spring Cloud 中的核心组件,它提供了熔断、隔离、降级、请求缓存、监控等功能,能够在依赖的服务出现问题时保证系统依然可用。

如下图,当 Dependenccy I 发生故障时,通过 Hystrix 的配置策略决定作出何种响应,如限流拒绝请求、接口异常超过阈值快速返回失败、接口超时发起重试等。

Vriam23.png!web

创建 .NET Core Hystrix 服务

基于 .NET Core + Spring Cloud:API 网关 的所有服务,对 client-service 进行熔断降级测试。

q6j63uN.png!web

修改 client-service :

  1. Nuget 添加引用,MetricsEventsCore 主要对 stream 的监测使用(后面会说明)

    Install-Package Steeltoe.CircuitBreaker.HystrixCore
    Install-Package Steeltoe.CircuitBreaker.Hystrix.MetricsEventsCore
    
  2. 创建 HystrixCommand

    之前是通过构造函数注入BaseService ,直接调用 BaseService 中的方法,现在需要对 BaseService 中的方法进行熔断降级,就需要定义HystrixCommand(本质上是一个代理模式),通过重写 HystrixCommand 的 RunAsync 来调用 _baseService.GetValueAsync()。使用 Steeltoe Hystrix 时, 需要为每个方法创建一个 HystrixCommand ,这个实在有些繁琐,希望后续版本会优化。IHystrixCommandOptions 为 Command 的策略配置参数,未设置则使用默认值,可在配置文件进行设置覆盖,参考: Command Settings

    public class GetValueCommand : HystrixCommand<string>
    {
    	private readonly IBaseService _baseService;
    
    	public GetValueCommand(IHystrixCommandOptions options,
    		IBaseService baseService) : base(options)
    	{
    		_baseService = baseService;
    	}
    
    	public async Task<string> GetValueAsync()
    	{
    		return await ExecuteAsync();
    	}
    
    	protected override async Task<string> RunAsync()
    	{
    		return await _baseService.GetValueAsync();
    	}
    
    	/// <summary>
    	/// 熔断降级执行方法
    	/// </summary>
    	/// <returns></returns>
    	protected override async Task<string> RunFallbackAsync()
    	{
    		return await Task.FromResult("调用 GetValueAsync 接口异常,服务异常,请稍候再试");
    	}
    }
    
  3. Startup.cs ConfigureServices 方法中添加:

    // Add Steeltoe Hystrix Command
    services.AddHystrixCommand<GetValueCommand>("base-service", Configuration);
    
    // Add Hystrix Metrics to container
    services.AddHystrixMetricsStream(Configuration);
    
  4. Startup.cs Configure方法中添加:

    // Start Hystrix metrics stream service
    app.UseHystrixMetricsStream();
    

搭建 Hystrix Dashboard

在进行测试之前,为了更加形象查看效果,我们借助 Hystrix Dashboard 来监控。

  1. 在 IntelliJ IDEA 中新建项目,选 Spring Initializr 完成项目创建

  2. 在 pom.xml 添加 hystrix-dashboard 和 eureka-client 的依赖,我们将会把 Hystrix Dashboard 注册到 Eureka Server

    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  3. 在启动类上添加 EnableHystrixDashboard 注解

    @EnableHystrixDashboard
    @SpringBootApplication
    public class EurekaServiceApplication {
    	public static void main(String[] args) {
    		SpringApplication.run(EurekaServiceApplication.class, args);
    	}
    }
    
  4. 修改 application.yml 配置文件

    spring:
      application:
    	name: hystrix-dashboard-service
    
    server:
      port: 6500
    
    eureka:
      instance:
    	hostname: server1
      client:
    	service-url:
    	  defaultZone: http://server1:8001/eureka/,http://server2:8002/eureka/,http://server3:8003/eureka/
    
  5. 启动服务,访问: http://server1:8001/,可以发现 Hystrix Dashboard 已在 6500 端口启动

    yMFbeqv.png!web

  6. 访问: http://server1:6500/hystrix

    BnA3ArR.png!web

    这时我们需要输入 client-service( http://server1:6001/hystrix/hystrix.stream) 的 stream 地址进行监测。

    v6NFR33.png!web

测试

正常情况请求 http://server1:5555/client-service/api/values/getvalue 接口没问题:

uyIFbuB.png!web

我们可以针对某个 HystrixCommand 配置参数覆盖默认值,在 appsettings.json 添加如下配置,GetValueCommand 执行超时时间为 10ms,所以会存在偶发的 Timeout ,Timeout 时会返回 Fallback 方法结果:

"hystrix": {
  "command": {
    "GetValueCommand": {
      "execution": {
        "isolation": {
          "thread": {
            "timeoutInMilliseconds": 10
          }
        }
      }
    }
  }
}

yEFzEre.png!web

bMVvmqz.png!web

当 Fallback 次数触发了 熔断阈值 ,会进入 Short-Circuited 状态:

UZrErui.png!web

当把 base-service 服务全部杀掉,请求会进入 Failure 状态:

EVz2am3.png!web

Steeltoe 的 Circuit Breaker 还支持 Request Cache、Request Logging、Thread Pool 等,更多请参考 官方文档


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK