Apollo安装与在SpringBoot下的使用

说明

What is Apollo?

随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址……

对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制……

在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。

Apollo配置中心应运而生!Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,具备规范的权限、流程治理等特性。

目前的几种配置中心对比如下:

功能点 优先级 spring-cloud-config ctrip apollo disconf 备注
静态配置管理 基于file 支持 支持  
动态配置管理 支持 支持 支持  
统一管理 无,需要github 支持 支持  
多环境 无,需要github 支持 支持  
本地配置缓存 支持 支持  
配置锁 支持 不支持 不支持 不允许动态及远程更新
配置校验 如:ip地址校验,配置
配置生效时间   重启生效,或手动refresh生效 实时 实时 需要结合热加载管理, springcloudconfig需要 git webhook+rabbitmq 实时生效
配置更新推送 需要手工触发 支持 支持  
配置定时拉取 支持 配置更新目前依赖事件驱动, client重启或者server端推送操作  
用户权限管理 无,需要github 支持 支持 现阶段可以人工处理
授权、审核、审计 无,需要github 支持 现阶段可以人工处理
配置版本管理 Git做版本管理 界面上直接提供发布历史和回滚按钮 操作记录有落数据库,但无查询接口  
配置合规检测 不支持 支持(但还需完善)    
实例配置监控 需要结合springadmin 支持 支持,可以查看每个配置在哪些机器上加载  
灰度发布 不支持 支持 不支持部分更新 现阶段可以人工处理
告警通知 不支持 支持,邮件方式告警 支持,邮件方式告警  
依赖关系 不支持 不支持 不支持 配置与系统版本的依赖系统运行时的依赖关系

更多比较->统一配置中心选型对比

快速开始

1 下载安装

首先去官网下载3个压缩包,我是用的是目前最新的1.2.0版本(apollo-adminservice,apollo-configservice,apollo-portal):

https://github.com/ctripcorp/apollo/releases

Apollo运行还需要MySQL(5.6.5+)和Eureka,Eureka安装配置可以看我以前的博客->SpringCloud Eureka服务治理模块,MySQL需要两个库ApolloPortalDB和ApolloConfigDB,建库/表的语句在官网->apolloportaldb.sql和apolloconfigdb.sql,

导入成功后,可以通过执行以下sql语句来验证:

select `Id`, `Key`, `Value`, `Comment` from `ApolloPortalDB`.`ServerConfig` limit 1;
Id Key Value Comment
1 apollo.portal.envs dev 可支持的环境列表

注:ApolloPortalDB只需要在生产环境部署一个即可

select `Id`, `Key`, `Value`, `Comment` from `ApolloConfigDB`.`ServerConfig` limit 1;
Id Key Value Comment
1 eureka.service.url http://127.0.0.1:8080/eureka/ Eureka服务Url

注:ApolloConfigDB需要在每个环境部署一套,如fat、uat和pro分别部署3套ApolloConfigDB

然后我们解压刚刚下载的3个压缩包,分别修改3个文件夹的config/application-github.properties文件的DataSource参数,修改apollo-portal-{version}-github文件夹下的config/apollo-env.properties如下:

local.meta=http://localhost:8080
dev.meta=http://127.0.0.1:8080
#fat.meta=http://fill-in-uat-meta-server:8080
#uat.meta=http://fill-in-uat-meta-server:8080
#lpt.meta=${lpt_meta}
#pro.meta=http://fill-in-pro-meta-server:8080

注:待会儿会开启3个Tomcat服务,会占用8070、8080、8090三个端口,如果需要改请修改各个文件夹下的scripts/startup.sh的SERVER_PORT参数值

分别进入三个项目启动(启动顺序:configservice->adminservice->portal):scripts/startup.sh,等待一会儿就会start了(关闭使用scripts/shutdown.sh),然后访问http://localhost:8070/即可看到登录界面,用户名/密码:apollo/admin

é¦é¡µ

注:如果Eureka不在本地,需要修改ApolloConfigDB库的ServerConfig表的eureka.service.url值为真实地址,否则报错"apollo 系统出错,请重试或联系系统负责人",如果改了还有问题是由于注册到Eureka需要时间等会或者重启服务就好了

启动成功可以在Eureka看到注册消息:APOLLO-ADMINSERVICEAPOLLO-CONFIGSERVICE

2 使用UI界面创建项目

创建项目(应用Id比较重要,如果是私有命名空间如默认的application空间,访问需要指定id号才能访问的到):

Apollo安装与在SpringBoot下的使用_第1张图片

新增配置->添加配置项:

Apollo安装与在SpringBoot下的使用_第2张图片

创建命名空间:

Apollo安装与在SpringBoot下的使用_第3张图片

最后结果:

Apollo安装与在SpringBoot下的使用_第4张图片

3 使用Springboot编写client端

项目结构如下:

Apollo安装与在SpringBoot下的使用_第5张图片

首先更新pom.xml添加一个apollo-client依赖

		
			com.ctrip.framework.apollo
			apollo-client
			1.1.2
		

更新application.yml

server:
  port: 8081
app:
  # 如果有private的命名空间需要配置(默认application空间是private的)
  id: 222
apollo:
  # 指定apollo-configservice
  meta: http://127.0.0.1:8080

启动类

package cn.yunlingfly.springbootapolloclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
// 如果都是使用默认的application命名空间可以直接在启动类使用下面的注解
//@EnableApolloConfig
public class SpringbootApolloClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootApolloClientApplication.class, args);
	}
}

Controller层

DefaultController :

package cn.yunlingfly.springbootapolloclient.controller;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableApolloConfig
public class DefaultController {
    @ApolloConfig("application")
    private Config config; //inject config for namespace application

    @Value("${key2:test}")//如果配置中心没有值,默认key为key2的value值为test
    private String name;

    //config change listener for namespace application
    @ApolloConfigChangeListener("application")
    private void anotherOnChange(ConfigChangeEvent changeEvent) {
        ConfigChange change = changeEvent.getChange("key2");
        System.out.println(String.format("Found change - key: %s, oldValue: %s,"
                + " newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
    }

    // 通过注解的方式
    @RequestMapping(value = "/getIndex",method = RequestMethod.GET)
    public String index(){
        return name;
    }

    // 通过Api的方式(不推荐)
    @RequestMapping(value = "/apiIndex",method = RequestMethod.GET)
    public String apiIndex(){
        // 使用默认命名空间"application"
        String someKey = "key2";
        String someDefaultValue = "defaultValue";
        String value = config.getProperty(someKey, someDefaultValue);
        return value;
    }
}

NameSpaceController :

package cn.yunlingfly.springbootapolloclient.controller;

import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
// 指定命名空间
@EnableApolloConfig("aaa")
public class NameSpaceController {
    @Value("${namespace:test}")//如果配置中心没有值,使用命名空间aaa,默认key为namespace的value值为test
    private String namespace;

    // 使用命名空间
    @RequestMapping(value = "/namespace",method = RequestMethod.GET)
    public String namespace(){
        return namespace;
    }
}

4 测试

访问:

http://localhost:8081/getIndex(使用注解形式)

http://localhost:8081/apiIndex(使用api形式)

http://localhost:8081/namespace(测试命名空间)

更多使用访问官网:Java客户端使用指南

你可能感兴趣的:(Spring,Boot)