Spring Cloud Eureka(服务发现) Netflix

原博客:https://www.cnblogs.com/knowledgesea/p/11208000.html

序言

EurekaNetflix 开发的,一个基于 REST 服务的,服务注册与发现的组件

它主要包括两个组件:Eureka Server 和 Eureka Client

  • Eureka Client:一个Java客户端,用于简化与 Eureka Server 的交互(通常就是微服务中的客户端和服务端)
  • Eureka Server:提供服务注册和发现的能力(通常就是微服务中的注册中心)
image

各个微服务启动时,会通过 Eureka Client 向 Eureka Server 注册自己,Eureka Server 会存储该服务的信息

也就是说,每个微服务的客户端和服务端,都会注册到 Eureka Server,这就衍生出了微服务相互识别的话题

  • 同步:每个 Eureka Server 同时也是 Eureka Client(逻辑上的)
       多个 Eureka Server 之间通过复制的方式完成服务注册表的同步,形成 Eureka 的高可用
  • 识别:Eureka Client 会缓存 Eureka Server 中的信息
       即使所有 Eureka Server 节点都宕掉,服务消费者仍可使用缓存中的信息找到服务提供者(笔者已亲测)
  • 续约:微服务会周期性(默认30s)地向 Eureka Server 发送心跳以Renew(续约)信息(类似于heartbeat)
  • 续期:Eureka Server 会定期(默认60s)执行一次失效服务检测功能
       它会检查超过一定时间(默认90s)没有Renew的微服务,发现则会注销该微服务节点

Spring Cloud 已经把 Eureka 集成在其子项目 Spring Cloud Netflix 里面

关于 Eureka 配置的最佳实践,可参考:https://github.com/spring-cloud/spring-cloud-netflix/issues/203

更多介绍,可参考:http://cloud.spring.io/spring-cloud-static/Camden.SR4/#spring-cloud-eureka-server

单个Eureka Server配置部署实例

pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

注册中心,启动类。

@SpringBootApplication
//创建服务注册中心
@EnableEurekaServer
public class StartMain {
    public static void main(String[] args) {
        SpringApplication.run(StartMain.class, args);
    }
}

注册中心配置文件

## server
server.port=8081

##eureka

#指定环境
eureka.environment=work
# 设置是否将自己作为客户端注册到注册中心(缺省true)
# 这里为不需要(查看@EnableEurekaServer注解的源码,会发现它间接用到了@EnableDiscoveryClient)
eureka.client.register-with-eureka=false
# 设置是否从注册中心获取注册信息(缺省true)
# 因为这是一个单点的EurekaServer,不需要同步其它EurekaServer节点的数据,故设为false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
#是否开启自我保护模式,默认为true。
eureka.server.enable-self-preservation=true
#续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
eureka.server.eviction-interval-timer-in-ms=10000

zone

上面提到 serviceUrl,那就顺便说下 defaultZone

Eureka 有一个 Region 和 Zone 的概念,你可以理解为现实中的大区(Region)和机房(Zone)

Eureka Client 在启动时需要指定 Zone,它会优先请求自己 Zone 的 Eureka Server 获取注册列表

同样的,Eureka Server 在启动时也需要指定 Zone,如果没有指定的话,其会默认使用 defaultZone

详见源码中的 getEurekaServerServiceUrls() 方法:https://github.com/spring-cloud/spring-cloud-netflix/blob/master/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java

note:

现在启动Eureka Server,没有Eureka Client,过一段时间会出现

 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.

这说明Eureka进入保护模式,可通过上述配置去掉,Eureka的保护模式讲解详见:https://github.com/Netflix/eureka/wiki/Understanding-Eureka-Peer-to-Peer-Communication

image

Eureka Client配置部署实现

pom文件

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
    </dependencies>
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

微服务client,启动类。

@SpringBootApplication
@EnableEurekaClient
public class StartMain {
    public static void main(String[] args) {
        SpringApplication.run(StartMain.class, args);
    }
}

微服务client,配置文件

##eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/
eureka.instance.instance-id=${spring.application.name}:${server.port}
# 设置微服务调用地址为IP优先(缺省为false)
eureka.instance.prefer-ip-address=true
# 心跳时间,即服务续约间隔时间(缺省为30s)
eureka.instance.lease-renewal-interval-in-seconds=30
# 发呆时间,即服务续约到期时间(缺省为90s)
eureka.instance.lease-expiration-duration-in-seconds=90

note:

关于续约序言中有讲解,instance-id,是再注册中心页面显示的微服务名。

Eureka 首页显示的微服务名默认为:机器主机名:应用名称:应用端口,也就是:${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}

eureka.client.serviceUrl.defaultZone这个配置可以配置单个注册中心的地址,也可配置多个,逗号隔开

eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8000/eureka/,http://127.0.0.1:8081/eureka/

好啦,这样一个注册中心与微服务就完成啦。启动看看吧。

Eureka Server注册中心(高可用)集群部署

Eureka Server 支持运行多实例,并以互相注册的方式(即伙伴机制),来实现高可用的部署

即每一台 Eureka 都在配置中指定另一个 Eureka 或多个 地址作为伙伴,它在启动时会向伙伴节点获取注册列表

详见:http://cloud.spring.io/spring-cloud-static/spring-cloud.html#_peer_awareness

配置demo

与单Server配置稍作改动,如下三个注册中心ABC

A:127.0.0.1:9001

B:127.0.0.1:9002

C:127.0.0.1:9003

A配置: eureka.client.serviceUrl.defaultZone : http://B/eureka/,http://C/eureka/

B配置: eureka.client.serviceUrl.defaultZone : http://A/eureka/,http://C/eureka/

