• <sup id="mk476"></sup>
    <dl id="mk476"></dl>
  • <progress id="mk476"><tr id="mk476"></tr></progress>
    <div id="mk476"><tr id="mk476"></tr></div>
    <sup id="mk476"><ins id="mk476"></ins></sup>
  • <progress id="mk476"></progress>
    <div id="mk476"></div>
    <div id="mk476"><tr id="mk476"></tr></div>
  • <div id="mk476"></div>
    <dl id="mk476"><s id="mk476"></s></dl><dl id="mk476"></dl><div id="mk476"></div>
  • <div id="mk476"></div>
    <dl id="mk476"><ins id="mk476"></ins></dl>

    .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儀表盤

     

    posted @ 2018-09-23 00:03 Edison Chou 閱讀(...) 評論(...) 編輯 收藏
    江苏11选5软件