持续更新在工作中使用eureka遇到的问题以及一些配置说明

—-集成篇—-

Eureka为我们提供服务发现的能力, 在微服务体系中, 有很重要的地位(最核心和基础的组件), 主要用来实现各个微服务之间的自动化注册与彼此可见(发现)

Spring cloud Eureka是对netflix Eureka的二次封装, 使其成为spring cloud微服务治理体系中的一员

eureka在应用时, 要两种模式互相配合使用, 一种为服务注册中心(discover-center), 一种为服务提供者(product)

在springboot环境中集成eureka非常简单, 具体步骤如下:

注册中心和服务提供者配置是不一样的, 一定要注意下

1. 引入依赖(需要配置springCloud依赖管理)

使用springboot脚手架新建两个springboot空项目(一个是注册中心, 一个是服务提供者)

<!-- 注册中心依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 服务提供者依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2. 在启动类上加入注解

//注册中心
@EnableEurekaServer

//服务提供者
@EnableEurekaClient

3. 配置yml文件

注册中心配置

spring:
  application:
    #应用名称
    name: GOMYCK-EUREKA-SERVER
  profiles:
    active: pro
server:
  port: 8888
eureka:
  client:
    #是否把当前应用注册到eureka
    register-with-eureka: false
    #是否获取注册列表
    fetch-registry: false
    #eureka服务地址, 可以有多个, 当有多个时, 会形成集群服务, eureka共享注册表
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #,http://eureka-8889.com:8889/eureka/
  instance:
    hostname: eureka-8888.com
    #实例信息
    instance-id: ${spring.application.name}-@project.version@-${spring.cloud.client.ip-address}:${server.port}
    #是否以IP方式注册, 如果是否的话, 在通讯时会用hostname作为请求地址
    prefer-ip-address: true
  server:
    #服务清理周期(毫秒)
    eviction-interval-timer-in-ms: 5000
    #是否开启保护模式, 如果开启, 当掉线率达到85% ? (具体是多少忘了), eureka将停止从服务列表中下线服务信息
    enable-self-preservation: false 

服务提供者配置

spring:
  application:
    name: GOMYCK-AUTH-CENTER
  profiles:
    active: pro
eureka:
  client:
    #是否把当前应用注册到eureka
    register-with-eureka: false
    #是否获取注册列表
    fetch-registry: false
    #eureka服务地址, 可以有多个, 当有多个时, 会形成集群服务, eureka共享注册表
    service-url:
      defaultZone: http://eureka-8888.com:8888/eureka/ #, http://eureka-8889.com:8889/eureka/
    enabled: true
  instance:
    hostname: gomyck-auth.com
    instance-id: ${spring.application.name}-@project.version@-${spring.cloud.client.ip-address}:${server.port}
    #是否以IP方式注册, 如果是否的话, 在通讯时会用hostname作为请求地址
    prefer-ip-address: true
    #心跳时间
    lease-renewal-interval-in-seconds: 5
    #服务时效时间 (这个值要比心跳时间大, 如果上次心跳到下次心跳时间超过这个值, eureka注册中心将会下线改服务)
    lease-expiration-duration-in-seconds: 10

4.配置本机hosts

windows:

  1. 打开文件夹: C:\Windows\System32\drivers\etc
  2. 把文件夹下的hosts复制到桌面, 然后打开复制的hosts
  3. 在文件最后, 加入配置: 192.168.x.xxx(IP根据实际情况写) eureka-8888.com

macOS:

  1. 使用vim打开(需要使用sudo) /etc/hosts
  2. 在文件最后, 加入配置: 192.168.x.xxx(IP根据实际情况写) eureka-8888.com

hosts文件修改后, 需要重启浏览器

5.启动服务

访问 http://eureka-8888.com:8888 即可进入注册中心管理页面

—-总结篇—-

1.eureka注册中心在非集群的情况下, 不要开启下面两个配置, 否则有一些诡异的异常, 我在实际生产中遇到的问题是, 不能请求未知的服务

can not … unknown server (具体的异常名字记不清了)

register-with-eureka: false
fetch-registry: false

2.eureka-client在与feign组合使用时, feign由于底层为ribbon, 而ribbon的服务列表在有eureka服务时, 会自动使用eureka的服务列表, 所以, 使用feign可以直接与其他服务提供者直接通信, 实际上我们也是这么使用的, 但是在新项目集成原有老的feign项目时, 可以使用当前项目 中的ribbon实例, 来作为feign的构建者client, 这样可以达到直接路由请求的效果

官网是这么描述的:

When Eureka is used in conjunction with Ribbon (that is, both are on the classpath), the ribbonServerList is overridden with an extension of DiscoveryEnabledNIWSServerList, which populates the list of servers from Eureka. It also replaces the IPing interface with NIWSDiscoveryPing, which delegates to Eureka to determine if a server is up. The ServerList that is installed by default is a DomainExtractingServerList. Its purpose is to make metadata available to the load balancer without using AWS AMI metadata (which is what Netflix relies on). By default, the server list is constructed with “zone” information, as provided in the instance metadata (so, on the remote clients, set eureka.instance.metadataMap.zone). If that is missing and if the approximateZoneFromHostname flag is set, it can use the domain name from the server hostname as a proxy for the zone. Once the zone information is available, it can be used in a ServerListFilter. By default, it is used to locate a server in the same zone as the client, because the default is a ZonePreferenceServerListFilter. By default, the zone of the client is determined in the same way as the remote instances (that is, through eureka.instance.metadataMap.zone).

//loadBalancerFeignClient 在eureka环境的工程中, 是自动注入的, 因为eureka服务中也存在ribbon实例
@Bean
public XXXClient createRestApi(Client loadBalancerFeignClient) {
    XXXClient xxxClient = Feign.builder().client(loadBalancerFeignClient)
            .options(new Request.Options(10000, 60000)).retryer(Retryer.NEVER_RETRY)
            .encoder(new QueryEncoder())
            .decoder(new JacksonDecoder())
            .errorDecoder(new XXXDecoder())
            .target(XXXClient.class, "URI[根据实际情况替换]");
    return xxxClient;
}

3.实际生产中, 我发现 eureka 对服务列表的维护存在一定的延迟, 原因有两方面

没有修改 eureka server 的只读服务列表的刷新间隔

没有修改 eureka client 的 ribbon 服务列表的刷新间隔 & 没有修改 eureka client 的服务拉取时间间隔

修改如下, 可快速感知服务上下线状态:


eureka: 
  server:
    eviction-interval-timer-in-ms: 3000 #主动失效时间
    enable-self-preservation: false
    responseCacheUpdateIntervalMs: 3000 #只读路由表更新时间

eureka:
  client:
    registry-fetch-interval-seconds: 5 #注册表拉取时间周期

ribbon:
  ServerListRefreshInterval: 5000 #服务列表刷新时间
  


相关文章:
⤧  上一篇 Maven 配置篇 ⤧  下一篇 Zuul 应用手册