目录
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.读取不到配置
1.@NacosValue 注解换成 @Value
参考原文:SpringCloud无法获取Nacos中的配置文件信息_springcloud读取不到nacos配置文件_会脸红的情先生的博客-CSDN博客
参考原文:spring-cloud使用nacos配置中心的坑_黑暗行动的博客-CSDN博客
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)