阅读目录: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
参考资料: