1. 程式人生 > >Spring Boot整合攜程Apollo配置中心

Spring Boot整合攜程Apollo配置中心

batch sts ade 文件 context rac bean -m space

攜程官網對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

Spring Boot整合攜程Apollo配置中心