目录
1. 环境变量切换
1.1 建立各环境配置文件
1.2 设置环境变量
2. nacos配置中心动态切换
2.1 配置文件
2.2 nacos配置
2.3 启动服务
3. 同一nacos环境下服务不同环境控制
3.1 cloud方式
3.1.1 引入依赖
3.1.2 添加配置
3.1.3 添加环境变量
3.1.4 启动服务
3.1.5 读取数据库配置
4.Maven方式
4.1 创建配置文件
4.2 更改pom文件
4.3 maven打包
总结
常见问题
1.读取不到配置
多环境配置说明:
在项目实际开发过程中,可能会有不同的环境,例如开发环境,测试环境和生产环境。不同的环境,对应的配置信息是不同的,将项目发布到不同的环境,需要去更改对应环境的配置信息,如果每次都是手动去更改环境,非常不友好,且容易漏掉配置,如果能够实现不同环境的自动识别,动态切换,将极大的提高工作效率。下面介绍一下自己在工作中使用到的多环境配置方法。
SpringBoot打包服务时,一些参数需要从外界获取,可以通过在配置文件中配置环境变量实现
spring:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:table}?useUnicode=true&characterEncoding=UTF-8
username: ${DB_USER:root}
password: ${DB_PASSWORD:root}
上面案例中,${DB_HOST:localhost}
服务会先在系统环境变量 DB_HOST
中获取值,如果获取不到则使用默认值 localhost
。
我们可以利用系统环境变量读取机制,在不同环境下给变量配置不同值,通过读取对应变量的值,获取不同的运行配置文件:
分别为 application-dev.yml
和 application-prod.yml
分别代表开发环境和生产环境的配置:
# application.yml
spring:
profiles:
active: ${HUACHUN_PROFILES_ACTIVE:dev}
# application-dev.yml
server:
port: 9001
# application-prod.yml
server:
port: 9002
这里只简单的测试环境切换服务端口号
网上有示例配置和系统变量后IDEA自动会有环境配置,我的没有所以手动加上(可能是我使用的破解版吧 ,不知道是不是这个原因...)
如果使用的 linux 物理机, 使用 vim /etc/profile
命令,添加上一下配置
SPRING_PROFILES_ACTIVE=prod
export SPRING_PROFILES_ACTIVE
1.3 启动服务
通过环境变量的方式,不同环境的配置可以直接观察到,不太安全(当然可以将关键配置抽离成环境变量)。可以将配置文件全部放置在 nacos 中,然后通过统一的域名访问 nacos 服务器,在不同的环境配置域名对应的host ,指向不同的nacos服务器地址,从而读取对应的配置。
# application.yml
spring:
profiles:
active: ${HUACHUN_PROFILES_ACTIVE}
# application-prod.yml
nacos:
config:
server-addr: nacos_addr:port # 这里填写相应环境nacos配置中心地址和端口号
bootstrap:
enable: true
log-enable: true
data-ids: environment.yaml
type: yaml
group: dev
auto-refresh: true
# namespace: 0e1ff256-8d17-4e94-a4dd-d81c06e9b56c # 如果需要指定环境可以添加namespace属性
nacos中 environment.yaml 配置如下:
server:
port: 9004
服务启动后发现已经从nacos读取到服务端口号
访问服务测试正常
上面两种方式都是不同的环境对应不同的配置中心,如果多个环境都是使用的同一个配置中心(使用nacos作为配置中心),那么可以通过 dataId 实现不同环境的隔离。
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
2.2.6.RELEASE
org.springframework.cloud
spring-cloud-starter-bootstrap
3.0.3
如果不引用spring-cloud-starter-bootstrap则不会读取nacos配置
添加 bootstrap.yml 配置文件
spring:
profiles:
active: ${HUACHUN_PROFILES_ACTIVE}
cloud:
nacos:
config:
server-addr: nacos_addr:port # nacos服务访问地址和端口
enabled: true
file-extension: yaml
prefix: environment
group: dev
refresh-enabled: true
nacos配置三个文件,端口好分别是9904,9908,9909(这里主要是快速简单的测试读取配置)
1. 配置如下
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: ${env.project.db.username}
password: ${env.project.db.password}
url: jdbc:mysql://${env.project.db.adrr}:${env.project.db.port}/hhmt_cpa?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
type: com.alibaba.druid.pool.DruidDataSource
2. nacos配置
访问正常
application-dev.yml
和 application-prod.yml
分别代表开发环境和生产环境的配置
# application.yml
spring:
profiles:
active: ${HUACHUN_PROFILES_ACTIVE:dev}
# application-dev.yml
server:
port: 9001
# application-prod.yml
server:
port: 9002
dev
dev
true
test
test
pro
pro
maven
-P dev
原文链接:https://blog.csdn.net/qq_41863849/article/details/122145312
通常在连接数据库时候明文信息不太安全,所以需要加密,这里展示数据库连接用户名密码加解密,其他参数同理
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: JAS(sNhUs2TnBigaKiBTIeobYA==)
password: JAS(BaqtsIAiaTrZx84TJaMWAq2ryBPvvKbl)
org.springframework.boot
spring-boot-starter-web
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
2.2.6.RELEASE
org.springframework.cloud
spring-cloud-starter-bootstrap
3.0.3
com.baomidou
mybatis-plus-boot-starter
${mybatis-plus.version}
mysql
mysql-connector-java
${mysql-connector.version}
com.alibaba
druid-spring-boot-starter
${druid-spring.version}
org.projectlombok
lombok
com.github.ulisesbocchio
jasypt-spring-boot-starter
3.0.3
package com.huachun.utils;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
public class JasyptUtil {
/**
* 加密方法
*
* @param password jasypt所需要的加密密码配置
* @param value 需要加密的密码
*/
public static String encyptPwd(String password, String value) {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(password);
config.setAlgorithm("PBEWithMD5AndDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
String result = encryptor.encrypt(value);
return result;
}
/**
* 解密
*
* @param password jasypt所需要的加密密码配置
* @param value 需要解密的密码
*/
public static String decyptPwd(String password, String value) {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(password);
config.setAlgorithm("PBEWithMD5AndDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
String realV = getValue(value);
String result = encryptor.decrypt(realV);
return result;
}
public static String getValue(String value) {
if (value.contains("JAS")) {
return value.substring(4, value.length() - 1);
}
return value;
}
}
package com.huachun.listener;
import com.huachun.utils.JasyptUtil;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EnvironmentPreparedListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment env = event.getEnvironment();
MutablePropertySources pss = env.getPropertySources();
List list = new ArrayList<>();
for (PropertySource ps : pss) {
Map map = new HashMap<>();
if (ps instanceof OriginTrackedMapPropertySource) {
OriginTrackedMapPropertySource propertySource = new OriginTrackedMapPropertySource(ps.getName(), map);
Map src = (Map) ps.getSource();
src.forEach((k, v) -> {
String strValue = String.valueOf(v);
if (strValue.startsWith("JAS(") && strValue.endsWith(")")) {
v = JasyptUtil.decyptPwd(k, v.toString());
}
map.put(k, v);
});
list.add(propertySource);
}
}
/**
此处是删除原来的 OriginTrackedMapPropertySource 对象,
把解密后新生成的放入到 Environment,为什么不直接修改原来的
OriginTrackedMapPropertySource 对象,此处不做过多解释
不懂的可以去看看它对应的源码,也算是留一个悬念,也是希望大家
能够没事多看一看源码。
*/
list.forEach(ps -> {
pss.remove(ps.getName());
pss.addLast(ps);
});
}
}
package com.huachun.controller;
import com.huachun.model.HcTest;
import com.huachun.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/env")
public class EnvCdDbController {
@Autowired
private TestService testService;
@GetMapping("/{id}")
public HcTest env(@PathVariable("id") String id) {
return testService.getData(id);
}
}
访问成功,查询数据库没有问题,说明解密成功。也可以打断点进去看
虽然在服务配置文件中可以正常加解密,但是并不灵活,通常还是需要将参数信息放到nacos配置中心管理。
1.springboot方式使用application.yml配置
2.springcloud方式使用bootstrap.yml配置
参考原文:spring-cloud使用nacos配置中心的坑_黑暗行动的博客-CSDN博客