SpringCloud的Eureka服务注册与发现

149 阅读5分钟

Eureka服务注册组件

  • Eureka 是 Netflix 公司开源的一个服务注册与发现的组件。
  • Eureka 和其他 Netflix 公司的服务组件(例如负载均衡、熔断器、网关等) 一起,被Spring Cloud社区整合为Spring-Cloud-Netflix 模块。
  • Eureka 包含两个组件:Eureka Server (注册中心) 和 Eureka Client (服务提供者、服务消费者)。在Eureka中只有注册中心是当做一种服务存在,其余的微服务模块都是作为客户端的方式提供服务。

一、注册中心概念

  • 服务注册 所有的微服务启动的时候,把自己能够提供的服务名以及自己的ip和port告诉注册中心
  • 服务发现 当一个微服务调用另外一个微服务的时候,先问注册中心拿到想要调用微服务的ip和port,然后直接调用
  • 服务维护 当一个微服务宕机后,从注册中心中删除该服务的全部信息

二、搭建Eureka工程

2.1 搭建EurekaServer工程

所需步骤:

  1. 创建 eureka-server 模块,引入pom文件
        <!-- eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
  1. 搭建EurekaApp的SpringBoot启动模块
@SpringBootApplication
// 启用EurekaServer
// 把注册中心当做一个启用Eureka的Server端
@EnableEurekaServer
public class EurekaApp {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApp.class,args);
    }
}
  1. 引入SpringBoot配置文件
server:
  port: 8761

# eureka 配置
# eureka 一共有4部分 配置
# 1. dashboard:eureka的web控制台配置
# 2. server:eureka的服务端配置
# 3. client:eureka的客户端配置
# 4. instance:eureka的实例配置


eureka:
  instance:
    hostname: localhost # 主机名
# eureka服务端可以注册到自己的服务上   (其中一个服务端也是一个客户端)
  client:
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信 给程序的调用路径
    register-with-eureka: false # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要 默认开始
    fetch-registry: false # 是否需要从eureka中抓取路径。要不要去注册中心获取其他服务的地址 eureka server 不需要的,eureka consumer client 需要 默认开始

2.2 搭建Provider 和 Consumer 称为 Eureka Client

Provider工程
pom文件

    <!-- eureka-client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

ProviderApp

@SpringBootApplication
@EnableDiscoveryClient  // 启动Eureka客户端服务
public class ProviderApp {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApp.class, args);
    }
}

application.yml

server:
  port: 8001
eureka:
  instance:
    hostname: localhost # 主机名
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
spring:
  application:
    name: eureka-provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径

Consumer
pom

    <!-- eureka-client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

ConsumerApp

@EnableDiscoveryClient // 激活DiscoveryClient  发现客户端
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApp {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApp.class,args);
    }
}

application.yml

server:
  port: 9000
eureka:
  instance:
    hostname: localhost # 主机名
  client:
    service-url:
    # defaultZone 就是填写eureka所在的地址  将自己的微服务注册到eureka注册中心中
      defaultZone: http://localhost:8761/eureka
spring:
  application:
    name: eureka-consumer # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径

2.3 Consumer服务通过从Eureka Server中抓取Provider地址,完成远程调用

Consumer

@RestController
@RequestMapping("/order")
public class OrderController {

    // 注入发现客户端对象
    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/add/{id}")
    public Goods add(@PathVariable("id") Integer id){
        // 服务发现
        // 获取客户端的eureka-provider实例 返回的是一个list实例
        List<ServiceInstance> instances = discoveryClient.getInstances("EUREKA-PROVIDER");
        if(instances==null||instances.size()<=0){
            return null;
        }
        // 通过某个策略拿到一个实例
        ServiceInstance serviceInstance = instances.get(0);
        String host = serviceInstance.getHost();
        int port = serviceInstance.getPort();
        System.out.println(host);
        System.out.println(port);
        // 通过实例拿到一个动态的主机名和端口号
        String url="http://"+host+":"+port+"/goods/findById/"+id;
        Goods goods = restTemplate.getForObject(url, Goods.class);
        return goods;
    }
}

