zoukankan      html  css  js  c++  java
  • .NET Core微服务之基于Steeltoe使用Hystrix熔断保护与监控

    Tip: 此篇已加入.NET Core微服务基础系列文章索引

    =>  Steeltoe目录快速导航

    1. 基于Steeltoe使用Spring Cloud Eureka

    2. 基于Steeltoe使用Spring Cloud Zuul

    3. 基于Steeltoe使用Spring Cloud Hystrix

    4. 基于Steeltoe使用Spring Cloud Config

    5. 基于Steeltoe使用Zipkin

    一、关于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仪表盘

  • 相关阅读:
    查看mysql版本的四种方法及常用命令
    newInstance和new的区别(good)
    Citrix 服务器虚拟化之六 Xenserver虚拟机创建与快照
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 2的次幂表示
    Java实现 蓝桥杯 算法训练 2的次幂表示
    Java实现 蓝桥杯 算法训练 前缀表达式
    Java实现 蓝桥杯 算法训练 前缀表达式
  • 原文地址:https://www.cnblogs.com/edisonchou/p/dotnet_core_microservice_integrate_with_springcloud_hystrix.html
Copyright © 2011-2022 走看看