.NET Core + Spring Cloud:服务注册与发现
source link: http://beckjin.com/2019/01/20/aspnet-eureka/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
毫无疑问,微服务架构是目前的主流,在微服务架构下,服务治理、负载均衡、服务熔断、配置中心、API网关 等都是需要关注的问题,当然不是非要全部完善后才能进行微服务开发,在很多项目团队中,初期可能会将某个服务部署成集群,然后通过 Nginx 代理做到负载均衡提供服务,但随着微服务体量逐渐庞大,以上提到需要关注的问题就越来越明显。在 .NET Core 环境下,目前比较流行的微服务架构:Consul(服务治理、配置中心)+ Polly(服务熔断)+ Ocelot(API网关),当然这只是一种组合方式。参考: NanoFabric
今天主要介绍一下如何通过 Spring Cloud 下的 Eureka 来实现服务注册与发现,Spring Cloud 是 Java 平台提供的一套解决方案,提供了微服务的基础功能,包括 Eureka(服务治理)、Config(配置中心)、Hystrix(服务熔断)、Zuul(API网关)等。
至于为什么要将 .NET Core 服务融合 Spring Cloud 来部署,毫无疑问,这只是一种结合方案,如果团队是 Java + .NET, 如果恰好需要,尝试一下也为何不可。
Steeltoe
Steeltoe 是 .NET 与 Spring Cloud 结合的桥梁,Steeltoe 客户端库使 .NET Core 和 .NET Framework 应用程序能够轻松利用 Spring Cloud 的 Eureka、Hystrix、Config Server、云平台服务 等核心组件。更多资料请参考官方文档: http://steeltoe.io/docs/
搭建 Eureka Server
-
在 IntelliJ IDEA 中新建项目,选 Spring Initializr 完成项目创建
-
在 pom.xml 添加 eureka-server 的依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
-
在启动类上添加 EnableEurekaServer 注解
@EnableEurekaServer @SpringBootApplication public class EurekaServiceApplication { public static void main(String[] args) { SpringApplication.run(EurekaServiceApplication.class, args); } }
-
修改配置文件,模拟搭建 Eureka Server 集群
application.yml
spring: application: # 服务名 name: eureka-service profiles: # 默认使用 server1 配置 active: server1
application-server1.yml
server: port: 8001 eureka: instance: hostname: server1 # 超过这个时间没收到心跳就剔除这个服务,这个配置一般为服务刷新时间配置的三倍,默认90s lease-expiration-duration-in-seconds: 15 # 服务刷新时间,默认30s lease-renewal-interval-in-seconds: 5 client: service-url: defaultZone: http://server1:8001/eureka/,http://server2:8002/eureka/,http://server3:8003/eureka/ # eureka client 刷新本地缓存时间,默认30s registry-fetch-interval-seconds: 5 server: # eureka server 刷新 readCacheMap 的时间,client 读取的是 readCacheMap,默认30s response-cache-update-interval-ms: 3000 # 服务下线任务定时,默认60s eviction-interval-timer-in-ms: 3000
application-server2.yml 和 application-server3.yml 与 server1 类似,只需 port 和 hostname 作调整。hostname 对应的名称需要修改电脑的 C:\Windows\System32\drivers\etc\HOSTS 文件添加映射关系
127.0.0.1 server1 127.0.0.1 server2 127.0.0.1 server3
-
修改启动配置
-
启动成功,访问: http://server1:8001 ( 当前 Availability Zones 为 3 )
创建 .NET Core 基础服务
基础服务只提供服务,不引用其他服务
- 创建 .NET Core WebApi 项目
- Nuget 添加 Steeltoe.Discovery.ClientCore 引用(目前版本 2.1.1)
-
修改 Startup.cs 的 ConfigureServices 方法,添加 AddDiscoveryClient
public void ConfigureServices(IServiceCollection services) { services.AddDiscoveryClient(Configuration); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }
-
修改 Startup.cs 的 Configure 方法,添加 UseDiscoveryClient
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); app.UseDiscoveryClient(); }
-
修改配置文件 appsettings.json,更多配置请参考 eureka-client-settings
{ "spring": { "application": { "name": "base-service" } }, "eureka": { "client": { "serviceUrl": "http://server1:8001/eureka/", "shouldRegisterWithEureka": true, "shouldFetchRegistry": false // 不需要获取注册信息,只提供服务 }, "instance": { "port": 5001 } } }
-
修改 program.cs,添加 UseUrls,端口与 appsettings.json port 一致
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseUrls("http://*:5001") .UseStartup<Startup>();
-
再新建一个项目,其他都一致,端口改成 5002
-
启动 2 个 base-service 成功后在 Eureka 中查看如下:
创建 .NET Core 客户端服务
客户端服务需要调用基础服务
与基础服务的主要不同如下:
-
appsettings.json,拉取注册信息(shouldFetchRegistry=true),添加 base-service url
{ "spring": { "application": { "name": "client-service" } }, "eureka": { "client": { "serviceUrl": "http://server1:8001/eureka/", "shouldRegisterWithEureka": true, "shouldFetchRegistry": true }, "instance": { "port": 6001 } }, "services": { "base-service": { "url": "http://base-service/" } } }
-
修改 Startup.cs 的 ConfigureServices 方法
services.AddDiscoveryClient(Configuration); services.AddTransient<DiscoveryHttpMessageHandler>(); // 指定 BaseService 内使用的 HttpClient 在发送请求前通过 DiscoveryHttpMessageHandler 解析 BaseAddress 为已注册服务的 host:port services.AddHttpClient("base-service", c => { c.BaseAddress = new Uri(Configuration["services:base-service:url"]); }) .AddHttpMessageHandler<DiscoveryHttpMessageHandler>() .AddTypedClient<IBaseService, BaseService>();
-
添加 BaseService 的封装
public interface IBaseService { Task<string> GetValueAsync(); } public class BaseService : IBaseService { private readonly HttpClient _httpClient; public BaseService(HttpClient httpClient) { _httpClient = httpClient; } public async Task<string> GetValueAsync() { var result = await _httpClient.GetStringAsync("api/values"); return result; } }
-
启动 client-service 成功后在 Eureka 中查看如下:
-
通过访问 http://server1:6001/api/values 查看调用 base-service 返回结果,因为 base-service 有 2 个服务,所以会自动做到负载均衡
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK