.NET Core 微服務架構 Steeltoe 使用(基於 Spring Cloud)

閱讀目錄:css

  • 1. Spring Cloud Eureka 註冊服務及調用
  • 2. Spring Cloud Hystrix 斷路器
  • 3. Spring Cloud Hystrix 指標監控
  • 4. Spring Cloud Config 配置中心

如今主流的開發平臺是微服務架構,在衆多的微服務開源項目中,Spring Cloud 很是具備表明性,但實現平臺是基於 Java,那在 .NET Core 平臺下,如何兼容實現 Spring Cloud 呢?答案就是 Steeltoe,或者你也能夠自行實現,由於 Spring Cloud 各組件基本都是基於 REST HTTP 接口實現,你可使用任何語言實現兼容。html

關於 Steeltoe 的官方介紹:git

Steeltoe is an open source project that enables .NET developers to implement industry standard best practices when building resilient microservices for the cloud. The Steeltoe client libraries enable .NET Core and .NET Framework apps to easily leverage Netflix Eureka, Hystrix, Spring Cloud Config Server, and Cloud Foundry services.github

這邊就不翻譯了,須要注意的幾點:spring

  • Netflix Eureka:服務註冊中心,實現服務註冊,以及服務發現調用。
  • Hystrix:斷路器,實現熔斷處理。
  • Spring Cloud Config Server:分佈式配置中心,主要是讀取配置中心的信息。
  • Cloud Foundry:開源 PaaS 雲平臺,Steeltoe 基本都運行在此平臺上,運行在其餘平臺兼容很差。

另外,Steeltoe 不只支持 .NET Core,還支持 .NET Framework(具體 ASP.NET 4.x 版本)。json

1. Spring Cloud Eureka 註冊服務及調用

項目代碼:https://github.com/yuezhongxin/Steeltoe.Samples/tree/master/Discovery-CircuitBreaker/AspDotNetCoreapi

首先,須要部署一個或多個 Spring Cloud Eureka 服務註冊中心,可使用 Spring Boot 很方便進行實現,這邊就不說了。瀏覽器

建立一個 APS.NET Core 應用程序(2.0 版本),而後 Nuget 安裝程序包:bash

> install-package Pivotal.Discovery.ClientCore

appsettings.json配置文件中,增長下面配置:微信

{
  "spring": { "application": { "name": "fortune-service" } }, "eureka": { "client": { "serviceUrl": "http://192.168.1.32:8100/eureka/", "shouldFetchRegistry": true, //Enable or disable registering as a service "shouldRegisterWithEureka": true, //Enable or disable discovering services "validate_certificates": false }, "instance": { //"hostName": "localhost", "port": 5000 } } }

這樣咱們啓動 APS.NET Core 應用程序,就會將fortune-service服務註冊到 Eureka 中了。

EUREKA-CLIENT是用 Spring Boot 實現的一個服務,下面咱們測試FORTUNE-SERVICE如何調用EUREKA-CLIENT

建立一個IEurekaClientService接口:

public interface IEurekaClientService { Task<string> GetServices(); }

而後再建立IEurekaClientService接口的實現EurekaClientService

public class EurekaClientService : IEurekaClientService { DiscoveryHttpClientHandler _handler; private const string GET_SERVICES_URL = "http://eureka-client/home"; private ILogger<EurekaClientService> _logger; public EurekaClientService(IDiscoveryClient client, ILoggerFactory logFactory = null) :base(options) { _handler = new DiscoveryHttpClientHandler(client, logFactory?.CreateLogger<DiscoveryHttpClientHandler>()); _logger = logFactory?.CreateLogger<EurekaClientService>(); } public async Task<string> GetServices() { _logger?.LogInformation("GetServices"); var client = GetClient(); return await client.GetStringAsync(GET_SERVICES_URL); } private HttpClient GetClient() { var client = new HttpClient(_handler, false); return client; } }

而後建立一個FortunesController

[Route("api")] public class FortunesController : Controller { private IEurekaClientService _eurekaClientService; private ILogger<FortunesController> _logger; public FortunesController(IEurekaClientService eurekaClientService, ILogger<FortunesController> logger) { _eurekaClientService = eurekaClientService; _logger = logger; } // GET: api/services [HttpGet("services")] public async Task<IActionResult> GetServices() { _logger?.LogInformation("api/services"); return Ok(await _eurekaClientService.GetServices()); } }

最後在Startup.cs中,添加以下配置:

public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; private set; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // 加載服務註冊配置 services.AddDiscoveryClient(Configuration); // Add framework services. services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime lifetime) { app.UseStaticFiles(); app.UseMvc(); // 啓動服務註冊 app.UseDiscoveryClient(); } }

而後從新啓動服務,執行命令:

$ curl http://192.168.1.3:5000/api/services
Services(get all by DiscoveryClient): [eureka-client, fortune-service]%

能夠看到,調用是成功的,實際調用的是EUREKA-CLIENT服務的接口,獲取的是 Eureka 註冊中心,全部的註冊服務信息。

ASP.NET 4.x 版本的實現,和上面的相似,這邊就不敘述了,能夠查看項目代碼:https://github.com/yuezhongxin/Steeltoe.Samples/tree/master/Discovery-CircuitBreaker/AspDotNet4

2. Spring Cloud Hystrix 斷路器

項目代碼:https://github.com/yuezhongxin/Steeltoe.Samples/tree/master/Configuration/AspDotNetCore

Spring Cloud Hystrix 的實現,須要咱們對上面的項目進行改造下。

IEurekaClientService增長一個GetServicesWithHystrix接口:

public interface IEurekaClientService { Task<string> GetServices(); Task<string> GetServicesWithHystrix(); }

而後對其進行實現:

public class EurekaClientService : HystrixCommand<string>, IEurekaClientService { DiscoveryHttpClientHandler _handler; private const string GET_SERVICES_URL = "http://eureka-client/home"; private ILogger<EurekaClientService> _logger; public EurekaClientService(IHystrixCommandOptions options, IDiscoveryClient client, ILoggerFactory logFactory = null) :base(options) { _handler = new DiscoveryHttpClientHandler(client, logFactory?.CreateLogger<DiscoveryHttpClientHandler>()); IsFallbackUserDefined = true; _logger = logFactory?.CreateLogger<EurekaClientService>(); } public async Task<string> GetServices() { _logger?.LogInformation("GetServices"); var client = GetClient(); return await client.GetStringAsync(GET_SERVICES_URL); } public async Task<string> GetServicesWithHystrix() { _logger?.LogInformation("GetServices"); var result = await ExecuteAsync(); _logger?.LogInformation("GetServices returning: " + result); return result; } protected override async Task<string> RunAsync() { _logger?.LogInformation("RunAsync"); var client = GetClient(); var result = await client.GetStringAsync(GET_SERVICES_URL); _logger?.LogInformation("RunAsync returning: " + result); return result; } protected override async Task<string> RunFallbackAsync() { _logger?.LogInformation("RunFallbackAsync"); return await Task.FromResult("This is a error(服務斷開,稍後重試)!"); } private HttpClient GetClient() { var client = new HttpClient(_handler, false); return client; } }

而後還須要在Startup.cs中添加註入:

public void ConfigureServices(IServiceCollection services) { // Register FortuneService Hystrix command services.AddHystrixCommand<IEurekaClientService, EurekaClientService>("eureka-client", Configuration); }

而後重啓服務,執行命令:

$ curl http://192.168.1.3:5000/api/services/hystrix
Services(get all by DiscoveryClient): [eureka-client, fortune-service]%

Hystrix 斷路器的做用,體如今調用服務出現問題不能訪問,這邊能夠進行熔斷處理,咱們把eureka-client服務停掉,而後再進行訪問測試:

$ curl http://192.168.1.3:5000/api/services/hystrix
This is a error(服務斷開,稍後重試)!%

能夠看到,Hystrix 起到了做用。

ASP.NET 4.x 版本的實現,和上面的相似,這邊就不敘述了,能夠查看項目代碼:https://github.com/yuezhongxin/Steeltoe.Samples/tree/master/Discovery-CircuitBreaker/AspDotNet4

3. Spring Cloud Hystrix 指標監控

項目代碼:https://github.com/yuezhongxin/Steeltoe.Samples/tree/master/Discovery-CircuitBreaker/AspDotNetCore

在實際應用中,咱們須要對 Hystrix 斷路器進行監控,好比熔斷請求有多少等等,Spring Cloud 中的實現有 Turbine 進行收集,數據展現的話使用 Hystrix Dashboard。

這邊須要咱們先建立一個 Hystrix Dashboard 項目,我使用的 Spring Boot 進行實現,這邊就不敘述了。

咱們須要再對上面的項目進行改造,在Startup.cs中添加配置,以啓動 Hystrix 指標監控。

public class Startup { public void ConfigureServices(IServiceCollection services) { // Add Hystrix metrics stream to enable monitoring 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, ILoggerFactory loggerFactory, IApplicationLifetime lifetime) { // Startup Hystrix metrics stream app.UseHystrixMetricsStream(); } }

另外,還須要配置下Fortune-Teller-Service.csproj

<ItemGroup Condition="'$(BUILD)' == 'LOCAL'"> <PackageReference Include="Steeltoe.CircuitBreaker.Hystrix.MetricsStreamCore" Version="2.0.0" /> <PackageReference Include="RabbitMQ.Client" Version="5.0.1" /> </ItemGroup> <ItemGroup Condition="'$(BUILD)' == ''"> <PackageReference Include="Steeltoe.CircuitBreaker.Hystrix.MetricsEventsCore" Version="2.0.0" /> <PackageReference Include="System.Threading.ThreadPool" Version="4.3.0" /> </ItemGroup>

而後重啓項目,而後瀏覽器打開:http://192.168.1.3:5000/hystrix/hystrix.stream

會看到不斷實時刷新的 Hystrix 指標監控數據了,但顯示並不友好,咱們還須要在儀表盤中顯示。

瀏覽器打開 Hystrix Dashboard(地址:http://192.168.1.31:8170/hystrix),而後在輸入框中輸入:http://192.168.1.3:5000/hystrix/hystrix.stream

而後點擊 Monitor Stream 按鈕,就能夠看到 Hystrix 圖形化監控了(屢次請求http://192.168.1.3:5000/api/services/hystrix,以便測試):

另外,ASP.NET 4.x 版本配置的話,訪問http://192.168.1.3:5000/hystrix/hystrix.stream會報 404 錯誤,緣由是 ASP.NET 4.x 版本暫不支持 Cloud Foundry 之外的平臺,詳情參見

4. Spring Cloud Config 配置中心

項目代碼:https://github.com/yuezhongxin/Steeltoe.Samples/tree/master/Configuration/AspDotNetCore

須要注意的是,這邊只測試 Steeltoe 讀取配置中心數據,須要先開發一個 Spring Cloud Config Server 配置中心服務,這邊就不敘述了。

我使用的 GitHub 做爲配置中心倉庫,xishuai-config-dev.yml配置詳情:

info:  profile: dev  name: xishuai7  password: '{cipher}AQAc+v42S+FW7H5DiATfeeHY887KLwmeBq+cbXYslcQTtEBNL9a5FKbeF1qDpwrscWtGThPsbb0QFUMb03FN6yZBP2ujF29J8Fvm89igasxA7F67ohJgUku5ni9qOsMNqm5juexCTGJvzPkyinymGFYz55MUqrySZQPbRxoQU9tcfbOv9AH4xR/3DPe5krqjo3kk5pK6QWpH37rBgQZLmM7TWooyPiRkuc5Wn/1z6rQIzH5rCLqv4C8J16MAwgU1W+KTrHd4t8hIDAQG9vwkL9SYAvlz38HMKL9utu2g4c9jhAJE/H0mePlp+LDrWSgnC+R+nyH91niaUlwv3wsehP0maYCgEsTJn/3vsNouk5VCy4IGGZbkPubuJM6hE8RP0r4='

注:對password進行了加密處理。

建立一個 APS.NET Core 應用程序(2.0 版本),而後 Nuget 安裝程序包:

> install-package Steeltoe.Extensions.Configuration.ConfigServerCore

appsettings.json配置文件中,增長下面配置:

{
  "spring": { "application": { "name": "xishuai-config" //配置文件名稱 }, "cloud": { "config": { "uri": "http://manager1:8180", //指向配置中心地址 "env": "dev" //配置中心profile } } } }

而後建立一個ConfigServerData模型:

public class ConfigServerData { public Info Info { get; set; } } public class Info { public string Profile { get; set; } public string Name { get; set; } public string Password { get; set; } }

增長HomeController訪問:

public class HomeController : Controller { private IOptionsSnapshot<ConfigServerData> IConfigServerData { get; set; } private IConfigurationRoot Config { get; set; } public HomeController(IConfigurationRoot config, IOptionsSnapshot<ConfigServerData> configServerData) { if (configServerData != null) IConfigServerData = configServerData; Config = config; } public IActionResult Error() { return View(); } public ConfigServerData ConfigServer() { var data = IConfigServerData.Value; return data; } public IActionResult Reload() { if (Config != null) { Config.Reload(); } return View(); } }

Startup.cs中增長配置:

public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables() .AddConfigServer(env); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddOptions(); // Optional: Adds IConfiguration and IConfigurationRoot to service container services.AddConfiguration(Configuration); // Adds the configuration data POCO configured with data returned from the Spring Cloud Config Server services.Configure<ConfigServerData>(Configuration); } }

啓動項目,而後執行命令:

$ curl http://192.168.1.3:5000/home/ConfigServer
{"info":{"profile":"dev","name":"xishuai7","password":"xishuai123"}}

當配置中心數據更新了,能夠訪問http://192.168.1.3:5000/home/Reload進行刷新配置。

ASP.NET 4.x 版本的實現,和上面的相似,這邊就不敘述了,能夠查看項目代碼:https://github.com/yuezhongxin/Steeltoe.Samples/tree/master/Configuration/AspDotNet4

參考資料:

做者:田園裏的蟋蟀 
微信公衆號: 你好架構 
出處: http://www.cnblogs.com/xishuai/  公衆號會不定時的分享有關架構的方方面面,包含並不侷限於:Microservices(微服務)、Service Mesh(服務網格)、DDD/TDD、Spring Cloud、Dubbo、Service Fabric、Linkerd、Envoy、Istio、Conduit、Kubernetes、Docker、MacOS/Linux、Java、.NET Core/ASP.NET Core、Redis、RabbitMQ、MongoDB、GitLab、CI/CD(持續集成/持續部署)、DevOps等等。  本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
相關文章
相關標籤/搜索