当前位置: 代码迷 >> 综合 >> Spring Cloud Eureka(服务治理)(3)
  详细解决方案

Spring Cloud Eureka(服务治理)(3)

热度:14   发布时间:2023-11-20 01:36:59.0

配置详解

在 Eureka 的服务治理体系中,主要分为服务端和客户端两个不同的角色,服务端为服务注册中心,而客户端为各个提供接口的微服务应用。当我们构建了高可用的注册中心之后,该集群中所有的微服务应用和后续将要介绍的一些基础类应用(如配置中心、API网关等)都可以视为该体系下的一个微服务(Eureka客户端)。服务注册中心也一样,只是高可用环境下的服务注册中心除了服务端之外,还为集群中的其他客户端提供了服务注册的特殊功能。所以,Eureka 客户端的配置对象存在于所有 Eureka 服务治理体系下的应用实例中。在使用使用 Spring cloud Eureka 的过程中, 我们所做的配置内容几乎都是对 Eureka 客户端配置进行的操作。

Eureka 客户端的配置主要分为以下两个方面:

1.服务注册相关的配置信息,包括服务注册中心的地址、服务获取的间隔时间、可用区域等。

2.服务实例相关的配置信息,包括服务实例的名称、IP地址、端口号、健康检查路径等。

Eureka服务端则类似于一个现成的产品,大多数情况下不需要修改它的配置。有兴趣的可以通过org.springframework.cloud.netflix.eureka.service.EurekaServerConfigBean类的定义来进一步了解学习。这些参数均以eureka.server做前缀,而在本地进行调试的时候,可以通过设置该类的enableSelfPreservation参数来关闭注册中心的“自我保护”功能,以防止关闭的实例无法被服务注册中心剔除的问题。

服务注册类配置

  关于服务注册类的配置信息,我们可以通过查看 org.springframework.cloud.netflix.eureka.EurekaClientConfigBean 的源码来获得比官方文档中更为详尽的内容,这些配置信息都已 eureka.client 为前缀。下面针对一些常用的配置信息做进一步的介绍和说明。

  指定注册中心

  在配置文件中通过 eureka.client.service-url 实现。该参数定义如下所示,它的配置值存储在HashMap类型中,并且设置有一组默认值,默认值的key为 defaultZone、value 为 http://localhost:8761/eureka/,类名为 EurekaClientConfigBean。

private Map<String, String> serviceUrl = new HashMap();this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");public static final String DEFAULT_URL = "http://localhost:8761/eureka/";
public static final String DEFAULT_ZONE = "defaultZone";

由于之前的服务注册中心使用了 1111 端口,所以我们做了如下配置,来讲应用注册到对应的 Eureka 服务端中

eureka.client.service-url.defaultZone=http://localhost:1111/eureka/当构建了高可用的服务注册中心集群时,可以为参数的value 值配置多个注册中心的地址(逗号分隔):eureka.client.service-url.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/

另外,为了服务注册中心的安全考虑,很多时候会为服务注册中心加入安全校验。这个时候,在配置serviceUrl时,需要在value 值的 URL 中加入响应的安全校验信息,比如: http://<username>:<password>@localhost:1111/eureka。其中<username>为安全校验信息的用户名,<password>为该用户的密码。

其他配置

下面整理了org.springframework.cloud.netflix.eureka.EurekaClientConfigBean中定义的常用配置参数以及说明和默认值,这些参数均以eureka.client为前缀。

服务实例类配置

  关于服务实例类的配置信息,可以通过查看 org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean 的源码来获取详细内容,这些配置均以 eureka.instance 为前缀。

  元数据

  在 org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean 的配置信息中,有一大部分内容都是对服务实例元数据的配置,元数据是 Eureka 客户端在向注册中心发送注册请求时,用来描述自身服务信息的对象,其中包含了一些标准化的元数据,比如服务名称、实例名称、实例IP、实例端口等用于服务治理的重要信息;以及一些用于负载均衡策略或是其他特殊用途的自定义元数据信息。

在使用SpringCloud Eureka的时候,所有的配置信息都通过org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean 进行加载,但在真正进行服务注册时,还是会包装成 com.netflix.appinfo.InstanceInfo 对象发送给 Eureka 客户端。这两个类的定义非常相似,可以直接查看 com.netflix.appinfo.InstanceInfo 类中的详细定义来了解原声的 Eureka 对元数据的定义。其中,Map<String, String> metaData = new ConcurrentHashMap<String, String>(); 是自定义的元数据信息,而其他成员变量则是标准化的元数据信息。Spring Cloud 的EurekaInstanceConfigBean 对原生元数据对象做了一些配置优化处理,在后续的介绍中会提到这些内容。

  我们可以通过 eureka.instance.<properties>=<value> 的格式对标准化元数据直接进行配置,<properties> 就是 EurekaInstanceConfigBean 对象中的成员变量名。对于自定义元数据,可以通过 eureka.instance.metadataMap.<key>=<value> 的格式来进行配置。

  实例名配置

  实例名,即 InstanceInfo 中的 instanceId 参数,它是区分同一服务中不同实例的唯一标识。在NetflixEureka 的原生实现中,实例名采用主机名作为默认值,这样的设置使得在同一主机上无法启动多个相同的服务实例。所以,在 Spring Cloud Eureka 的配置中,针对同一主机中启动多实例的情况,对实例名的默认命名做了更为合理的扩展,它采用了如下默认规则:

