57

.NET Core + Spring Cloud:服务注册与发现

 5 years ago
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

  1. 在 IntelliJ IDEA 中新建项目,选 Spring Initializr 完成项目创建

  2. 在 pom.xml 添加 eureka-server 的依赖

    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    
  3. 在启动类上添加 EnableEurekaServer 注解

    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaServiceApplication {
    	public static void main(String[] args) {
    		SpringApplication.run(EurekaServiceApplication.class, args);
    	}
    }
    
  4. 修改配置文件,模拟搭建 Eureka Server 集群

    IBNrqya.png!web

    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
    
  5. 修改启动配置

    bE3EVjU.png!web

  6. 启动成功,访问: http://server1:8001 ( 当前 Availability Zones 为 3

    iI3YNvI.png!web

创建 .NET Core 基础服务

基础服务只提供服务,不引用其他服务

  1. 创建 .NET Core WebApi 项目
  2. Nuget 添加 Steeltoe.Discovery.ClientCore 引用(目前版本 2.1.1)
  3. 修改 Startup.cs 的 ConfigureServices 方法,添加 AddDiscoveryClient

    public void ConfigureServices(IServiceCollection services)
    {
    	services.AddDiscoveryClient(Configuration);
    	services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }
    
  4. 修改 Startup.cs 的 Configure 方法,添加 UseDiscoveryClient

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    	if (env.IsDevelopment())
    	{
    		app.UseDeveloperExceptionPage();
    	}
    	app.UseMvc();
    	app.UseDiscoveryClient();
    }
    
  5. 修改配置文件 appsettings.json,更多配置请参考 eureka-client-settings

    {
      "spring": {
    	"application": {
    	  "name": "base-service"
    	}
      },
      "eureka": {
    	"client": {
    	  "serviceUrl": "http://server1:8001/eureka/",
    	  "shouldRegisterWithEureka": true,
    	  "shouldFetchRegistry": false // 不需要获取注册信息,只提供服务
    	},
    	"instance": {
    	  "port": 5001
    	}
      }
    }
    
  6. 修改 program.cs,添加 UseUrls,端口与 appsettings.json port 一致

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    	WebHost.CreateDefaultBuilder(args)
    	.UseUrls("http://*:5001")
    	.UseStartup<Startup>();
    
  7. 再新建一个项目,其他都一致,端口改成 5002

  8. 启动 2 个 base-service 成功后在 Eureka 中查看如下:

    vA3U7vQ.png!web

    EFBvaqy.png!web

    3AbEjyY.png!web

创建 .NET Core 客户端服务

客户端服务需要调用基础服务

与基础服务的主要不同如下:

  1. 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/"
    	}
      }
    }
    
  2. 修改 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>();
    
  3. 添加 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;
    	}
    }
    
  4. 启动 client-service 成功后在 Eureka 中查看如下:

    QFVnQbr.png!web

  5. 通过访问 http://server1:6001/api/values 查看调用 base-service 返回结果,因为 base-service 有 2 个服务,所以会自动做到负载均衡

Friqaee.png!web

Bbqqiq3.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK