项目规划
如一个电商系统,内部的核心系统架构,如下图
项目架构如下图
问题
在整个系统中,我们会配置数据库源的相关配置,如:
<code>#============数据源配置================spring: datasource:
url: jdbc:mysql://127.0.0.1:3306/shop
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver/<code>
还有dubbo微服务注册中心地址
<code>dubbo: registry: address: spring-cloud://127.0.0.1/<code>
上面的注册中心采用的是springcloud alibaba的nacos注册中心,这个不是重点
因为整个系统中有很多微服务,都要用到数据源和注册中心地址;那通常做法就是把各个服务application.yml中进行配置,如:
业务逻辑项目rb-business也会在它的application.yml中也会用到注册中心地址。
那问题来了:
这么多子项目中各自都配置了数据源以及注册中心,显然不合理;万一地址变了,那所有的子项目都要进行更改
那这么进行修改呢?
配置子项目
怎么解决上面的问题?就是再新建一个公共配置的子项目,把公共的配置放在配置子项目中,然后其他子项目引用这个公共配置子项目。
我们可以把数据库配置,redis配置参数、oss、sms等共同需要的配置写在里面,我们观察一些配置文件的名字的命名方式application-xxx.properties(也可以yml格式);这个必须要准守,因为我们要利用一下springboot的机制。继续往下看。
spring.profiles.include
小伙伴有没有见过profiles.include呢?好像一直在用profiles.active。
SpringBoot能使用application- {你的自定义profile名称myProfileName} .properties模式添加任何你指定配置文件到其属性文件。
要加载特定的配置文件属性文件,我们可以使用命令行选项-Dspring.profiles.active = myProfileName。
缺省默认SpringBoot是加载application.properties,无需任何-Dspring.profile.active选项。
或使用-Dspring.profiles.active = default来加载。默认属性文件也可以命名为application-default.properties。
默认配置文件application.properties中指定的任何属性将被你指定加载的配置文件中的的属性覆盖。
也可以在application.properties中指定激活配置文件。
spring.profiles.active=prod
比如你有三个配置文件:
<code>src/main/resources/application.properties(默认的)
src/main/resources/application-dev.properties(你指定的dev)
src/main/resources/application-prod.properties(你指定的prod)/<code>
如果在application.properties中有:
<code>spring.profiles.active=prod/<code>
那么SpringBoot将加载application-prod.properties内容。如果你在代码中使用配置文件中的变量:
<code>@Configurationpublic class UserBean {
@Value("${app.name}")
private String name;
@Value("${app.age}")
private int age;/<code>
如果application-prod.properties和application.properties都有app.name和app.age,那么以prod中配置的值为主。 spring.profile.include属性
在application-prod.properties还可以加入:
spring.profiles.include=redis,db
这是无条件地添加活动配置文件(以逗号分隔) 。此属性添加的配置文件不会根据某些条件或命令行开关决定是否添加,而是始终无条件添加它们。
上述配置是就加载了:
<code>src/main/resources/application-redis.properties
src/main/resources/application-db.properties/<code>
这两个配置文件中的内容。即使这些文件在其他子项目resources中,也可以被加载 我们只需要在rb-user-server、rb-goods-server等引用项目中引用rb-common-config这个子项目。并且在项目中的application.yml配置文件中,加入:
<code>spring: profiles: include: - redis - db - nacos /<code>
就可以引用rb-common-config中的配置文件了。有些细心的小朋友会问,那个rb-common-config项目的配置文件是在resources目录下的config文件夹下的哦,怎么也会加载呢?
配置文件目录
SpringBoot配置文件可以放置在多种路径下,不同路径下的配置优先级有所不同 。
可放置目录(优先级从高到低)
file:./config/ (当前项目路径config目录下);
file:./ (当前项目路径下);
classpath:/config/ (类路径config目录下);
classpath:/ (类路径config下).
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载配置文件并互补配置;
我们可以从ConfigFileApplicationListener这类便可看出,其中DEFAULTSEARCHLOCATIONS属性设置了加载的目录:
所以之前的配置文件在config目录中也照样有效,而且优先级高一级哦。
到这里为止,我们很好的把公共的配置项,转移到子项目rb-common-config文件下了,其中的关键点就是,在引用项目加入spring.profiles.include配置。
多环境配置
在开发过程中,我们都会区分开发环境,测试环境,预演环境,生产环境等;不同环境的配置参数是不一样的。分布式项目中如何应用呢?
网上大多数介绍是针对单个项目工程的,利用上面介绍的spring.profiles.active配置来进行区分不同的环境:
<code>src/main/resources/application.properties(默认的)
src/main/resources/application-dev.properties(开发环境)
src/main/resources/application-prod.properties(生产环境)/<code>
想要什么环境,在启动的时候
<code>java -jar xxx.jar --spring.profiles.active=prod/<code>
上面就是应用了生产环境了。 这种方式是否可以应用到分布式多项目中 ,也是可以的,我们可以把rb-common-config中也配置多个配置文件,如:
<code>src/main/resources/config/application-devDB.properties(开发环境)
src/main/resources/config/application-devRedis.properties(开发环境)
src/main/resources/config/application-prodDB.properties(生产环境)
src/main/resources/config/application-prodRedis.properties(生产环境)/<code>
然后在引用项目中如rb-user-server中 application-dev.properties加入
<code>spring.profiles.include=devDB,devRedis/<code>
application-prod.properties加入
<code>spring.profiles.include=prodDB,prodRedis/<code>
启动rb-user-server.jar
<code>java -jar rb-user-server.jar --spring.profiles.active=prod/<code>
这样就做到了区分多环境的目的。
多环境配置问题总结
在上面的多环境配置中,我们需要在各个项目中,新建多个properties文件,区分不同的环境,这个是比较麻烦的事情,而且不够优雅。
閱讀更多 青芽草 的文章