Spring Cloud Eureka

一、Eureka简介

1、背景

传统应用中,组件之间的调用,通过有规范的约束的接口来实现,从而实现不同模块间良好的协作。但是被拆分成微服务后,每个微服务实例的网络地址都可能动态变化,数量也会变化,使得原来硬编码的地址失去了作用。需要一个中心化的组件来进行服务的登记和管理。

2、介绍

Eureka来源于古希腊词汇,意为“发现了”,是一个RESTful风格的服务,是一个用于服务发现和注册的基础组件,是搭建Spring Cloud微服务的前提之一,它屏蔽了Server和client的交互细节,使得开发者将精力放到业务上。

3、注册中心的好处

不用关心有多少提供方。

4、注册中心有哪些

  • Eureka
  • Nacos
  • Consul
  • Zookeeper

二、服务注册与发现

服务注册与发现包括两部分,一个是服务器端,另一个是客户端。

1、服务器端

Server是一个公共服务,为Client提供服务注册和发现的功能,维护注册到自身的Client的相关信息,同时提供接口给Client获取注册表中其他服务的信息,使得动态变化的Client能够进行服务间的相互调用。

功能

  • 服务注册表。记录每个注册上来微服务信息,比如服务名称、IP、端口等。注册表提供 查询API(查询可用的微服务实例)和管理API(用于服务的注册和注销)。
  • 服务注册。将微服务信息注册到注册中心。
  • 服务发现。查询可用微服务列表及其网络地址。
  • 服务检查。定时检查已注册的服务。发现某服务长时间未提供心跳包,就从注册表中移除。

自我保护机制

机制

Eureka在CAP理论当中是属于AP,也就说当产生网络分区时,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.

默认情况下,Eureka Server在一定时间内,没有接收到某个微服务心跳,会将某个微服务注销(90S)。但是当网络故障时,微服务与Server之间无法正常通信,上述行为就非常危险,因为微服务正常,不应该注销。
Eureka Server通过自我保护模式来解决整个问题,当Server在短时间内丢失过多客户端时,那么Server会进入自我保护模式,会保护注册表中的微服务不被注销掉。当网络故障恢复后,退出自我保护模式。

思想

宁可保留有不健康的,也不盲目注销任何健康的服务。

机制触发条件

客户端每分钟续约数量小于客户端总数的85%时会触发保护机制
(当每分钟心跳次数( renewsLastMin ) 小于 numberOfRenewsPerMinThreshold 时,并且开启自动保护模式开关( eureka.server.enable-self-preservation = true ) 时,触发自我保护机制,不再自动过期租约。)
numberOfRenewsPerMinThreshold = expectedNumberOfRenewsPerMin * 续租百分比( eureka.server.renewalPercentThreshold, 默认0.85 )
expectedNumberOfRenewsPerMin = 当前注册的应用实例数 x 2
默认情况下,注册的应用实例每半分钟续租一次,那么一分钟心跳两次,因此 x 2 。
服务实例数:10个,期望每分钟续约数:10 * 2=20,期望阈值:20*0.85=17,自我保护少于17时 触发。

关闭自我保护机制

eureka:
  server:
    enable-self-preservation: false

清理时间

eureka:
  server:
    eviction-interval-timer-in-ms: 3000

2、客户端

Client将自己的服务信息通过一定的方式登记到Server上,并在正常范围内维护自己信息一致性,方便其他服务发现自己,同时可以通过Server获取到自己依赖的其他服务信息,完成服务调用,还内置了负载均衡器,用来进行基本的负载均衡。

  • Register注册。微服务启动时,将自己信息注册到注册中心,注册中心存储这些信息(内存中)。服务启动后第一次心跳提交注册。
  • FetchRegistry拉取注册中心列表。定时去注册中心拉取注册表信息,缓存到client本地。避免每次请求都去注册中心查找。通过获取上一个获取周期和当前获取周期之间的增量更新,可以定期(每30秒)更新此信息。节点信息在服务器中保存的时间更长(大约3分钟),因此获取节点信息时可能会再次返回相同的实例。Eureka客户端自动处理重复的信息。在获得增量之后,Eureka客户机通过比较服务器返回的实例计数来与服务器协调信息,如果由于某种原因信息不匹配,则再次获取整个注册表信息。
  • Renew续约、心跳。微服务与注册中心通过某种机制(心跳)通讯。如果服务器在90秒内(可配置)没有看到更新,它将从其注册表中删除实例。
  • Cancel注销。Eureka客户端在关闭时向Eureka服务器发送取消请求。这将从服务器的实例注册表中删除实例,从而有效地将实例从通信量中取出。
  • TimeLag同步时间延迟。来自Eureka客户端的所有操作可能需要一段时间才能反映到Eureka服务器上,然后反映到其他Eureka客户端上。这是因为eureka服务器上的有效负载缓存,它会定期刷新以反映新信息。Eureka客户端还定期地获取增量。因此,更改传播到所有Eureka客户机可能需要2分钟。
  • Communication Mechanism通讯机制。Http协议下的Rest请求,默认情况下Eureka使用Jersey和Jackson以及JSON完成节点间的通讯
  • 调用服务。解析服务名和具体地址对应关系,找到具体地址发起请求。

三、配置

1、注册中心配置

(1)依赖

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

(2)配置文件

server:
  port: 7901
eureka:
  client:
    # 是否将自己注册到Eureka Server,默认是true,由于当前就是server,所以设置false,表明改服务不会注册到Eureka Server
    register-with-eureka: true
    # 是否从Eureka Server获取注册信息,由于当前是单节点,不需要同步其他节点数据,用false
    fetch-registry: true
    # 是否过滤掉非Up的实例
    # filter-only-up-instances: true
    # 设置服务注册中心的url 用于client和server交流
    service-url:
      defaultZone: http://root:123456@euk2.com:7902/eureka/
    # 客户端拉取服务端注册列表信息间隔 默认30s   对于网关如果需要迅速获取服务注册状态 可以调下 比如5s
    registry-fetch-interval-seconds: 30
  instance:
    hostname: euk1.com
    # 续约 心跳间隔  默认30s
    lease-renewal-interval-in-seconds: 30
    # 续约到期时间  默认90s
    lease-expiration-duration-in-seconds: 90
  # 关闭自我保护机制
  server:
    enable-self-preservation: false

3、注册成功

DiscoveryClient_EUREKASERVER/localhost:EurekaServer:7901 - registration status: 204

4、高可用

多个server之间互相注册

server:
  port: 7902
eureka:
  client:
    # 是否将自己注册到Eureka Server,默认是true,由于当前就是server,所以设置false,表明改服务不会注册到Eureka Server
    register-with-eureka: true
    # 是否从Eureka Server获取注册信息,由于当前是单节点,不需要同步其他节点数据,用false
    fetch-registry: true
    # 是否过滤掉非Up的实例
    # filter-only-up-instances: true
    # 设置服务注册中心的url 用于client和server交流
    service-url:
      defaultZone: http://root:123456@euk1.com:7901/eureka/
    # 客户端拉取服务端注册列表信息间隔 默认30s   对于网关如果需要迅速获取服务注册状态 可以调下 比如5s
    registry-fetch-interval-seconds: 30
  instance:
    hostname: euk2.com
    # 续约 心跳间隔  默认30s
    lease-renewal-interval-in-seconds: 30
    # 续约到期时间  默认90s
    lease-expiration-duration-in-seconds: 90

5、DiscoveryClient

org.springframework.cloud.client.discovery.DiscoveryClient

SpringCloud对注册中心client的抽象封装,提供公用功能。是客户端进行服务发现的核心接口,是spring cloud用来进行服务发现的顶级接口,在common中可以看到其地位。在Netflix Eureka和Consul中都有具体的实现类。

com.netflix.discovery.DiscoveryClient

Eureka注册中心客户端的接口,功能更丰富。

6、多网卡选择

IP注册

# 表示将自己的ip注册到EurekaServer上。不配置或false,表示将操作系统的hostname注册到server
eureka:
  instance:
    prefer-ip-address: true
    # 指定IP
    ip-address: 实际能访问到的Ip

排除其他网卡

spring:
  cloud:
    inetutils:
      ignored-interfaces: "VMware Virtual Ethernet Adapter for VMnet1,Microsoft Wi-Fi Direct Virtual Adapter #2,VMware Virtual Ethernet Adapter for VMnet8"

7、健康检查

由于server和client通过心跳保持 服务状态,而只有状态为UP的服务才能被访问。看eureka界面中的status。
比如心跳一直正常,服务一直UP,但是此服务DB连不上了,无法正常提供服务。
此时,我们需要将微服务的健康状态也同步到server。只需要启动eureka的健康检查就行。这样微服务就会将自己的健康状态同步到eureka。配置如下即可。

手动开启

在client端配置:将自己真正的健康状态传播到server。

eureka:
  client:
    healthcheck:
      enabled: true

