quarkus实战之八:profile

锦通  金牌会员 | 2023-7-28 07:46:51 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 918|帖子 918|积分 2754

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览


  • 本文是《quarkus实战》系列的第八篇,经过前面的学习,咱们对配置有了足够了解,但问题也随之而来:如何让应用以最小的改动同时运行在不同环境(如本地、测试、生产等)
  • 举个例子,下面是个简化版配置文件,有两个配置项,第一个固定不变,第二个随环境变化各不相同:
  1. # 这个配置信息在各个环境中都是相同的
  2. greeting.message=hello
  3. # 这个配置信息在各个环境中都不一样
  4. quarkus.http.port=9090
复制代码

  • 在实际部署的时候,如何达到要求呢?quarkus.http.port的值随着环境变化
  • 不同环境用不同配置文件是一种方法,但会导致配置文件数量上升,并且greeting.message在各环境都是一样的,这就出现了冗余,除了维护成本增加,在管理过程中容易出错
  • 除了多个配置文件,还有种方法可以满足要求,并且不需要多个配置文件,这就是今天要聊的profile
演示代码


  • 创建一个demo工程,参考下面的命令,这样的工程会自带一个web服务类HobbyResource.java
  1. mvn "io.quarkus:quarkus-maven-plugin:create" \
  2.   -DprojectGroupId="com.bolingcavalry" \
  3.   -DprojectArtifactId="hello-quarkus" \
  4.   -DprojectVersion="1.0-SNAPSHOT" \
  5.   -DclassName="HobbyResource" \
  6.   -Dpath="actions"
复制代码

  • 用下面这段代码来演示配置是否生效,可见用了一个配置项greeting.message,所以我们需要配置它的值才行
  1. package com.bolingcavalry;
  2. import org.eclipse.microprofile.config.inject.ConfigProperty;
  3. import javax.ws.rs.GET;
  4. import javax.ws.rs.Path;
  5. import javax.ws.rs.Produces;
  6. import javax.ws.rs.core.MediaType;
  7. import java.time.LocalDateTime;
  8. @Path("/actions")
  9. public class HobbyResource {
  10.     @ConfigProperty(name = "greeting.message")
  11.     String message;
  12.     @GET
  13.     @Produces(MediaType.TEXT_PLAIN)
  14.     public String hello() {
  15.         return "Hello RESTEasy, " + LocalDateTime.now() + " [" + message + "]";
  16.     }
  17. }
复制代码

  • 配置文件是hello-quarkus/src/main/resources/application.properties
  1. # 这个配置信息在各个环境中都是相同的
  2. greeting.message=hello
复制代码
设定profile


  • profile自己是个普通的配置项,例如在application.properties文件中,是这样设置profile的
  1. # 这个配置信息在各个环境中都是相同的
  2. quarkus.profile=dev
  3. # 如果不指定profile,就使用此配置
  4. quarkus.http.port=8080
复制代码

  • 也可以在System properties中设置,如下所示,如此以来,不同环境只有启动命令不同,配置文件可以完全不用修改:
  1. java -Dquarkus.profile="dev" -jar hello-quarkus-1.0-SNAPSHOT-runner.jar
复制代码
同一个配置项在不同profile时的值


  • profile的格式是%{profile-name}.config.name
  • 以刚才的配置为例,quarkus.http.port配置项共出现三次,前两次带有前缀,格式是百分号+profile名称+点号,如下所示
  1. # 指定当前profilequarkus.profile=dev# 这个配置信息在各个环境中都是相同的
  2. greeting.message=hello# 如果profile为dev,就是用此配置%dev.quarkus.http.port=8081# 如果profile为production,就是用此配置%production.quarkus.http.port=8082# 如果不指定profile,或者profile既不是dev也不是production,就使用此配置quarkus.http.port=8080
复制代码

  • 使用上述配置后,因为profile等于dev,会使用不同配置项%dev.quarkus.http.port,也就是说服务端口是8081,另外两个配置%production.quarkus.http.portquarkus.http.port都无效
  • 启动应用验证,我这是用mvn quarkus:dev命令启动的,如下图红框:

  • 浏览器访问地址http://localhost:8081/actions,服务正常,配置项greeting.message的值也符合预期:

  • 再试试另一种配置,先在application.properties文件中删除配置项quarkus.profile=dev,再改用mvn quarkus:dev -Dquarkus.profile=production启动应用,这次生效的配置项是%production.quarkus.http.port,如下图:

  • 访问地址也变成了http://localhost:8082/actions

需要大写的场景


  • 《quarkus实战之六:配置》一文中,曾提到过配置方式有六种,有几种要求配置项大写,例如在.env中的配置,此时格式变成了_{PROFILE}_CONFIG_KEY=value,举例如下
  1. # 这个配置信息在各个环境中都是相同的
  2. GREETING_MESSAGE=hello
  3. # 如果profile为dev,就是用此配置
  4. _DEV_QUARKUS_HTTP_PORT=8081
  5. # 如果profile为production,就是用此配置
  6. _PRODUCTION_QUARKUS_HTTP_PORT=8082
  7. # 如果不指定profile,就使用此配置
  8. QUARKUS_HTTP_PORT=8080
复制代码

  • 注意,实测发现在.env中配置QUARKUS_PROFILE=dev无效,也就是说不能在.env中指定profile,此时应该在启动命令中指定profile,例如:
  1. java -Dquarkus.profile=dev -jar hello-quarkus-1.0-SNAPSHOT-runner.jar
复制代码
不指定profile时的默认值


  • 不指定profile的时候,quarkus会给profile设置默认值,有三种可能:dev、test、prod,具体逻辑如下:

  • 如果启动命令是mvn quarkus:dev,profile等于dev,如下图,大家应该见过多次了:

  • 单元测试期间,例如执行命令mvn test,profile等于test

  • 以上两种场景之外,profile等于prod,例如用命令java -jar hello-quarkus-1.0-SNAPSHOT-runner.jar启动应用

每个profile对应一个配置文件


  • 如果您希望每个profile都有自己的配置文件,quarkus也支持,如下所示,src/main/resources/目录下同时存在两个配置文件:application.propertiesapplication-staging.properties
  1. resources
  2. ├── META-INF
  3. │   └── resources
  4. │       └── index.html
  5. ├── application-staging.properties
  6. └── application.properties
复制代码

  • application.properties内容如下
  1. greeting.message=hello
  2. quarkus.http.port=8080
复制代码

  • application-staging.properties内容如下
  1. greeting.message=hello
  2. quarkus.http.port=8081
复制代码

  • 如果启动命令指定了profile,如mvn quarkus:dev -Dquarkus.profile=staging,此时只有application-staging.properties文件生效,如下图


  • 还要注意一点:此时如果指定一个不存在的profile,例如mvn quarkus:dev -Dquarkus.profile=xxxxxxx,此时生效的是application.properties文件生效,如下图

Parent Profile


  • parent profile解决的问题是:假设当前profile是aaa,那么配置项xxx对应的配置名应该是%dev.aaa,如果找不到%dev.aaa,就去找它的parent profile对应的配置项,来看个例子就清楚了,假设配置信息如下:
  1. # 指定profile的名字
  2. quarkus.profile=dev
  3. # 指定parent的名字
  4. quarkus.config.profile.parent=common
  5. %common.quarkus.http.port=9090
  6. %dev.quarkus.http.ssl-port=9443
  7. quarkus.http.port=8080
  8. quarkus.http.ssl-port=8443
复制代码

  • 当前profile已经指定为dev
  • parent profile已经指定为common
  • 对于配置项quarkus.http.port,由于没找到%dev.quarkus.http.port,就去找parent profile的配置,于是找到了%common.quarkus.http.port,所以值为9090
  • 对于配置项quarkus.http.ssl-port,由于找到了%dev.quarkus.http.ssl-port,所以值为9443
  • 对于配置项quarkus.http.port,如果%dev.quarkus.http.port%common.quarkus.http.port都不存在,会用quarkus.http.port,值为8080
修改默认profile


  • 前面曾说到,启动的时候如果不指定profile,quarkus会指定默认的profile:将应用制作成jar,以java -jar命令启动时,profile会被设置为prod
  • 如果您想让默认值从prod变为其他值,可以在构建的时候用-Dquarkus.profile去改变它,例如下面这个命令,jar包生成后,启动的时候默认profile是prod-aws
  1. mvn clean package -U -Dquarkus.package.type=uber-jar -Dquarkus.profile=prod-aws
复制代码

  • 启动jar的时候不指定profile,如下图,profile已被设定为prod-aws

三个关键注意事项(重要)


  • quarkus官方给出了三个重点注意事项

  • 应用在运行时,只会有一种profile生效
  • 如果想在代码获取当前的profile,可以用此API
  1. io.quarkus.runtime.configuration.ProfileManager#getActiveProfile
复制代码

  • 用注解的方式获取profile是无效的,下面这段代码无法得到当前的profile
  1. @ConfigProperty("quarkus.profile")
  2. String profile;
复制代码
欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

锦通

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表