目录
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.读取不到配置
多环境配置说明:
????????在项目实际开发过程中,可能会有不同的环境,例如开发环境,测试环境和生产环境。不同的环境,对应的配置信息是不同的,将项目发布到不同的环境,需要去更改对应环境的配置信息,如果每次都是手动去更改环境,非常不友好,且容易漏掉配置,如果能够实现不同环境的自动识别,动态切换,将极大的提高工作效率。下面介绍一下自己在工作中使用到的多环境配置方法。
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 。
? 我们可以利用系统环境变量读取机制,在不同环境下给变量配置不同值,通过读取对应变量的值,获取不同的运行配置文件:
1.1 建立各环境配置文件
分别为?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
这里只简单的测试环境切换服务端口号
1.2 设置环境变量
网上有示例配置和系统变量后IDEA自动会有环境配置,我的没有所以手动加上(可能是我使用的破解版吧 ,不知道是不是这个原因...)
如果使用的 linux 物理机, 使用?vim /etc/profile ?命令,添加上一下配置
SPRING_PROFILES_ACTIVE=prod
export SPRING_PROFILES_ACTIVE
1.3 启动服务
2. nacos配置中心动态切换
????????通过环境变量的方式,不同环境的配置可以直接观察到,不太安全(当然可以将关键配置抽离成环境变量)。可以将配置文件全部放置在 nacos 中,然后通过统一的域名访问 nacos 服务器,在不同的环境配置域名对应的host ,指向不同的nacos服务器地址,从而读取对应的配置。
2.1?配置文件
# 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属性
2.2 nacos配置
?nacos中 environment.yaml?配置如下:
server:
port: 9004
2.3?启动服务
服务启动后发现已经从nacos读取到服务端口号
访问服务测试正常
3.?同一nacos环境下服务不同环境控制
????????上面两种方式都是不同的环境对应不同的配置中心,如果多个环境都是使用的同一个配置中心(使用nacos作为配置中心),那么可以通过 dataId 实现不同环境的隔离。
3.1 cloud方式
3.1.1 引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<!-- 启动获取配置中心配置 原文链接:https://blog.csdn.net/chy2z/article/details/119464497 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.0.3</version>
</dependency>
如果不引用spring-cloud-starter-bootstrap则不会读取nacos配置
3.1.2?添加配置
添加 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(这里主要是快速简单的测试读取配置)?
3.1.3?添加环境变量
3.1.4?启动服务
3.1.5?读取数据库配置
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配置
?
?访问正常
4.Maven方式
4.1?创建配置文件
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
4.2?更改pom文件
<profiles>
<profile>
<id>dev</id>
<properties>
<profileActive>dev</profileActive>
</properties>
<!--默认开发环境-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profileActive>test</profileActive>
</properties>
</profile>
<profile>
<id>pro</id>
<properties>
<profileActive>pro</profileActive>
</properties>
</profile>
</profiles>
4.3?maven打包
maven ?-P dev
原文链接:https://blog.csdn.net/qq_41863849/article/details/122145312
5.配置加密
5.1?服务配置文件中加密
通常在连接数据库时候明文信息不太安全,所以需要加密,这里展示数据库连接用户名密码加解密,其他参数同理
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: JAS(sNhUs2TnBigaKiBTIeobYA==)
password: JAS(BaqtsIAiaTrZx84TJaMWAq2ryBPvvKbl)
5.1.1?引入依赖
<!-- web应用依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- cloud整合nacos依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<!-- cloud启动依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.0.3</version>
</dependency>
<!-- mybatis-plus依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- mysql依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
</dependency>
<!-- 数据库连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid-spring.version}</version>
</dependency>
<!-- lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 加解密依赖 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
5.1.2 加解密工具类
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;
}
}
5.1.3?添加监听
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<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment env = event.getEnvironment();
MutablePropertySources pss = env.getPropertySources();
List<PropertySource> list = new ArrayList<>();
for (PropertySource ps : pss) {
Map<String, Object> map = new HashMap<>();
if (ps instanceof OriginTrackedMapPropertySource) {
OriginTrackedMapPropertySource propertySource = new OriginTrackedMapPropertySource(ps.getName(), map);
Map<String, Object> src = (Map<String, Object>) 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);
});
}
}
5.1.4?添加控制类
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);
}
}
5.1.5?访问测试
访问成功,查询数据库没有问题,说明解密成功。也可以打断点进去看?
5.2 SpringCloud读取Nacos中加密参数
虽然在服务配置文件中可以正常加解密,但是并不灵活,通常还是需要将参数信息放到nacos配置中心管理。
总结
1.springboot方式使用application.yml配置
2.springcloud方式使用bootstrap.yml配置
常见问题
1.读取不到配置
参考原文:spring-cloud使用nacos配置中心的坑_黑暗行动的博客-CSDN博客
|