Spring Boot整合携程Apollo配置中心

携程官网对apollo的使用讲解了很多种方式的使用,但是感觉一些细节还是没讲全,特别是eureka配置中心地址的配置

这里对springboot整合apollo说一下

>SpringBoot启动vm参数添加:
-Ddev_meta=http://18.16.200.107:8080 -Denv=DEV
其中-Ddev-meta连接的是配置管理eureka的url地址
-Denv配置的是具体的环境

>也可以在C:\opt\settings\server.properties中添加环境配置:
env=DEV
这个配置文件里面只能配置环境,不能配置url

>第一步配置app.id,在META-INF/app.properties里面添加app.id,类型字符串

代码:

package com.qhong.springboot;

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 lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 使用Java Config方式
 * 使用@ApolloConfig自动注入Config对象
 * 使用@ApolloConfigChangeListener自动注入ConfigChangeListener对象
 * 当监听到属性值发生变化后使用Config API修改属性值
 */
@ToString
@Component
@ConfigurationProperties
public class JavaConfigSample {
    /**
     * @ApolloConfig用来自动注入Config对象
     */
    @ApolloConfig
    private Config config;
    /**
     * @ApolloConfigChangeListener用来自动注册ConfigChangeListener
     */
    @ApolloConfigChangeListener
    private void someOnChange(ConfigChangeEvent changeEvent) {
        changeEvent.changedKeys().forEach(key ->{
            ConfigChange change = changeEvent.getChange(key);
            System.out.println(String.format("Found JavaConfigSample change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
        });
    }


    @Value("${timeout:100}")
    private int timeout;
    private int batch;

    @Value("${batch:200}")
    public void setBatch(int batch) {
        this.batch = batch;
    }

    public int getTimeout() {
        if(config!=null) {
            return config.getIntProperty("timeout", 100);
        }else{
            return timeout;
        }
    }

    public int getBatch() {
        return this.batch;
    }
}

这个类里面timeout获取值的方式直接调用getIntProperty

package com.qhong.springboot;

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 com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 使用Spring Boot ConfigurationProperties方式
 * <pre>
 * redis.cache.enabled = true
 * redis.cache.expireSeconds = 100
 * redis.cache.clusterNodes = 1,2
 * redis.cache.commandTimeout = 50
 * redis.cache.someMap.key1 = a
 * redis.cache.someMap.key2 = b
 * redis.cache.someList[0] = c
 * redis.cache.someList[1] = d
 * </pre>
 */
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "redis.cache")
@EnableApolloConfig("application")
public class ConfigurationPropertiesSample {

    private int expireSeconds;
    private String clusterNodes;
    private int commandTimeout;

    private Map<String, String> someMap = Maps.newLinkedHashMap();
    private List<String> someList = Lists.newLinkedList();

    @PostConstruct
    private void initialize() {
        System.out.println(String.format(
            "SampleRedisConfig initialized - expireSeconds: {}, clusterNodes: {}, commandTimeout: {}, someMap: {}, someList: {}",
            expireSeconds, clusterNodes, commandTimeout, someMap, someList));
    }

    /**
     * @ApolloConfig用来自动注入Config对象
     */
    @ApolloConfig("application")
    private Config config;
    /**
     * @ApolloConfigChangeListener用来自动注册ConfigChangeListener
     */
    @ApolloConfigChangeListener("application")
    private void someOnChange(ConfigChangeEvent changeEvent) {
        changeEvent.changedKeys().forEach(key ->{
            ConfigChange change = changeEvent.getChange(key);
            System.out.println(String.format("Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
        });
    }
}

这个是各种属性类型的使用

apollo配置中心文本格式:

esb.app.url = http://18.16.200.10:3000/
endpoints.shutdown.enabled = true
endpoints.shutdown.sensitive = false
spring.http.multipart.maxFileSize = 100Mb
spring.http.multipart.max-request-size = 100Mb

timeout = 120
batch = 222
redis.cache.enabled = false
redis.cache.expireSeconds = 154
redis.cache.clusterNodes = 1,2,3,4
redis.cache.commandTimeout = 60
redis.cache.someMap.key1 = a
redis.cache.someMap.key2 = b
redis.cache.someList[0] = c
redis.cache.someList[1] = d

上面两种都是默认的namespace,为application

下面添加一个datasource命名空间类型的类

package com.qhong.springboot;

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 lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * Created by qhong on 2018/5/8 16:10
 **/
@ToString
@Component
@Data
@ConfigurationProperties
@EnableApolloConfig("datasource")
public class DataSourceConfig {
    // 动态配置从esb config读取
    private String url;
    private String username;
    private String password;
    private String driverClassName;

    /**
     * @ApolloConfig用来自动注入Config对象
     */
    @ApolloConfig("datasource")
    private Config config;

    /**
     * @ApolloConfigChangeListener用来自动注册ConfigChangeListener
     */
    @ApolloConfigChangeListener("datasource")
    private void someOnChange(ConfigChangeEvent changeEvent) {
        changeEvent.changedKeys().forEach(key ->{
            ConfigChange change = changeEvent.getChange(key);
            System.out.println(String.format("Found datasource change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
        });
    }

}

注意EnableApolloConfig中定义datasource命名空间

上面类的具体文本:

url = jdbc:mysql://120.26.130.187:3306/huishi-server?useUnicode=true&characterEncoding=utf-8&useSSL=false
username = root
password = jsy2016memeda
driverClassName = com.mysql.jdbc.Driver

当然也可以使用ApolloConfig这个定义datasource命名空间的,然后一个个getProperty来获取值,就是有点不方便。

下面使用SpringBoot启动:

package com.qhong.springboot;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication(scanBasePackages = {"com.qhong.springboot"})
public class Application {
    public static void main(String[] args) throws Exception {
        ApplicationContext context = new SpringApplicationBuilder(Application.class).run(args);
        JavaConfigSample javaConfigSample = context.getBean(JavaConfigSample.class);
         ConfigurationPropertiesSample configurationPropertiesSample=context.getBean(ConfigurationPropertiesSample.class);
        DataSourceConfig dataSourceConfig=context.getBean(DataSourceConfig.class);
        System.out.println("Application Demo. Input any key except quit to print the values. Input quit to exit.");
        while (true) {
            System.out.print("> ");
            String input = new BufferedReader(new InputStreamReader(System.in, Charsets.UTF_8)).readLine();
            if (!Strings.isNullOrEmpty(input) && input.trim().equalsIgnoreCase("quit")) {
                System.exit(0);
            }

            if(javaConfigSample!=null){
                System.out.println(javaConfigSample.toString());
            }
            if(configurationPropertiesSample!=null){
                System.out.println(configurationPropertiesSample.toString());
            }
            if(dataSourceConfig!=null){
                System.out.println(dataSourceConfig);
            }

        }
    }
}

随便输入字符就可以显示监控的字段

上面代码的地址:

https://gitee.com/hongdada/spring-boot-apollo-sample

参考:

https://github.com/ctripcorp/apollo/wiki/Java%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97

猜你喜欢

转载自www.cnblogs.com/hongdada/p/9015748.html