ToB企服应用市场:ToB评测及商务社交产业平台
标题:
quarkus实战之八:profile
[打印本页]
作者:
锦通
时间:
2023-7-28 07:46
标题:
quarkus实战之八:profile
欢迎访问我的GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):
https://github.com/zq2599/blog_demos
本篇概览
本文是《quarkus实战》系列的第八篇,经过前面的学习,咱们对配置有了足够了解,但问题也随之而来:如何让应用以最小的改动同时运行在不同环境(如本地、测试、生产等)
举个例子,下面是个简化版配置文件,有两个配置项,第一个固定不变,第二个随环境变化各不相同:
# 这个配置信息在各个环境中都是相同的
greeting.message=hello
# 这个配置信息在各个环境中都不一样
quarkus.http.port=9090
复制代码
在实际部署的时候,如何达到要求呢?
quarkus.http.port
的值随着环境变化
不同环境用不同配置文件是一种方法,但会导致配置文件数量上升,并且
greeting.message
在各环境都是一样的,这就出现了冗余,除了维护成本增加,在管理过程中容易出错
除了多个配置文件,还有种方法可以满足要求,并且不需要多个配置文件,这就是今天要聊的profile
演示代码
创建一个demo工程,参考下面的命令,这样的工程会自带一个web服务类HobbyResource.java
mvn "io.quarkus:quarkus-maven-plugin:create" \
-DprojectGroupId="com.bolingcavalry" \
-DprojectArtifactId="hello-quarkus" \
-DprojectVersion="1.0-SNAPSHOT" \
-DclassName="HobbyResource" \
-Dpath="actions"
复制代码
用下面这段代码来演示配置是否生效,可见用了一个配置项
greeting.message
,所以我们需要配置它的值才行
package com.bolingcavalry;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.time.LocalDateTime;
@Path("/actions")
public class HobbyResource {
@ConfigProperty(name = "greeting.message")
String message;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello RESTEasy, " + LocalDateTime.now() + " [" + message + "]";
}
}
复制代码
配置文件是
hello-quarkus/src/main/resources/application.properties
# 这个配置信息在各个环境中都是相同的
greeting.message=hello
复制代码
设定profile
profile自己是个普通的配置项,例如在application.properties文件中,是这样设置profile的
# 这个配置信息在各个环境中都是相同的
quarkus.profile=dev
# 如果不指定profile,就使用此配置
quarkus.http.port=8080
复制代码
也可以在System properties中设置,如下所示,如此以来,不同环境只有启动命令不同,配置文件可以完全不用修改:
java -Dquarkus.profile="dev" -jar hello-quarkus-1.0-SNAPSHOT-runner.jar
复制代码
同一个配置项在不同profile时的值
profile的格式是
%{profile-name}.config.name
以刚才的配置为例,
quarkus.http.port
配置项共出现三次,前两次带有前缀,格式是
百分号+profile名称+点号
,如下所示
# 指定当前profilequarkus.profile=dev# 这个配置信息在各个环境中都是相同的
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.port
和
quarkus.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
,举例如下
# 这个配置信息在各个环境中都是相同的
GREETING_MESSAGE=hello
# 如果profile为dev,就是用此配置
_DEV_QUARKUS_HTTP_PORT=8081
# 如果profile为production,就是用此配置
_PRODUCTION_QUARKUS_HTTP_PORT=8082
# 如果不指定profile,就使用此配置
QUARKUS_HTTP_PORT=8080
复制代码
注意,实测发现在.env中配置
QUARKUS_PROFILE=dev
无效,也就是说不能在.env中指定profile,此时应该在启动命令中指定profile,例如:
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.properties
和
application-staging.properties
resources
├── META-INF
│ └── resources
│ └── index.html
├── application-staging.properties
└── application.properties
复制代码
application.properties内容如下
greeting.message=hello
quarkus.http.port=8080
复制代码
application-staging.properties内容如下
greeting.message=hello
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对应的配置项,来看个例子就清楚了,假设配置信息如下:
# 指定profile的名字
quarkus.profile=dev
# 指定parent的名字
quarkus.config.profile.parent=common
%common.quarkus.http.port=9090
%dev.quarkus.http.ssl-port=9443
quarkus.http.port=8080
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
mvn clean package -U -Dquarkus.package.type=uber-jar -Dquarkus.profile=prod-aws
复制代码
启动jar的时候不指定profile,如下图,profile已被设定为
prod-aws
三个关键注意事项(重要)
quarkus官方给出了三个重点注意事项
应用在运行时,只会有一种profile生效
如果想在代码获取当前的profile,可以用此API
io.quarkus.runtime.configuration.ProfileManager#getActiveProfile
复制代码
用注解的方式获取profile是
无效的
,下面这段代码无法得到当前的profile
@ConfigProperty("quarkus.profile")
String profile;
复制代码
欢迎关注博客园:程序员欣宸
学习路上,你不孤单,欣宸原创一路相伴...
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4