14.4 提供特定应用和profile的属性

14.4 提供特定应用和profile的属性

我们可以回忆一下,当Config Server客户端启动的时候,它会发送一个请求到Config Server中,这个请求的路径中会包含应用的名称和激活profile的名称。在提供配置数据的时候,Config Server会考虑这些值,并为客户端返回特定应用和特定profile的配置数据。

从客户端的角度来讲,消费特定应用和特定profile的配置属性与之前没有ConfigServer时并没有太大的差别。应用的名称可以通过spring.application.name属性(这与Eureka识别应用的属性名是相同的)来指定应用的名称。激活的profile可以通过spring.profiles.active属性进行设置(通常会通过名为SPRING_PROFILES_ACTIVE的环境变量进行设置)。

类似的,要提供面向特定应用和profile的属性,Config Server本身也没有太多需要做的。真正比较重要的是,这些属性在支撑Git仓库中该如何进行存储。

14.4.1 提供特定应用的属性

按照我们之前的讨论,使用Config Server的好处之一就是我们可以让应用中的所有微服务共享通用的配置属性。尽管如此,有些属性可能是某个服务特有的,不需要(或者不应该)与所有的服务共享。

除了共享配置之外,Config Server还能管理面向特定应用的配置属性。要实现这一点,需要将配置文件的名称命名为该应用spring.application.name属性的值。

在第13章中,我们使用spring.application.name属性为微服务提供了一个名称,将会注册到Eureka中。相同的属性也可以被配置客户端用来在Config Server中识别自身,这样Config Server就能提供该应用特有的配置。

例如,在Taco Cloud应用中,我们将应用拆分成了多个微服务,分别是ingredient-service、order-service、taco-service和user-service,我们可以在每个服务的spring.application.name属性中指定它的名称。然后,我们就可以根据各个服务的名称在Config Server的Git后端创建对应的配置YAML文件,比如ingredient-service.yml、order-service.yml、taco-service.yml和user-service.yml。图14.3为Gogs Web应用中配置仓库的文件截图。

不管服务应用的名称是什么,所有的应用都会接收来自application.yml文件的配置。但是,在向Config Server发起请求的时候,每个服务应用的spring.application.name的属性值会一同发送(作为请求路径的第一部分),如果存在匹配的属性文件,那么该文件中的属性将会一并返回。如果application.yml中通用的属性与特定应用配置文件中的属性出现重复,那么特定应用的属性会优先生效。

需要注意的是,尽管图14.3显示的是YAML配置文件,实际上,如果在Git仓库中存放properties文件,同样的规则依然有效。

image-20211021172703981

图14.3 应用特定的配置文件会根据每个应用的spring.application.name属性进行命名

14.4.2 提供来自profile的属性

在第5章中,在编写配置属性时,我们曾经看到过利用Spring profile实现特定的属性只有在给定profile处于激活状态时才生效。Spring Cloud Config Server采用与单个Spring Boot应用完全相同的方式,提供了对特定profile属性的支持,包括:

  • 提供特定profile的“.properties”或YAML文件,比如名为application-production.yml的配置文件;
  • 在一个YAML文件中提供多个profile配置组,它们之间以“—”和spring.profiles分割开。

假设我们要通过Config Server为应用所有的微服务共享Eureka配置,现在它只引用了一个Eureka开发实例,对于开发环境来说是很不错的。如果服务要在生产环境运行,那么我们可能想要将它配置成引用多个Eureka节点。

另外,尽管我们在开发环境的配置中将server.port属性设置成了0,但是服务在部署到生产环境的时候,每个服务可能会运行到独立的容器中,容器将8080端口映射到外部的端口,这样就需要所有的应用都监听8080端口。

借助profile,我们可以声明多个配置。除了已经推送到Config Server Git后端的默认application.yml文件之外,我们还可以推送另外一个名为application-production.yml的YAML文件,如下所示:

1
2
3
4
5
6
server:
port: 8080
eureka:
client:
service-url:
defaultZone: http://eureka1:8761/eureka/,http://eureka2:8761/eureka/

在应用从Config Server获取配置信息的时候,Config Server会识别哪个profile处于激活状态(位于请求路径的第二部分)。如果活跃profile是production,那么两个属性集(application.yml和application-production.yml)都将会返回,并且application- production.yml中的属性会优先于application.yml中的默认属性。图14.4为后端Git仓库的显示效果。

image-20211021172817385

图14.4 特定profile的配置文件在命名时后缀与激活profile的名称相同

我们还可以使用同样的命名约定指定适用于特定应用且特定profile的属性,也就是将属性文件命名为应用名加中划线再加profile名的形式。

例如,我们想要为名为ingredient-service的应用设置属性,而且这些属性只有当production profile处于激活状态时才有效。在这种场景下,名为ingredient-service-production.yml的文件可以包含特定应用且特定profile的属性,如图14.5所示。

image-20211021172834285

图14.5 配置文件可以适用于特定应用且特定profile的属性

对于特定profile的属性,在后端Git仓库中,我们也可以使用相同命名约定的properties文件来代替YAML。在YAML文件中,我们可以将特定profile的属性和默认profile的属性放到同一个文件中,中间使用3个中划线和spring.profiles进行分割,相关内容我们在第5章已经学习过了。