01 Spring Cloud Eureka

Wu Jun 2019-01-05 17:03:30
10 微服务 > 0 服务注册与发现

简介

Spring Cloud针对服务注册与发现,进行了一层抽象,并提供了三种实现:Eureka、Consul、Zookeeper。目前支持得最好的就是Eureka,其次是Consul,最后是Zookeeper。Eureka 是封装了 Netflix 的 Eureka 模块,采用了 C-S 的设计架构。

基本架构

Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。

上图简要描述了Eureka的基本架构,由3个角色组成:

  1. 服务注册中心
    • 提供服务注册和发现
  2. 服务提供者
    • 服务提供方
    • 将自身服务注册到Eureka,从而使服务消费方能够找到
  3. 服务消费者
    • 服务消费方
    • 从Eureka获取注册服务列表,从而能够消费服务

服务注册中心

Eureka Server作为一个独立的部署单元,以REST API的形式为服务实例提供了注册、管理和查询等操作。同时,Eureka Server也为我们提供了可视化的监控页面,可以直观地看到各个Eureka Server当前的运行状态和所有已注册服务的情况。

单点配置

  1. pom中添加依赖
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
		</dependency>
  1. 启动类添加@EnableEurekaServer注解启用服务注册中心
  2. 在 application.properties 添加以下配置,作为服务注册中心时禁止默认的自我注册:
spring.application.name=spring-cloud-eureka

server.port=8000
//表示是否将自己注册到Eureka Server,默认为true
eureka.client.register-with-eureka=false
//表示是否从Eureka Server获取注册信息,默认为true
eureka.client.fetch-registry=false

//设置与Eureka Server交互的地址。默认http://localhost:8761/eureka;多个地址可使用 , 分隔。
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

启动工程后,访问:http://localhost:8000/ 可以看到 eureka 可视化监控页面 ##集群 Eureka Server可以运行多个实例来构建集群,通过P2P互相注册,将Eureke Server配置其他可用的serviceUrl就能实现高可用部署。去中心化,每个节点都可被视为其他节点的副本。

Region、Zone

Region、Zone、Eureka集群三者的关系,如下图所示:

region和zone均是AWS的概念。在非AWS环境下,可先简单地将region理解为Eureka集群,zone理解成机房。上图就可以理解为一个Eureka集群被部署在了zone1机房和zone2机房中。

服务提供方

Service Provider本质上是一个Eureka Client。它启动时,会调用服务注册方法,向Eureka Server注册自己的信息。如果服务提供方有多个,服务中心会自动提供负载均衡功能。

  1. pom中添加依赖
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
  1. 启动类加上@EnableDiscoveryClient注解启用服务注册与发现
  2. 配置文件
//指定微服务的名称,后续调用使用
spring.application.name=eureka-provider
//指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

服务消费者

Service Consumer本质上也是一个Eureka Client。它启动后,会从Eureka Server上获取所有实例的注册信息,包括IP地址、端口等,并缓存到本地。 以下展示通过LoadBalancerClient接口手动调用服务,Spring Cloud中提供了Ribbon、Feign等服务调用工具,来简化服务调用:

  1. pom中添加依赖
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
	</dependency>
	<dependency>  
	   <groupId>org.springframework.boot</groupId>  
	   <artifactId>spring-boot-starter-web</artifactId>  
	</dependency>  
  1. 配置application.properties,指定eureka注册中心的地址:
spring.application.name=eureka-consumer

eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
  1. 创建应用主类。初始化RestTemplate,用来真正发起REST请求。@EnableDiscoveryClient注解用来将当前应用加入到服务治理体系中。
@EnableDiscoveryClient
@SpringBootApplication
public class Application {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }
}
  1. 创建一个接口用来消费eureka-client提供的接口:
@RestController
public class DcController {

    @Autowired
    LoadBalancerClient loadBalancerClient;
    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/consumer")
    public String dc() {
        ServiceInstance serviceInstance = loadBalancerClient.choose("eureka-provider");
        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/dc";
        return restTemplate.getForObject(url, String.class);
    }
}