${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id}:${server.port}

对于实例名的命名规则,可以通过eureka.instance.instanceId 参数来进行配置。比如,在本地进行客户端负载均衡调试时,需要启动同一服务的多个实例,如果我们直接启动同一个应用必然会发生端口冲突。虽然可以在命令行中指定不同的server.port 来启动,但这样略显麻烦。可以直接通过设置 server.port=0 或者使用随机数 server.port=${random.int[10000,19999]} 来让Tomcat 启动的时候采用随机端口。但是这个时候会发现注册到 Eureka Server的实例名都是相同的,这会使得只有一个服务实例能够正常提供服务。对于这个问题,就可以通过设置实例名规则来轻松解决:

eureka.instance.instanceId=${spring.application.name}:${random.int}

通过上面的配置,利用应用名+随机数的方式来区分不同的实例,从而实现在同一个主机上,不指定端就能轻松启动多个实例的效果。

端点配置

在InstanceInfo中,我们可以看到一些URL的配置信息,比如homePageUrl、statusPageUrl、healthCheckUrl,它们分别代表了应用主页的URL、状态页的URL、健康检查的URL。其中,状态页和健康检查的URL在Spring Cloud Eureka中默认使用了spring-boot-actuator模块提供的/info端点和/heath端点。虽然我们之前的示例中并没有对这些端点做具体的设置,但实际上这些URL地址的配置非常重要。为了服务的正常运作,我们必须确保Eureka客户端的/heath端点在发送元数据的时候,是一个能够被注册中心访问到的地址,否则服务注册中心不会根据应用的健康检查来更改状态(仅当启用了heathcheck功能时,以该端点信息作为健康检查标准)。而/info端点如果不正确的话,会导致Eureka面板中点击服务实例时,我发访问到服务实例提供的信息接口。

大多数情况下,我们并不需要修改这几个URL的配置,但在一些特殊情况下,比如,为应用设置了context-path,这时,所有spring-boot-actuator模块的监控端点都会增加一个前缀。所以我们就需要做类似如下的配置,为/info和/heath端点也加上类似的前缀信息:

management.context-path=/helloeureka.instance.statusPageUrlPath=${management.context-path}/infoeureka.instance.healthCheckUrlPath=${management.context-path}/heath

 

另外,有时候为了安全考虑,也可能会修改/info和/heath端点的原始路径。这个时候,我们也需要做一些特殊的配置,比如像下面这样:

endpoints.info.path=/appInfoendpoints.heath.path=/checkHealtheureka.instance.statusPageUrlPath=${endpoints.info.path}eureka.instance.healthCheckUrlPath=${endpoints.heath.path}

 

在上面举例的两个示例中,我们使用了eureka.instance.statusPageUrlPath和eureka.instance.healthCheckUrlPath参数这两个配置值有一个共同特点,它们都是用相对路径来进行配置。由于Eureka的服务注册中心默认会以HTTP的方式来访问和暴露这些端点,因此当客户端应用以HTTPS的方式来暴露服务和监控端点时,相对路径的配置方式就无法满足需求了。所以,Spring Cloud Eureka还提供了绝对路径的配置参数,具体实例如下所示:

eureka.instance.statusPageUrl=https://${eureka.instance.hostname}/infoeureka.instance.healthCheckUrl=https://${eureka.instance.hostname}/heatheureka.instance.homePageUrl=https://${eureka.instance.hostname}/

 

健康检测

默认情况下,Eureka中各个服务实例的健康检测并不是通过spring-boot-actuator模块的/health端点来实现的,而是依靠客户端心跳的方式来保持服务实例的存活。在Eureka的服务续约与服务剔除机制下,客户端的健康状态从注册到注册中心开始都会处于UP状态,除非心跳终止一段时间之后,服务注册中心将其剔除。默认的心跳的实现方式可以有效检查客户端进程是否正常运作,但却无法保证客户端应用能够正常提供服务。由于大多数的应用与这些外部资源无法联通的时候,实际上已经不能提供正常的对外服务了,但是因为客户端的心跳依然在运行,所以它还是会被服务消费者调用,而这样的调用实际上并不能获得预期的结果。

在Spring Cloud Eureka中,我们可以通过简单的配置,把Eureka客户端的健康检测交给spring-boot-actouator模块的/health端点,以实现更加全面的健康状态维护。详细的配置步骤如下所示:

  • 在pom.xml中引入spring-boot-starter-actuator模块的依赖。
  • 在application.properties中增加参数配置eureka.client.healthcheck.enabled=true.
  • 如果客户端的/health端点路径做了一些特殊处理,请参考上面介绍的端点配置时的方法进行配置,让服务注册中心可以正确访问到健康检测端点。

其他配置

除了上面介绍的配置参数外,下面整理了一些org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean中定义的配置参数以及对应的说明和默认值,这些参数均以eureka.instance为前缀。

在上面的配置中除了前三个配置参数在需要的时候做一下调整,其他参数配置大多数情况下使用默认值即可。

跨平台支持

    除了 Eureka 的Java 客户端之外, 还有很多其他 语言平台对其的支待, 比如eureka-js-client、python-eureka等

(这里不做过多描述)

这三篇文章主要参考自《Spring Could微服务实战》

  相关解决方案