spring boot + nacos多环境部署
问题描述
nacos 是什么这里就不阐述了,在本篇博客中作用是作为spring boot动态配置的中心,配合spring cloud 可以很容易的实现多环境的部署,但是配合spring boot就出现问题,无法实现。示例如下
application.properties配置内容如下
server.port=8088
spring.profiles.active=local
nacos.config.server-addr=127.0.0.1:8848
application-local.properties配置内容如下
nacos.config.group=LOCAL
application-myself.properties配置内容如下
nacos.config.group=MYSELF
预期效果就是maven根据不同的环境打包,这样很方便,项目整体改动也很小
刚好nacos有spring boot集成的方案
github地址
但是整个项目拉下来之后发现根本不行,会有报错: endpoint not blank,应该是nacos配置中心地址没有配置或者没有找到
所以没办法那就自己搞
解决思路
nacos配置两种方式,一种是硬编码一种是纯配置文件配置,所以有两种解决方式
一、
硬编码,也就是在启动类上加注解
@NacosPropertySource(
groupId = "MYSELF",
dataId = "eco-mock",
autoRefreshed = true,
type = ConfigType.PROPERTIES
)
差不多就像这样,像个办法在项目启动前改变这个group的值,或者这个dataId的值(用来区分不同的配置环境)
二、
纯配置文件
#开启配置预加载功能
nacos.config.bootstrap.enable=true
# 主配置服务器地址
nacos.config.server-addr=127.0.0.1:8848
# 主配置 data-id
nacos.config.data-id=eco-mock
# 主配置 group-id
nacos.config.group=MYSELF
# 主配置 配置文件类型
nacos.config.type=properties
# 主配置 最大重试次数
nacos.config.max-retry=10
# 主配置 开启自动刷新
nacos.config.auto-refresh=true
# 主配置 重试时间
nacos.config.config-retry-time=2333
# 主配置 配置监听长轮询超时时间
nacos.config.config-long-poll-timeout=46000
# 主配置 开启注册监听器预加载配置服务(除非特殊业务需求,否则不推荐打开该参数)
nacos.config.enable-remote-sync-config=true
通过某种方式让 nacos.config.group=MYSELF
这个数值改变或者让application.properties
变成我们指定的环境配置
三、我们可以利用maven在打包时会将配置文件中的参数赋值的机制,动态修改application.properties文件(推荐)
准备工作
nacos 配置中心的具体配置
dataId:eco-mock
group:myself
eco.test.nacos=myself
eco.enable.sendMsg=false
dataId:eco-mock
group:local
eco.test.nacos=local
eco.enable.sendMsg=false
配置文件如上问题描述
再注入的代码中输出数据
@Configuration
@Slf4j
public class CommonParam {
public static String TEST_NACOS;
@NacosValue(value = "${eco.test.nacos}",autoRefreshed = true)
public void setTestNacos(String testNacos) {
log.info("修改 eco.test.nacos ==> {}", testNacos);
this.TEST_NACOS = testNacos;
}
}
具体实施
方案一
首先注解的中的值如果要修改只能在类加载初始化的时候,那就是启动类静态代码块中进行修改
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.Properties;
@NacosPropertySource(
groupId = "",
dataId = "eco-mock",
autoRefreshed = true,
type = ConfigType.PROPERTIES
)
@EnableScheduling
@SpringBootApplication
public class MockApplication {
static {
try {
Properties properties = new Properties();
properties.load(MockApplication.class.getClassLoader().getResourceAsStream("application.properties"));
// 从配置文件中读取当前部署的环境
String profile = properties.getProperty("spring.profiles.active");
// 读取指定环境对应的group
properties.load(MockApplication.class.getClassLoader().getResourceAsStream(String.format("application-%s.properties", profile)));
String groupId = properties.getProperty("nacos.config.group");
// 进行赋值
NacosPropertySource annotation = MockApplication.class.getAnnotation(NacosPropertySource.class);
InvocationHandler ih = Proxy.getInvocationHandler(annotation);
Field memberValuesField = ih.getClass().getDeclaredField("memberValues");
memberValuesField .setAccessible(true);
Map map = (Map) memberValuesField .get(ih);
map.put("groupId", groupId);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(MockApplication.class);
springApplication.run(args);
}
}
先修改application.properties配置 spring.profiles.active=local
启动日志如下
再application.properties配置 spring.profiles.active=myself
说明配置成功
线上项目只需要修改为spring.profiles.active=@activatedProperties@
然后部署根据maven指定环境即可
方案二
可以看下这篇博客中的maven方案
思路相同,因为配置文件预加载加载的是application.properties,
那么我只需要将指定的配置文件比如说application-local.properties
打包成application.properties
即可
具体实施我就不写了,大同小异
方案三(个人推荐)
#开启配置预加载功能
nacos.config.bootstrap.enable=true
# 主配置服务器地址
nacos.config.server-addr=@addr@
# 主配置 data-id
nacos.config.data-id=eco-mock
# 主配置 group-id
nacos.config.group=@group@
# 命名空间指定
nacos.config.namespace=@space@
# 主配置 配置文件类型
nacos.config.type=properties
# 主配置 最大重试次数
nacos.config.max-retry=10
# 主配置 开启自动刷新
nacos.config.auto-refresh=true
# 主配置 重试时间
nacos.config.config-retry-time=2333
# 主配置 配置监听长轮询超时时间
nacos.config.config-long-poll-timeout=46000
# 主配置 开启注册监听器预加载配置服务(除非特殊业务需求,否则不推荐打开该参数)
nacos.config.enable-remote-sync-config=true
pom.xml 中如下配置
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 替换 配置文件中 @ss@ 样式字符-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<delimiters>
<delimiter>@</delimiter>
<delimiter>${*}</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 替换开关-->
<filtering>true</filtering>
</resource>
</resources>
</build>
<profiles>
<profile>
<!-- 本地开发环境 -->
<id>local</id>
<properties>
<env>local</env>
<addr>192.168.1.198:8848</addr>
<space>4ca4defb-a712-408b-8b1a-301774637d79</space>
</properties>
<activation>
<!-- 设置默认激活这个配置 -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<!-- 发布环境 -->
<id>prod</id>
<properties>
<env>prod</env>
<addr>192.168.1.122:8848</addr>
<space>4ca4defb-a712-408b-8b1a-89878972a</space>
</properties>
</profile>
<profile>
<!-- 测试环境 -->
<id>test</id>
<properties>
<env>test</env>
</properties>
</profile>
</profiles>
maven部署构建之后查看项目 target/classess 中application.properties 文件验证是否修改成功
总结
如果有更好更优雅的解决方案希望留言学习下,谢谢!