.NET Core 微服务架构 Steeltoe 使用(基于 Spring Cloud)
阅读目录:
- 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 接口实现,你可以使用任何语言实现兼容。
关于 Steeltoe 的官方介绍:
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.
这边就不翻译了,需要注意的几点:
- Netflix Eureka:服务注册中心,实现服务注册,以及服务发现调用。
- Hystrix:断路器,实现熔断处理。
- Spring Cloud Config Server:分布式配置中心,主要是读取配置中心的信息。
- Cloud Foundry:开源 PaaS 云平台,Steeltoe 基本都运行在此平台上,运行在其他平台兼容不好。
另外,Steeltoe 不仅支持 .NET Core,还支持 .NET Framework(具体 ASP.NET 4.x 版本)。
1. Spring Cloud Eureka 注册服务及调用
项目代码:https://github.com/yuezhongxin/Steeltoe.Samples/tree/master/Discovery-CircuitBreaker/AspDotNetCore
首先,需要部署一个或多个 Spring Cloud Eureka 服务注册中心,可以使用 Spring Boot 很方便进行实现,这边就不说了。
创建一个 APS.NET Core 应用程序(2.0 版本),然后 Nuget 安装程序包:
> 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://steeltoe.io/
- https://github.com/SteeltoeOSS/Samples
- Enabling .NET Core Microservices with Steeltoe and Pivotal Cloud Foundry
- .net framework 4.5 +steeltoe+ springcloud(二) 实现服务发现与调用功能
.NET Core 微服务架构 Steeltoe 使用(基于 Spring Cloud)的更多相关文章
- 漫谈微服务架构:什么是Spring Cloud,为何要选择Spring Cloud
Spring Cloud是基于Spring Boot的,因此还在使用SpringMVC的同学要先了解Spring Boot.先上一段官话,Spring Cloud是一个基于Spring Boo ...
- 微服务架构 Steeltoe
.NET Core 微服务架构 Steeltoe 使用(基于 Spring Cloud) https://www.cnblogs.com/xishuai/p/steeltoe-and-spring-c ...
- .NET Core微服务架构学习与实践系列文章索引目录
一.为啥要总结和收集这个系列? 今年从原来的Team里面被抽出来加入了新的Team,开始做Java微服务的开发工作,接触了Spring Boot, Spring Cloud等技术栈,对微服务这种架构有 ...
- 微服务架构 | 4.2 基于 Feign 与 OpenFeign 的服务接口调用
目录 前言 1. OpenFeign 基本知识 1.1 Feign 是什么 1.2 Feign 的出现解决了什么问题 1.3 Feign 与 OpenFeign 的区别与对比 2. 在服务消费者端开启 ...
- Spring Cloud 微服务三: API网关Spring cloud gateway
前言:前面介绍了一款API网关组件zuul,不过发现spring cloud自己开发了一个新网关gateway,貌似要取代zuul,spring官网上也已经没有zuul的组件了(虽然在仓库中可以更新到 ...
- .net core 微服务架构-docker的部署-包括网关服务(Ocelot)+认证服务(IdentityServer4)+应用服务(asp.net core web api)
本文主要介绍通过Docker来部署通过.Net Core开发的微服务架构,部署的微服务主要包括统一网关(使用Ocelot开发).统一认证(IdentityServer4).应用服务(asp.net c ...
- .NET Core 微服务架构-Docker部署
本文主要介绍通过Docker来部署通过.NET Core开发的微服务架构,部署的微服务主要包括统一网关(使用Ocelot开发).统一认证(IdentityServer4).应用服务(ASP.NET C ...
- 微服务架构 | 5.2 基于 Sentinel 的服务限流及熔断
目录 前言 1. Sentinel 基础知识 1.1 Sentinel 的特性 1.2 Sentinel 的组成 1.3 Sentinel 控制台上的 9 个功能 1.4 Sentinel 工作原理 ...
- 微服务架构 | 7.1 基于 OAuth2 的安全认证
目录 前言 1. OAuth2 基础知识 1.1 安全性的 4 个组成部分 1.2 OAuth2 的工作原理 1.3 OAuth2 规范的 4 种类型的授权 1.4 OAuth2 的优势 1.5 OA ...
随机推荐
- C++多线程join同步问题
其实就是想记录一下自己的想法,就是关于多个线程的执行顺序的思考.之前一直觉得std::thread::join会阻塞其他线程的运行,其实并不是这样子的.举个例子 std::vector<std: ...
- 错误: Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for studentDao.insert
详细错误信息: org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: java. ...
- 编译问题解决:LINK : fatal error LNK1104: 无法打开文件“*.dll”
一.引言 编译项目的时候,总会遇到些奇怪的问题,比如说以下这种: LINK : fatal error LNK1104: 无法打开文件“..\bin\ICPRegistration.dll” 我在编译 ...
- [原创]..\OBJ\gpio.axf: error: L6002U: Could not open file ..\obj\gpio.o: No such file
可以通过: 可以通过修改用户环境变量路径的方法解决:方法:右键我的电脑\属性\高级系统设置\环境变量\用户环境变量,找到变量TEMP和TMP,将变量值中的“%USERPROFILE%”使用“C:\us ...
- 创建、使用SpringBoot项目
>>>>>>>>>>>>>>>>>>>>>>>>> ...
- keepalived介绍及工作原理
keepalived介绍keepalived观察其名可知,保持存活,在网络里面就是保持在线了,也就是所谓的高可用或热备,它集群管理中保证集群高可用的一个服务软件,其功能类似于heartbeat,用来防 ...
- 运营-赵本山最近有点烦:二人转产业链滑铁卢 关联公司IPO预披露
http://news.cecb2b.com/info/20141117/2868962.shtml
- DS博客作业01—日期抽象数据类型设计与实现
1.本章学习总结 1.1 思维导图 1.2学习体会 开学就来了个大作业,还要求用的是c++语法,作为一个只听过没学过的未知语法,靠着CSDN和寝室大佬的帮助下渐渐地了解了一些c++的使用,现在也可以使 ...
- notes for lxf(四)
类名首字母通常大写 创建实例 类名 +() __init__方法 创建实例时把一些属性绑上去 __init__方法第一参数永远是self 表示船舰的实例本身 类是实例的模板 实例是一个一个具体的对象 ...
- python基础day1
一.python介绍 1.1简介 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum ...