目录
- 前言
- 项目规划
- 问题
- 配置子项目
- spring.profiles.include
- 配置文件目录
- 多环境目录
- 多环境配置问题总结
前言
我们在日常开发过程中,在新建一个项目中,我们经常会将一个项目按照功能性、模块等将一个项目分成多个子项目,这些子项目都包含在主项目中。
今天老顾就介绍企业应用中,分布式项目如何将配置分为开发环境、测试环境、预演环境、生产环境,对于不同的环境参数配置,如何处理?以及如何规划配置文件?
项目规划
如一个电商系统,内部的核心系统架构,如下图
项目架构如下图
问题
在整个系统中,我们会配置数据库源的相关配置,如:
<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>@Configuration
public 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这类便可看出,其中DEFAULT_SEARCH_LOCATIONS属性设置了加载的目录:
所以之前的配置文件在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文件,区分不同的环境,这个是比较麻烦的事情,而且不够优雅。
遗留问题一:
那有没有一种方案,不需要建那么多的配置文件,每个项目只需要必须的配置文件就行了呢?
遗留问题二:
上面的方案中,涉及到了开发环境,测试环境,预演环境,生产环境,我们把各自环境的参数配置到各自的配置文件中。
这里就出现了安全问题,数据库的连接地址,用户名与密码等直接暴露在开发人员面前;开发与测试环境安全要求低,还能接受;但是生产环境的相关服务器参数直接暴露在开发人员面前,那是很不安全的。那怎么处理呢?
上面遗留的问题,老顾在下一篇文章中,进行分享介绍,谢谢!!!
---End---
最近老顾上传了微服务网关的分享课程,请大家多多支持
1、基于RocketMq的SpringCloud Stream框架实战入门
2、如何搭建消息中间件应用框架之SpringCloud Stream
3、面试必备:网关异常了怎么办?如何做全局异常处理?
4、Gateway网关系列(二):SpringCloud Gateway入门实战,路由规则
5、Gateway网关系列开篇:SpringCloud的官方网关Gateway介绍
6、API网关在微服务架构中的应用,这一篇就够了
7、学习Lambda表达式看这篇就够了,不会让你失望的哦(续篇)
8、Lambda用在哪里?几种场景?
9、为什么会出现Lambda表达式,你知道吗?
10、不说“分布式事务”理论,直接上大厂阿里的解决方案,绝对实用
11、女程序员问到这个问题,让我思考了半天,Mysql的“三高”架构
12、大厂二面:CAP原则为什么只能满足其中两项?而不能同时满足
13、阿里P7二面:聊聊零拷贝的原理
14、秒杀系统的核心点都在这里,快来取
15、你了解如何利用token方式实现分布式Session吗?
16、Mysql索引结构演变,为什么最终会是那个结构呢?让你一看就懂
17、一场比赛涉及到的知识,用通俗易通的方式介绍并发协调
18、企业实战Redis全方面思考,你思考了吗?
19、面试题:Thread的start和run的区别
20、面试题:什么是CAS?CAS的作用以及缺点
21、如何访问redis中的海量数据?避免事故产生
22、如何解决Redis热点问题?以及如何发现热点?
23、如何设计API接口,实现统一格式返回?
24、你真的知道在生产环境下如何部署tomcat吗?
25、分享一线互联网大厂分布式唯一ID设计 之 snowflake方案
26、分享大厂分布式唯一ID设计方案,快来围观
27、你想了解一线大厂的分布式唯一ID生成方案吗?
28、你知道如何处理大数据量吗?(数据拆分篇)
29、如何永不迁移数据和避免热点? 根据服务器指标分配数据量(揭秘篇)
30、你知道怎么分库分表吗?如何做到永不迁移数据和避免热点吗?
31、你了解大型网站的页面静态化吗?
32、你知道如何更新缓存吗?如何保证缓存和数据库双写一致性?
33、你知道怎么解决DB读写分离,导致数据不一致问题吗?
34、DB读写分离情况下,如何解决缓存和数据库不一致性问题?
35、你真的知道怎么使用缓存吗?
36、如何利用锁,防止缓存击穿?重构思想的重要性
37、海量订单产生的业务高峰期,如何避免消息的重复消费?
38、你知道如何保障生产端100%消息投递成功吗?
39、微服务下的分布式session该如何管理?
40、阿里二面:filter、interceptor、aspect应如何选择?很多人中招
41、互联网架构重要组员CDN,很多高级开发都没有实操过,来看这里
42、阿里二面:CDN缓存控制原理,看看能不能难住你
43、SpringCloud Alibaba之Nacos多环境多项目管理
44、SpringCloud Alibaba系列之Nacos配置中心玩法
45、SpringCloud Alibaba之Nacos注册中心
46、SpringCloud Plus版本之SpringCloud Alibaba
47、SpringCloud Alibaba之Nacos集群、持久化
48、SpringCloud Alibaba之Nacos共享配置、灰度配置
49、SpringCloud Alibaba之Sentinel工作原理
50、SpringCloud Alibaba之Sentinel流控管理
51、SpringCloud Alibaba之Sentinel降级管理
52、SpringCloud Alibaba之Sentinel热点参数限流
53、SpringCloud Alibaba之Sentinel的API实战
閱讀更多 老顧聊技術 的文章