C配置: eureka.client.serviceUrl.defaultZone : http://B/eureka/,http://A/eureka/

运行不同环境

java -jar .\trade-0.0.1-SNAPSHOT.jar --spring.profiles.active=local

ok啦,试试吧。

配置

服务端

server:
  # 项目端口号
  port: 8761
  # SSL 配置
  ssl:
    # 开启 SSL 认证
    enabled: true
    # 证书别名
    key-alias: eurekaserver
    # 证书存放路径
    key-store: classpath:EurekaServer.p12
    # 证书密码
    key-store-password: 123456
    # 存储类型
    key-store-type: PKCS12

spring:
  application:
    name: demo-eureka-server
  # 开启安全控制
  security:
    user:
      # 用户名
      name: eureka-server
      # 密码
      password: 8e9lx7LuP3436gfsg

eureka:
  instance:
    # 主机名
    hostname: localhost
    # 使用 ip 注册到注册中心实例化
    prefer-ip-address: true
    # 安全端口
    secure-port: ${server.port}
    # 指示是否应为流量启用安全端口
    secure-port-enabled: true
    # 关闭非安全端口
    non-secure-port-enabled: false
    home-page-url: https://${eureka.instance.hostname}:${server.port}/
    status-page-url: https://${eureka.instance.hostname}:${server.port}/actuator/info
    health-check-url: https://${eureka.instance.hostname}:${server.port}/actuator/health
  client:
    # 此实例是否从注册中心获取注册信息
    fetch-registry: false
    # 是否将此实例注册到注册中心
    register-with-eureka: false
    # 注册地址
    service-url:
      # 默认注册分区地址
      defaultZone: https://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    # 同步为空时,等待时间
    wait-time-in-ms-when-sync-empty: 0
    # 是否开启自我保护机制
    ## 在分布式系统设计里头,通常需要对应用实例的存活进行健康检查,这里比较关键的问题就是要处理好网络偶尔抖动或短暂不可用时造成的误判。另外Eureka Server端与Client端之间如果出现网络分区问题,在极端情况下可能会使得Eureka Server清空部分服务的实例列表,这个将严重影响到Eureka server的 availibility属性。因此Eureka server引入了SELF PRESERVATION机制。
    ## Eureka client端与Server端之间有个租约,Client要定时发送心跳来维持这个租约,表示自己还存活着。 Eureka通过当前注册的实例数,去计算每分钟应该从应用实例接收到的心跳数,如果最近一分钟接收到的续约的次数小于指定阈值的话,则关闭租约失效剔除,禁止定时任务剔除失效的实例,从而保护注册信息。
    # 此处关闭可以防止问题(测试环境可以设置为false):Eureka server由于开启并引入了SELF PRESERVATION模式,导致registry的信息不会因为过期而被剔除掉,直到退出SELF PRESERVATION模式才能剔除。
    enable-self-preservation: false
    # 指定 Eviction Task 定时任务的调度频率,用于剔除过期的实例,此处未使用默认频率,频率为:5/秒,默认为:60/秒
    # 有效防止的问题是:应用实例异常挂掉,没能在挂掉之前告知Eureka server要下线掉该服务实例信息。这个就需要依赖Eureka server的EvictionTask去剔除。
    eviction-interval-timer-in-ms: 5000
    # 设置read Write CacheMap的expire After Write参数,指定写入多长时间后过期
    # 有效防止的问题是:应用实例下线时有告知Eureka server下线,但是由于Eureka server的REST API有response cache,因此需要等待缓存过期才能更新
    response-cache-auto-expiration-in-seconds: 60
    # 此处不开启缓存,上方配置开启一个即可
    # use-read-only-response-cache: false
    # 指定每分钟需要收到的续约次数的阈值,默认值就是:0.85
    renewal-percent-threshold: 0.85
    # 续约频率提高,默认:30
    leaseRenewalIntervalInseconds: 10

客户端

server:
  # \u9879\u76EE\u7AEF\u53E3\u53F7
  port: 11200

spring:
  application:
    # Spring Boot \u9879\u76EE\u5B9E\u4F8B\u540D\u79F0
    name: demo-goods

### \u6CE8\u518C\u4E2D\u5FC3\u914D\u7F6E
eureka:
  instance:
    # \u4E3B\u673A\u540D
    hostname: localhost
    # \u4F7F\u7528 ip \u6CE8\u518C\u5230\u6CE8\u518C\u4E2D\u5FC3\u5B9E\u4F8B\u5316
    prefer-ip-address: true
  client:
    secure-port-enabled: true
    ssl:
      key-store: EurekaClient.p12
      key-store-password: 123456
    security:
      user:
        name: eureka-server
        password: 8e9lx7LuP3436gfsg
    # Spring Cloud Eureka \u6CE8\u518C\u4E2D\u5FC3\u5730\u5740
    service-url:
      defaultZone: https://${eureka.client.security.user.name}:${eureka.client.security.user.password}@${eureka.instance.hostname}:8761/eureka/
    # \u9488\u5BF9\u65B0\u670D\u52A1\u4E0A\u7EBF, Eureka client\u83B7\u53D6\u4E0D\u53CA\u65F6\u7684\u95EE\u9898\uFF0C\u5728\u6D4B\u8BD5\u73AF\u5883\uFF0C\u53EF\u4EE5\u9002\u5F53\u63D0\u9AD8Client\u7AEF\u62C9\u53D6Server\u6CE8\u518C\u4FE1\u606F\u7684\u9891\u7387\uFF0C\u9ED8\u8BA4\uFF1A30\u79D2
    registry-fetch-interval-seconds: 30

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342