背景
项目架构基于springboot和dubbo,部署上service端以jar包的方式部署,web端以war包部署(交给运维团队,不使用springboot内置的tomcat),项目使用git进行版本管理。
部署时对于配置文件(需要启动时就加载的,比如jdbc,mq,redis等文件)的处理,其实问题还是比较经典的。基本上大部分项目应该都会遇到,处理方式可能各不相同。
一、spring
对于spring项目来讲,将在不同环境中可变的配置放到.properties文件中,通过加载PropertyPlaceholderConfigurer这个bean将配置文件加载进去
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:${CONFIG_HOME}/dubbo-config.properties</value>
<value>file:${CONFIG_HOME}/jdbc.properties</value>
</list>
</property>
</bean>
然后使用时就可以通过${jdbc.driver}了
具体代码
<dubbo:registry protocol="zookeeper" address="${dubboServer.address}" />
spring早在3.1版本中就提供了Profile的设置方案,通过激活某个(可以多个)配置文件,是特定的配置生效,在springboot中通过spring.profiles.active更可以方便的设置生效的配置文件。通过maven找到设置的profile将生效的配置文件打包,具体可以参考 https://blog.csdn.net/lihe2008125/article/details/50443491 。 但是在以前的项目中并没有使用过这种方式,问题思考了一下使用这种方式需要在版本管理中将各个环境的配置文件都管理上,开发时本地就多出来了很多其他环境的配置,好像这样会不好?
之前项目中更多的方式是通过配置jvm参数配置类似于上面代码里的CONFIG_HOME(-DCONFIG_HOME)配置配置文件所处的具体路径。这样配置的话相当于项目内的配置文件就不生效了,打包的时候就不需要管这些配置文件,有修改的时候就修改外部的配置文件就ok了。
二、springboot
1.jar
springboot默认以jar包的形式部署默认可以将配置文件放到一下四个位置,前面的会被后面的覆盖(以下排名按照读取优先级)
a.jar包同级的config文件夹里
b.jar包同级的文件夹里
c.classpath(对应开发目录src/main/resources里)的config文件夹
d.classpath(对应开发目录src/main/resources里)文件夹
所以再部署的时候可以将配置文件放到jar包之外,然后打包的时候讲包内的配置文件排除就可以了 具体maven中的插件代码为(第二个plugin是将依赖的jar打到jar外面的lib中)
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<!-- 添加index则不从mainfest中读取classpath,而是从Index.list中读取 -->
<!-- <index>true</index> -->
<manifest>
<mainClass>com.caxs.athena.ServiceApplication</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>./</Class-Path>
</manifestEntries>
</archive>
<excludes>
<exclude>config/**</exclude>
</excludes>
<!--<source>1.8</source>-->
<!--<target>1.8</target>-->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
2.war
对于war包来讲,无法加载默认的外部配置文件(上面jar中的a、b),但是仍然可以通过以下方式读取外部配置文件。
a.在外部tomcat中设置jvm启动参数(windows在tomcat/bin/catalina.bat) 添加spring.config.location指定自定义的外部地址(相当于指定classPath地址)这种方式优先级最高
b在外部tomcat中conf目录下的catalina.properties中的common.loader添加自定义的外部文件地址
common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar","自定义地址"
推荐一个springboot的一个学习网址