SpringBoot进阶教程(七十二)整合Apollo
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。
v架构一览
上图简要描述了Apollo的总体设计:
- Config Service提供配置的读取、推送等功能,服务对象是Apollo客户端
- Admin Service提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)
- Config Service和Admin Service都是多实例、无状态部署,所以需要将自己注册到Eureka中并保持心跳
- 在Eureka之上我们架了一层Meta Server用于封装Eureka的服务发现接口
- Client通过域名访问Meta Server获取Config Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Client侧会做load balance、错误重试
- Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试
- 为了简化部署,我们实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中
vDocker部署Apollo
1. 准备MySQL
git clone https://github.com/ctripcorp/apollo.git
将克隆的sql拷贝到docker实例中(docker实例中的路径/opt/apollo/script需要自行创建)(注意,也可以直接下载对应的两个sql脚本。)
docker cp /data/app/apollo/source-code/apollo/scripts/sql mysql3308:/opt/apollo/scripts
进入docker实例执行sql脚本。
docker exec -it mysql3308 bash
2. 镜像拉取
docker pull apolloconfig/apollo-configservice
docker pull apolloconfig/apollo-adminservice
docker pull apolloconfig/apollo-portal
3. apollo-configservice
docker run -d \
--name apollo-configservice \
--net=host \
-v /tmp/logs:/opt/logs \
-e SPRING_DATASOURCE_URL="jdbc:mysql://ip.ip.ip.ip:3308/ApolloConfigDB?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root \
-e SPRING_DATASOURCE_PASSWORD=password \
apolloconfig/apollo-configservice
注意默认apollo-configservice的端口是8080, 可能会引起端口冲突。如果需要修改apollo-configservice的端口,记得同时修改Eureka的地址,在ApolloConfigDB库中ServerConfig表的value值,默认是8080的。否则其他服务注册不上去。
另外,若apollo和mysql都是一台虚机上的docker,mysql链接字符串 jdbc:mysql://ip.ip.ip.ip:3308/ApolloConfigDB?characterEncoding=utf8
中的ip.ip.ip.ip不要使用127.0.0.1。docker部署apollo中其它使用到ip的地方也不要使用127.0.0.1。
SPRING_DATASOURCE_URL: 对应环境ApolloConfigDB的地址
SPRING_DATASOURCE_USERNAME: 对应环境ApolloConfigDB的用户名
SPRING_DATASOURCE_PASSWORD: 对应环境ApolloConfigDB的密码
4. apollo-adminservice
docker run -d \
--name apollo-adminservice \
--net=host \
-v /tmp/logs:/opt/logs \
-e SPRING_DATASOURCE_URL="jdbc:mysql://ip.ip.ip.ip:3308/ApolloConfigDB?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root \
-e SPRING_DATASOURCE_PASSWORD=password \
apolloconfig/apollo-adminservice
SPRING_DATASOURCE_URL: 对应环境ApolloConfigDB的地址
SPRING_DATASOURCE_USERNAME: 对应环境ApolloConfigDB的用户名
SPRING_DATASOURCE_PASSWORD: 对应环境ApolloConfigDB的密码
5. apollo-portal
docker run -d \
--name apollo-portal \
--net=host \
-v /tmp/logs:/opt/logs \
-e SPRING_DATASOURCE_URL="jdbc:mysql://ip.ip.ip.ip:3308/ApolloPortalDB?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root \
-e SPRING_DATASOURCE_PASSWORD=password \
-e APOLLO_PORTAL_ENVS=dev \
-e DEV_META=http://ip.ip.ip.ip:8080 \
apolloconfig/apollo-portal
SPRING_DATASOURCE_URL: 对应环境ApolloPortalDB的地址
SPRING_DATASOURCE_USERNAME: 对应环境ApolloPortalDB的用户名
SPRING_DATASOURCE_PASSWORD: 对应环境ApolloPortalDB的密码
APOLLO_PORTAL_ENVS(可选): 对应ApolloPortalDB中的apollo.portal.envs配置项,如果没有在数据库中配置的话,可以通过此环境参数配置
DEV_META/PRO_META(可选): 配置对应环境的Meta Service地址,以${ENV}_META命名,需要注意的是如果配置了ApolloPortalDB中的apollo.portal.meta.servers配置,则以apollo.portal.meta.servers中的配置为准
6. 验证apollo
url访问http://toutou.com:8070,效果如下:可以使用系统自带账号/密码登录:apollo/admin。
7. 创建项目
点击首页创建项目,创建好了提交,然后回到首页即可看到创建好的项目。
8. 新增配置
9. 发布配置
配置添加好选择好对应的环境之后,点击发布即可。
vspringboot整合Apollo
1. 添加引用
<dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> <version>1.7.0</version> </dependency>
2. 添加配置
application.properties:
#AppId是应用的身份信息,是配置中心获取配置的一个重要信息。
app.id=abc10086def
#在应用启动阶段,向Spring容器注入被托管的application.properties文件的配置信息。
apollo.bootstrap.enabled = true
#开启apollo后你的Eureka注册中心的地址
apollo.meta=http://toutou.com:8080
#将Apollo配置加载提到初始化日志系统之前(1.2.0+)
#从1.2.0版本开始,如果希望把日志相关的配置(如logging.level.root=info或logback-spring.xml中的参数)也放在Apollo管理,那么可以额外配置apollo.bootstrap.eagerLoad.enabled=true来使Apollo的加载顺序放到日志系统加载之前。
apollo.bootstrap.eagerLoad.enabled=true
3. 接口代码
package learn.web.controller; import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.spring.annotation.ApolloConfig; import learn.model.vo.Result; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.beans.factory.annotation.Value; import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; /** * @author toutou * @date by 2021/2 * @des https://www.cnblogs.com/toutou */ @Slf4j @RestController @EnableApolloConfig public class IndexController { @Value("${demo.default.message}") private String helloMessage; @ApolloConfig private Config config; @GetMapping("apollo/message") public Result apolloMessage() { return Result.setSuccessResult(config.getProperty("demo.default.message", "null")); } @GetMapping("apollo/message2") public Result apolloMessage2() { return Result.setSuccessResult(helloMessage); } }
4. 验证效果
5. 获取apollo配置的多种方式
1.通过@value注解获取配置值 例如: @Value("${demo.default.message}") private String message; 2.通过@ConfigurationProperties注入到bean对象中获取配置信息 例如: @ConfigurationProperties(prefix="test") Public class Myprop{ private Map<String,String> prop = Maps.newLinkedHashMap(); } 在被spring管理的类中使用: @Autowired private Myprop myprop; prop.getProp().get("name"); 注:使用这种方式获取的属性值不会实时更新。 3.通过@ApolloConfig获取注入的config对象,再通过config对象获取属性值 例如: 在被spring管理的类中使用: @ApolloConfig private Config config; config.getProperty("demo.default.message",null); 4.通过java API的方式获取 Config config = ConfigService.getAppConfig(); String someKey = "someKeyFromDefaultNamespace"; String someDefaultValue = "someDefaultValueForTheKey"; String value = config.getProperty(someKey, someDefaultValue); 5.在配置文件中获取属性值 例如:在application.properties中, spring.datasource.name=${jdbc.name} spring.datasource.password=${jdbc.password}
其他参考/学习资料:
v源码地址
https://github.com/toutouge/javademosecond/tree/master/hellolearn
作 者:请叫我头头哥
出 处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!