欢迎访问我的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名称+点号,如下所示
# 指定当前profile
quarkus.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,具体逻辑如下:
  1. 如果启动命令是mvn quarkus:dev,profile等于dev,如下图,大家应该见过多次了:

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

  3. 以上两种场景之外,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
  1. 当前profile已经指定为dev
  2. parent profile已经指定为common
  3. 对于配置项quarkus.http.port,由于没找到%dev.quarkus.http.port,就去找parent profile的配置,于是找到了%common.quarkus.http.port,所以值为9090
  4. 对于配置项quarkus.http.ssl-port,由于找到了%dev.quarkus.http.ssl-port,所以值为9443
  5. 对于配置项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官方给出了三个重点注意事项
  1. 应用在运行时,只会有一种profile生效
  2. 如果想在代码获取当前的profile,可以用此API
io.quarkus.runtime.configuration.ProfileManager#getActiveProfile
  1. 用注解的方式获取profile是无效的,下面这段代码无法得到当前的profile
 @ConfigProperty("quarkus.profile")
String profile;

欢迎关注博客园:程序员欣宸

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

quarkus实战之八:profile的更多相关文章

  1. [原创].NET 业务框架开发实战之八 业务层Mapping的选择策略

    原文:[原创].NET 业务框架开发实战之八 业务层Mapping的选择策略 .NET 业务框架开发实战之八 业务层Mapping的选择策略 前言:在上一篇文章中提到了mapping,感觉很像在重新实 ...

  2. spring4.1.8扩展实战之八:Import注解

    spring4.1.8扩展实战之八:Import注解 2018年09月10日 12:53:57 博陵精骑 阅读数:441更多 所属专栏: spring4源码分析与实战    版权声明:欢迎转载,请注明 ...

  3. OpenFaaS实战之八:自制模板(maven+jdk8)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. kubebuilder实战之八:知识点小记

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  5. [Java聊天室server]实战之二 监听类

    前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...

  6. [Java聊天室server]实战之五 读写循环(服务端)

    前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...

  7. NET 分布式架构开发项目实战

    .NET 分布式架构开发项目实战 从头到尾,一步一步讲述一个真实的项目实战,关注点主要是架构的思考和实现,以及如何解决平时项目遇到的一些问题. 同时也司公布源代码. 如何构建高性能,稳定SOA应用之- ...

  8. [原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇)

    原文:[原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇) .NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇) 前言:接着上篇来. 系列文章链接: [ ...

  9. [原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略

    原文:[原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略 .NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略 前言:之前的讨论一直关注在怎么从D ...

  10. [原创].NET 业务框架开发实战之七 业务层初步构想

    原文:[原创].NET 业务框架开发实战之七 业务层初步构想 .NET 业务框架开发实战之七 业务层初步构想 前言:本篇主要讲述如何把DAL和BLL衔接起来. 本篇议题如下: 1.       DAL ...

随机推荐

  1. Appweb配置

    Appweb配置       具体配置网页=> https://www.embedthis.com/appweb/doc/users/configuration.html         具体参 ...

  2. 使用select需要注意的细节

    使用select需要注意的细节 在学校的时候就使用过select,但是在项目中使用的时候却犯了个错误. select如何使用就不进行总结了,网上教程太多,以下是项目中我写的一小段代码,便于总结. in ...

  3. if, if else, else if 的区别,以js为例

    一个具有迷惑性的例子,底下的两种情况可以看做两个循环,第一个只要满足一个条件就跳出循环,第二个是不管满足几个条件,都会往下走直至循环结束. 1 var a = 5; 2 if (a > 3) { ...

  4. boot-admin开源项目中有关后端参数校验的最佳实践

    我们在项目开发中,经常会对一些参数进行校验,比如非空校验.长度校验,以及定制的业务校验规则等,如果使用if/else语句来对请求的每一个参数一一校验,就会出现大量与业务逻辑无关的代码,繁重不堪且繁琐的 ...

  5. OFFICE-利用Word邮件合并功能联动编辑《目标责任成本调整说明》

    正文 00.开始以及目标 0.1 开始 众所周知的原因,X建工的很多文档都提供了一个填写模板,这是个好事.但是捏,当他们把模板放下来要来填数的时候,你会发现所有的数据,都是在不同的文档中搬来搬去,这点 ...

  6. 大米cms爆破后台及支付逻辑漏洞

    又找到个网站挖洞,我来康康. 大米手机是个什么鬼手机??看一下吧 这个支付页面好熟悉,可能存在支付逻辑漏洞,咱们用burp改个包看看. 先支付一个看看 把包里那个=1改成0试试~ 证实确实存在支付逻辑 ...

  7. 2022-09-15:Range模块是跟踪数字范围的模块。 设计一个数据结构来跟踪表示为 半开区间 的范围并查询它们。 半开区间 [left, right) 表示所有 left <= x < righ

    2022-09-15:Range模块是跟踪数字范围的模块. 设计一个数据结构来跟踪表示为 半开区间 的范围并查询它们. 半开区间 [left, right) 表示所有 left <= x < ...

  8. 2021-02-15:给定一个整型数组arr,代表数值不同的纸牌排成一条线。玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿。但是每个玩家每次只能拿走最左或最右的纸牌,玩家A和玩家B都绝顶聪明。请返回最后获胜者的分数。

    2021-02-15:给定一个整型数组arr,代表数值不同的纸牌排成一条线.玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿.但是每个玩家每次只能拿走最左或最右的纸牌,玩家A和玩家B都绝顶聪 ...

  9. .NET周报 【5月第2期 2023-05-14】

    国内文章 XUnit数据共享与并行测试 https://www.cnblogs.com/podolski/p/17388602.html 在单元或者集成测试的过程中,需要测试的用例非常多,如果测试是一 ...

  10. MMCM/PLL VCO

    输入输出时钟频率,input 322.265625Mhz, output 312.5Mhz 对于使用MMCM与PLL的不同情况,虽然输入输出频率是一样的,但是,分/倍频系数是不同的,不能使用同一套参数 ...