背景
在项目开发中,我们经常会遇到这么一种问题,就是开发、测试、线上环境连接的数据库、redis等参数配置都是不一样的,当我们在开发环境把项目开发完成之后,就需要将代码放到测试或者线上环境,由于不同环境的参数是不一样的,我们还得将配置文件修改一遍,这样很麻烦,现在出现一个可以动态配置不同环境参数变量的工具,apollo,可以很方便的就解决了我们遇到的难题。
Apollo是由携程框架部门研发的分布式配置中心,能够集中化管理不同环境、不同集群的配置,配置修改后能实时的推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置场景
github地址:https://github.com/ctripcorp/...
搭建apollo服务器
Apollo的存储工具是Mysql,所以要启动apollo的服务,首先要安装一套Mysql数据库
Apollo的服务端需要的jdk版本是1.8+Apollo客户端需要的jdk的版本是1.7+
Mysql需要的版本号是5.6.5+
安装Mysql数据库
具体安装过程不说了
安装apollo项目
下载quick start安装包
下载地址:https://github.com/nobodyiam/...
解压并执行sql文件
将下载下来的mater.zip进行解压,并执行sql文件夹下面的两个sql脚本
source {本地目录}/apollo-build-scripts-master/sql/apolloconfigdb.sql
source {本地目录}/apollo-build-scripts-master/sql/apolloportaldb.sql
执行完之后查看是否执行成功
select `NamespaceId`, `Key`, `Value`, `Comment` from ApolloConfigDB.Item;
配置数据库连接信息
修改demo.sh脚本
#apollo config db info
apollo_config_db_url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8
apollo_config_db_username=用户名
apollo_config_db_password=密码(如果没有密码,留空即可)
# apollo portal db info
apollo_portal_db_url=jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8
apollo_portal_db_username=用户名
apollo_portal_db_password=密码(如果没有密码,留空即可)
启动apollo服务
由于apollo会在本地启动三个服务,分别会使用到8070,8080,8090三个端口,所以需要看看这三个端口是否被占用
lsof -i:8070
lsof -i:8080
lsof -i:8090
执行脚本
./demo.sh start
会出现下面的日志信息
==== starting service ====
Service logging file is ./service/apollo-service.log
Started [25980]
Waiting for config service startup........
Config service started. You may visit http://localhost:8080 for service status now!
Waiting for admin service startup...
Admin service started
==== starting portal ====
Portal logging file is ./portal/apollo-portal.log
Started [26217]
Waiting for portal startup........
Portal started. You can visit http://localhost:8070 now!
登录apollo
初始密码是apollo/admin
配置apollo
点击SampleApp进入AppId是SampleApp的管理界面
分布式环境下Apollo服务搭建
Apollo客户端配置
添加apollo-client对应的jar包
com.ctrip.framework.apollo
apollo-client
1.1.2
在pom.xml中添加如下配置
local
http://localhost:8080
template_portal
D:\apollo\data
dev
http://ip:8080
template_portal
D:\apollo\data
true
uat
http://ip:8080
template_portal
/opt/data/
pro
http://ip1:8080,http://ip2:8080
template_portal
/opt/data/
注意:configService和Meta Server基本上都在一个jvm中,不同环境(开发、测试、线上)对应的configService服务是不一样的,所以配置的meta server地址也是不一样的
注意:如果configService服务注册到MetaServer服务的IP和端口号是内网地址,我们在外网拉取到内网IP和端口号是访问不通的,这个时候我们可以在启动时配置一下configService服务的外网IP和端口号:-Dapollo.configService=http://外网IP:端口号 ,通过这种方式,我们就可以直接去访问配置的服务拉取配置信息了
注意:我们在配置了不同的环境下使用不同的配置参数,那么开发环境、仿真环境、线上环境需要在Jenkins启动打包的时候,需要配置上参数-Ppro或者-Puat,如果想使用本地缓存着的配置,使用参数配置:-Denv=Local
如果在settings.xml中定义profile设置默认激活时的配置如下:
profileTest1
profileTest2
关于profile具体配置可以参考博客:https://elim.iteye.com/blog/1...
敏感参数信息加密
- 首先需要一个加密用的字符串,salt字符串,最好长一点,比如ED3C9ADB0A53474098F594D0FD561E9E
单独创建一个配置文件,比如encryptor.properties,这个配置文件是不会放到apollo上进行管理的
里面的配置内容如下:
jasypt.encryptor.password=ED3C9ADB0A53474098F594D0FD561E9E
然后配置springboot加载这个配置文件
@PropertySource(value = {"classpath:prop/encryptor.properties"}, name = "encryptor.properties", ignoreResourceNotFound = false)
@Configuration
public class WebMvcConfigurerInitializer extends WebMvcConfigurerAdapter {
- 导入加密的jar包
com.github.ulisesbocchio
jasypt-spring-boot-starter
2.1.0
jdk7版本的就使用下面的jar包
com.github.ulisesbocchio
jasypt-spring-boot-starter
1.5-java7
- 加需要加密的字符串信息使用下面代码进行加密处理
public static void main(String[] args) {
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword("ED3C9ADB0A53474098F594D0FD561E9E");
System.out.println("加密后:"+textEncryptor.encrypt("${需要加密的字符串}"));
System.out.println("解密后:"+textEncryptor.decrypt("${需要解密的字符串}"));
}
或者使用jar包进行加密解密操作,jar包路径:D:installedmavenlocal_repositoryorgjasyptjasypt1.9.2
// 加密
java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI password=ED3C9ADB0A53474098F594D0FD561E9E algorithm=PBEWithMD5AndDES input=要加密的字符串
// 解密
java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI password=ED3C9ADB0A53474098F594D0FD561E9E algorithm=PBEWithMD5AndDES input=要解密的字符串
最后发现用这两种方式加密出来的字符串每次都不一样,但是都是可以使用的。
- 修改apollo配置中的关键信息
如:
spring.datasource.username=ENC(加密后的字符串)
spring.datasource.password=ENC(加密后的字符串)