client端需要开启Actuator

改变健康状态的Service

/**
 * 自定义修改服务状态
 * actuator上报时会上报修改后的状态
 * 优点:人工控制服务是否可用  应对服务可用 业务不可用的情况  比如短信平台短信数量到达上限
 */
@Service
public class HealthStatusService implements HealthIndicator {
	private Boolean status = true;

	public void setStatus(Boolean status) {
		this.status = status;
	}
	@Override
	public Health health() {
		if (status)
			return new Health.Builder().up().build();
		return new Health.Builder().down().build();
	}
	public String getStatus() {
		return this.status.toString();
	}
}

入口

    @GetMapping("/statusChange")
    public String statusChange(@RequestParam("status") Boolean status) {
        healthStatusService.setStatus(status);
        return healthStatusService.health().getStatus().getCode();
    }

8、安全配置

开启安全验证

spring:
  # 开启安全认证  登录
  security:
    user:
      name: root
      password: 123456

如果服务启动报错

Root name 'timestamp' does not match expected ('instance') for type [simple

是默认开启了防止跨域攻击
手动关闭防止跨域攻击

/**
 * csrf配置类
 * Root name 'timestamp' does not match expected ('instance') for type [simple type, class com.netflix.appinfo.InstanceInfo
 * 关闭防止跨域攻击
 */
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();//关闭csrf认证,否则会报错Root name 'timestamp' does not match expected ('instance')
        super.configure(http);
    }
}

四、Rest服务调用Eureka

1、官方文档 https://github.com/Netflix/eureka/wiki/Eureka-REST-operations

Operation HTTP action Description
Register new application instance POST /eureka/v2/apps/appID Input: JSON/XMLpayload HTTPCode: 204 on success
De-register application instance DELETE /eureka/v2/apps/appID/instanceID HTTP Code: 200 on success
Send application instance heartbeat PUT /eureka/v2/apps/appID/instanceID HTTP Code: * 200 on success * 404 if instanceIDdoesn’t exist
Query for all instances GET /eureka/v2/apps HTTP Code: 200 on success Output: JSON/XML
Query for all appID instances GET /eureka/v2/apps/appID HTTP Code: 200 on success Output: JSON/XML
Query for a specific appID/instanceID GET /eureka/v2/apps/appID/instanceID HTTP Code: 200 on success Output: JSON/XML
Query for a specific instanceID GET /eureka/v2/instances/instanceID HTTP Code: 200 on success Output: JSON/XML
Take instance out of service PUT /eureka/v2/apps/appID/instanceID/status?value=OUT_OF_SERVICE HTTP Code: * 200 on success * 500 on failure
Move instance back into service (remove override) DELETE /eureka/v2/apps/appID/instanceID/status?value=UP (The value=UP is optional, it is used as a suggestion for the fallback status due to removal of the override) HTTP Code: * 200 on success * 500 on failure
Update metadata PUT /eureka/v2/apps/appID/instanceID/metadata?key=value HTTP Code: * 200 on success * 500 on failure
Query for all instances under a particular vip address GET /eureka/v2/vips/vipAddress * HTTP Code: 200 on success Output: JSON/XML * 404 if the vipAddressdoes not exist.
Query for all instances under a particular secure vip address GET /eureka/v2/svips/svipAddress * HTTP Code: 200 on success Output: JSON/XML * 404 if the svipAddressdoes not exist.

2、服务状态

get方式请求
/eureka/status
使用浏览器请求url会返回服务器状态信息

3、注册服务列表信息查看

get方式请求
/eureka/apps

4、服务具体信息查看

get方式请求
/eureka/apps/{appname}/{id}

5、服务续约

put方式请求
/eureka/apps/{appname}/{id}?lastDirtyTimestamp={}&status=up

6、更改服务状态

put方式请求
/eureka/apps/{appname}/{id}/status?lastDirtyTimestamp={}&value={UP/DOWN}

7、删除更新状态

delete方式请求
/eureka/apps/{appname}/{id}/status?lastDirtyTimestamp={}&value={UP/DOWN}

8、元数据

标准元数据

主机名、IP地址、端口号、状态页和健康检查等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。

自定义元数据

可以使用eureka.instance.metadata-map配置,这些元数据可以在远程客户端中访问,但是一般不改变客户端行为,除非客户端知道该元数据的含义。
可以配置在eureka服务器和eureka的客户端上

# 自定义权重
eureka:
  instance:
    metadata-map:
      weight: 6

posted @   -Lucas  阅读(150)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示