eureka服务注册与发现

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。

1.eureka简介


Eureka包含两个组件:Eureka Server和Eureka Client。

调用关系说明:

1.服务提供者在启动时,向注册中心注册自己提供的服务。
2.服务消费者在启动时,向注册中心订阅自己所需的服务。
3.注册中心返回服务提供者地址给消费者。
4.服务消费者从提供者地址中调用消费者。
注意! 下面的服务端指:注册中心,客户端指:服务提供者和消费者

Eureka Server:提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,包括主机与端口号、服务版本号、通讯协议等。这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka服务端支持集群模式部署,首尾相连形成一个闭环即可,集群中的的不同服务注册中心通过异步模式互相复制各自的状态,这也意味着在给定的时间点每个实例关于所有服务的状态可能存在不一致的现象。

eureka客户端,主要处理服务的注册和发现。客户端服务通过注册和参数配置的方式,嵌入在客户端应用程序的代码中。在应用程序启动时,Eureka客户端向服务注册中心注册自身提供的服务,并周期性的发送心跳来更新它的服务租约。同时,他也能从服务端查询当前注册的服务信息并把它们缓存到本地并周期行的刷新服务状态。

服务调用
服务消费者在获取服务清单后,通过服务名可以获取具体提供服务的实例名和该实例的元数据信息。因为有这些服务实例的详细信息,所以客户端可以根据自己的需要决定具体调用哪个实例,在Ribbon中会默认采用轮询的方式进行调用,从而实现客户端的负载均衡。

2.服务注册中心搭建

2.1引入pom

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
        <relativePath></relativePath>
 </parent>
 <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
 </dependencies>
 <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

2.2编写启动类

@EnableEurekaServer声明一个注册中心

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(EurekaApplication.class).web(true).run(args);
    }

}

2.3添加配置

# server (eureka 默认端口为:8761)
server.port=8761
# 服务名
spring.application.name=spring-cloud-server
# 是否注册到eureka(eureka本身是不需要再注册到自己的)
eureka.client.register-with-eureka=false
# 是否从eureka获取注册信息
eureka.client.fetch-registry=false
# eureka服务器的地址(注意:地址最后面的 /eureka/ 这个是固定值)
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
#服务失效时间,Eureka多长时间没收到服务的renew操作,就剔除该服务,默认90秒
eureka.instance.leaseExpirationDurationInSeconds=15
#eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒
eureka.server.evictionIntervalTimerInMs=20000
# 自我保护模式(缺省为打开)
eureka.server.enable-self-preservation: true
# 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)       
eureka.server.eviction-interval-timer-in-ms: 5000 

2.4高可用注册中心

Eureka Server在设计的时候就考虑了高可用设计,在Eureka服务治理设计中,所有节点既是服务的提供方,也是服务的消费方,服务注册中心也不例外。

Eureka Server的高可用实际上就是将自己做为服务向其他服务注册中心注册自己,这样就可以形成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用的效果。
Eureka Server的同步遵循着一个非常简单的原则:只要有一条边将节点连接,就可以进行信息传播与同步。可以采用两两注册的方式实现集群中节点完全对等的效果,实现最高可用性集群,任何一台注册中心故障都不会影响服务的注册与发现。

spring boot允许你通过命名约定按照一定的格式(application-{profile}.properties)来定义多个配置文件,然后通过在application.properyies通过spring.profiles.active来具体激活一个或者多个配置文件。这里我们不在application.properyies文件中指定spring.profiles.active属性,我们通过jar -jar的方式指定这个属性。
这里我们新建如下俩个文件

application-peer1.properties:
#集群时使用命令行加参数进行启动,两两注册互为发现 :java -jar eureka-server-1.0.0.jar --spring.profiles.active=peer1
spring.application.name=eureka-server
server.port=1111
#eureka.instance.hostname=peer1
eureka.client.serviceUrl.defaultZone=http://localhost:1112/eureka/
application-peer2.properties:
#集群时使用命令行加参数进行启动,两两注册互为发现 :java -jar eureka-server-1.0.0.jar --spring.profiles.active=peer2
spring.application.name=eureka-server
server.port=1112
#eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

打包eurekaserver我们通过Java -jar 方式启动俩个服务

java -jar eureka-server-1.0.0.jar --spring.profiles.active=peer1

java -jar eureka-server-1.0.0.jar --spring.profiles.active=peer2

打开浏览器查看:



3客户端配置

3.1添加pom 依赖

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

3.2添加注解

启动类添加@EnableDiscoveryClient或者@EnableEurekaClient
1,@EnableDiscoveryClient注解是基于spring-cloud-commons依赖,并且在classpath中实现;
2,@EnableEurekaClient注解是基于spring-cloud-netflix依赖,只能为eureka作用;
如果你的classpath中添加了eureka,则它们的作用是一样的。

3.3配置

服务提供者:
# server
server.port=1234
# 客户端在注册时就会使用自己的ip地址而不是主机名(客户端自身加)
eureka.instance.preferIpAddress=true
eureka.client.registerWithEureka=true
#是否需要去检索寻找服务,默认是true
eureka.client.fetchRegistry=true
#renew频率,向Eureka服务发送renew信息,默认30秒
eureka.instance.leaseRenewalIntervalInSeconds=10

# 心跳时间,即服务续约间隔时间(缺省为30s)
#eureka.instance.lease-renewal-interval-in-seconds: 5     
# 发呆时间,即服务续约到期时间(缺省为90s)
#eureka.instance.lease-expiration-duration-in-seconds: 10  
# 开启健康检查(依赖spring-boot-starter-actuator)
#eureka.client.healthcheck.enabled: true     

# 提供者服务名
spring.application.name=service-test
# eureka
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
消费者(一般需要连接其他微服务的服务或者gateway/zuul)
# server 
server.port=8888
# 消费者服务名
spring.application.name=zuul
#client隔多久去拉取服务注册信息,默认为30秒,zuul需要将该时间缩短以便迅速获取其他服务信息
eureka.client.registry-fetch-interval-seconds=5
# eureka
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

4.eureka配置项解读:

在注册服务之后,服务提供者会维护一个心跳用来持续高速Eureka Server,“我还在持续提供服务”,否则Eureka Server的剔除任务会将该服务实例从服务列表中排除出去。我们称之为服务续约。
面是服务续约的两个重要属性:

(1)eureka.instance.lease-expiration-duration-in-seconds
leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance。
默认为90秒
如果该值太大,则很可能将流量转发过去的时候,该instance已经不存活了。
如果该值设置太小了,则instance则很可能因为临时的网络抖动而被摘除掉。
该值至少应该大于leaseRenewalIntervalInSeconds

(2)eureka.instance.lease-renewal-interval-in-seconds
leaseRenewalIntervalInSeconds,表示eureka client发送心跳给server端的频率。如果在leaseExpirationDurationInSeconds后,server端没有收到client的心跳,则将摘除该instance。除此之外,如果该instance实现了HealthCheckCallback,并决定让自己unavailable的话,则该instance也不会接收到流量。
默认30秒

eureka.client.registry-fetch-interval-seconds :表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒
eureka.server.enable-self-preservation
是否开启自我保护模式,默认为true。
默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。
Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。
eureka.server.eviction-interval-timer-in-ms
eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒

推荐阅读更多精彩内容