服务注册中心Eureka(AP)

Posted by Beyonderwei on 2020-11-15
Words 1.6k and Reading Time 6 Minutes
Viewed Times

Eureka由java语言编写。已经弃用。

一、服务治理

Spring Cloud封装了Netflix公司开发的Eureka来实现服务的治理,但是该模块已经停更。

在传统的RPC远程调用框架中,管理每个服务与服务之间的依赖关系表复杂,所以需要使用服务治理,管理服务与服务之间的依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。

二、 服务注册与发现

Eureka 采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,是服务注册中心,系统中的微服务使用Eureka的客户端连接到Eureka Server来维持新桃连接(一般30秒发送一次),这样就可以通过Eureka Server来监控系统中的各个微服务是否正常运行。

当每个微服务启动的时候,会把自己的服务器的信息(如服务地址、通讯地址)以别名的方式注册到注册中心上,另一方(消费者或服务提供者)以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用、RPC远程调用框架的核心设计思想在于注册中心,因为使用注册中心管理每一个服务与服务之间的一个依赖关系(服务治理的概念)。在任何RPC远程调用框架中,都会有一个注册中心(存放服务地址等信息(接口地址))。

三、新建Eureka服务模块

    1. 新建modle,例如Eureka-server
    1. 在pom中添加依赖:加入如下依赖

      1
      2
      3
      4
      <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
      </dependency>
    1. 新建yml配置文件,配置如下

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      server:
      port: 端口

      eureka:
      instance:
      hostname: localhost #eureka服务端的实例名字
      client:
      register-with-eureka: false #表识不向注册中心注册自己
      fetch-registry: false #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
      service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
    1. 新建主启动类 EurekaMain端口号 在配置类上添加注解

      1
      @EnableEurekaServer // 表明是Eureka的服务端

四、微服务注册到Eureka Server

  1. 依赖引入:微服务pom中引入如下依赖

    1
    2
    3
    4
    5
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
  2. 在配置文件中配置微服务为Eureka 客户端

    1
    2
    3
    4
    5
    6
    eureka:
    client:
    register-with-eureka: true
    fetchRegistry: true
    service-url:
    defaultZone: http://localhost:端口/eureka
  3. 在微服务启动类上添加Eureka client注解

    1
    @EnableEurekaClient

五、Eureka集群配置

修改Eureka 服务的配置文件如下所示

1
2
3
4
5
6
7
8
9
10
11
server:
port: 7001

eureka:
instance:
hostname: xxx.xx .xx.xxx #eureka服务端的域名或地址 和端口
client:
register-with-eureka: false #表示不向注册中心注册自己
fetch-registry: false #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://xxx.xxx.xx.xx:7002/eureka/ #注册到其他Eureka服务的地址和端口

六、 微服务注册到Eureka集群

只需修改服务的配置文件,各个Eureka地址之间用逗号分隔开

1
http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  #集群版

七、服务调用

当存在多个微服务时,客户端需要对Eureka上的服务进行负载均衡的调度,因此需要进行如下配置:

nginx

直接通过给不同的服务端口设置不同的权重或直接轮询访问

RestTemplate

  • 访问地址改为 "http://注册到Eureka的服务名"

  • RestTemplate的配置类的创建方法上添加注解 @LoadBalanced

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Configuration // 配置类注解
    public class ApplicationContextConfig {

    @Bean // 注入后,容器内就有RestTemplate 对象
    @LoadBalanced
    public RestTemplate getRestTemplate() {
    return new RestTemplate();
    }

    }

八、actuator信息完善

为了使注册到Eureka的微服务的信息在Eureka上显示的更加完善,需要对微服务的Eureka的配置中加入如下内容:

1
2
3
4
eureka:
instance:
instance-id: 服务名 # 显示在Eureka监控平台上的服务名字
prefer-ip-address: true # 显示服务的IP地址

九、服务发现

为了使我们可以得到到每个微服务的具体信息,因此需要在服务内写固定接口,用来向外提供这些信息。

  • 在Controller中注入 DiscoveryClient

    1
    2
    @Resource
    private DiscoveryClient discoveryClient;
  • 添加接口,返回所需要的的信息,如下例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @GetMapping(value = "/payment8001/discovery")
    public Object discovery(){
    List<String> services = discoveryClient.getServices();
    for (String element : services) {
    log.info("***** element:"+element);
    }
    List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
    for (ServiceInstance instance : instances) {
    log.info(instance.getServiceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri());
    }
    return this.discoveryClient;
    }
  • 在启动类上添加注解

    1
    @EnableDiscoveryClient
  • 调用接口进行测试,查看log信息。

十、Eureka的自我保护

通常在服务注册后,访问Eureka的时候,会发现有红色的警告信息,代表着Eureka开启了自我保护,警告信息如下:EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

1. 自我保护机制

如果某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的注册信息进行保存,满足了CAP理论中的AP。默认Eureka的自我保护机制是开启的,实际生产环境中也是开启的,即:eureka.server.enable-self-preservation = true ,想要关闭可以在Eureka的配置中将其关闭。

默认情况下,微服务注册后会30秒发送一个心跳包到eureka,若Eureka在默认的90秒钟内没有收到心跳包,则认为服务出现问题,但在保护模式下并不会将其剔除。因为可能服务是健康的,没有收到心跳包可能是因为网络故障。

  • 微服务的Eureka客户端(即微服务本身)配置如下:
1
2
3
4
5
instance:
# 微服务向eureka发送心跳包的间隔 开发时可设置小一些
lease-renewal-interval-in-seconds: 30
# 未收到心跳包的等待上限,超时剔除
lease-expiration-duration-in-seconds: 90
  • 微服务的Eureka服务端(即Eureka注册中心)配置如下:
1
2
3
server:
enable-self-preservation: false # 是否开启保护模式
eviction-interval-timer-in-ms: 2000 # 多久没有接收到心跳包注销的时间 单位毫秒 默认90S

本文为作者原创文章,未经作者允许不得转载。

...

...

00:00
00:00