三、Euraka文件配置

Eureka包含四个部分的配置

  • instance:当前Eureka Instance实例信息配置
  • client:Eureka Client客户端特性配置
  • server:Eureka Server注册中心特性配置
  • dashboard:Eureka Server注册中心仪表盘配置

下面列举常用的Euraka配置项

eureka:
    instance: #实例配置信息
        hostname: localhost # 主机名
        prefer-ip-address: # 是否将自己的ip注册到eureka中,默认false 注册 主机名
        ip-address: # 设置当前实例ip
        instance-id: # 修改instance-id显示
        lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server发送心跳的时间间隔
        lease-expiration-duration-in-seconds: 90 # 如果90秒内eureka server没有收到eureka client的心跳包,则剔除该服务

eureka:
    client: # 客户端
        service-url:
        	defaultZone:   # eureka服务端地址,将来客户端使用该地址和eureka进行通信
        register-with-eureka: # 是否将自己的路径 注册到eureka上。 相对于服务的提供者是否要注册自己到注册中心上,方便别人直接调用我
        fetch-registry: # 是否需要从eureka中抓取数据。 相对于调用者是否在调用服务的时候,要不要去注册中心获取其他服务的地址

eureka:
    server: #服务端
        enable-self-preservation: #是否开启自我保护机制,默认true  意思是即使注册中心服务与client断开连接,也不从注册列表中删除信息
        eviction-interval-timer-in-ms: 120 # 2月 清理间隔(单位毫秒,默认是60*1000)
	instance:
        lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server发送心跳的时间间隔
        lease-expiration-duration-in-seconds: 90 # 如果90秒内eureka server没有收到eureka client的心跳包,则剔除该服务

eureka:
    dashboard:
        enabled: true # 是否启用eureka web控制台
        path: / # 设置eureka web控制台默认访问路径

四、高可用 (HA集群)

怎么配置Eureka高可用?

  1. 准备两个Eureka Server
  2. 分别进行配置,相互注册
  3. Eureka Client 分别注册到这两个 Eureka Server中
  4. 两个服务端相互注册,当一台宕机时,另外一台顶上去。作为客户端的微服务,分别往两个注册中心注册服务。

Eureka 高可用关注点在哪?

  • 是否能调用通
  • 当一台注册中心宕机后,微服务能否继续访问

4.1 创建eureka-server1

server:
  port: 8761


eureka:
  instance:
    hostname: eureka-server1 # 主机名
  client:
    service-url:
      defaultZone: http://eureka-server2:8762/eureka
    register-with-eureka: true # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
    fetch-registry: true # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要

# 当服务名一样时 会组成集群
spring:
  application:
    name: eureka-server-ha

4.2 创建eureka-server2

server:
  port: 8762


eureka:
  instance:
    hostname: eureka-server2 # 主机名
  client:
    service-url:
      defaultZone: http://eureka-server1:8761/eureka

    register-with-eureka: true # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
    fetch-registry: true # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要
spring:
  application:
    name: eureka-server-ha

4.3 provider工程

server:
  port: 8001
eureka:
  instance:
    hostname: localhost # 主机名
    prefer-ip-address: true # 将当前实例的ip注册到eureka server 中。默认是false 注册主机名
    ip-address: 127.0.0.1 # 设置当前实例的ip
    instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port} # 设置web控制台显示的 实例id
    lease-renewal-interval-in-seconds: 3 # 每隔3 秒发一次心跳包
    lease-expiration-duration-in-seconds: 9 # 如果9秒没有发心跳包,请服务器删除掉我的配置项
  client:
    service-url:
      defaultZone: http://eureka-server1:8761/eureka,http://eureka-server2:8762/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
spring:
  application:
    name: eureka-provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径

4.4 consumer工程

server:
  port: 9000
eureka:
  instance:
    hostname: localhost # 主机名
  client:
    service-url:
      defaultZone:  http://eureka-server1:8761/eureka,http://eureka-server2:8762/eureka  # eureka服务端地址,将来客户端使用该地址和eureka进行通信
spring:
  application:
    name: eureka-consumer # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径