springboot簡單集成diamond實現配置中心

springboot簡單集成diamond

diamond源碼下載:https://github.com/gzllol/diamond。

搭建
Diamond -- 分佈式配置中心
一、簡介
Diamond是淘寶研發的分佈式配置管理系統。使用Diamond可以讓集羣中的服務進程動態感知數據的變化,無需重啓服務就可以實現配置數據的更新。
具有簡單、可靠、易用等特點
二、使用方法
服務端搭建
1 準備工作
安裝jdk
安裝maven
安裝tomcat
安裝mysql
2 啓動mysql並創建數據庫和表
-- 創建Diamond數據庫
CREATE DATABASE IF NOT EXISTS `diamond` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `diamond`;


-- 配置表
CREATE TABLE IF NOT EXISTS `config_info` (
  `id` bigint(64) unsigned NOT NULL AUTO_INCREMENT,
  `data_id` varchar(255) NOT NULL DEFAULT '',
  `group_id` varchar(128) NOT NULL DEFAULT '',
  `content` longtext NOT NULL,
  `md5` varchar(32) NOT NULL DEFAULT '',
  `src_ip` varchar(20) DEFAULT NULL,
  `src_user` varchar(20) DEFAULT NULL,
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_config_datagroup` (`data_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- 數據導出被取消選擇。


-- 組表
CREATE TABLE IF NOT EXISTS `group_info` (
  `id` bigint(64) unsigned NOT NULL AUTO_INCREMENT,
  `address` varchar(70) NOT NULL DEFAULT '',
  `data_id` varchar(255) NOT NULL DEFAULT '',
  `group_id` varchar(128) NOT NULL DEFAULT '',
  `src_ip` varchar(20) DEFAULT NULL,
  `src_user` varchar(20) DEFAULT NULL,
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_group_address` (`address`,`data_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

3、打包
修改diamond-server/src/main/resources/system.properties文件,將diamond.server.addr的值換成Diamond服務器所在機器的ip地址
修改diamond-server/src/main/resources/jdbc.properties文件,配置mysql服務器的url,用戶名和密碼
diamond-server/src/main/resources/user.properties文件配置diamond登錄賬戶,默認是:abc=123
修改diamond-client/src/main/java/com/taobao/diamond/client/DiamondConfigure.java類的loadConfig()方法
private void loadConfig() {
    URL url = this.getClass().getClassLoader().getResource("diamond.properties");
    if (url != null) {
        File file = new File(url.getFile());
        Properties prop = new Properties();
        try {
            prop.load(new FileInputStream(file));
            configServerAddress = prop.getProperty(Constants.CONF_KEY_CONFIG_IP, Constants.DEFAULT_DOMAINNAME);
            String portStr = prop.getProperty(Constants.CONF_KEY_PORT, "8080");
            try {
                port = Integer.parseInt(portStr);
            } catch (NumberFormatException nfe) {
                port = 8080;
            }
            //新增代碼
            configServerPort=port;
        } catch (IOException e) {
        }
    }
}
在根目錄執行打包命令
mvn clean package -Dmaven.test.skip=true

4、server部署
diamond-server/target/diamond-server.war解壓
使用的apache-tomcat-6.0.37部署,需要發佈到ROOT,默認源碼裏面的請求沒有項目後綴

需要注意,tomcat的路徑不要用空格,空格識別存在問題。

 

springboot簡單集成diamond-client

把diamond-client-2.0.5.4.taocode-SNAPSHOT.jar和diamond-utils-2.0.5.4.taocode-SNAPSHOT.jar上傳maven

mvn install:install-file -DgroupId=com.taobao.diamond -DartifactId=diamond-client -Dversion=2.0.5.4.taocode-SNAPSHOT -Dpackaging=jar -Dfile=F:\deploy\diamond-master\diamond-client\target\diamond-client-2.0.5.4.taocode-SNAPSHOT.jar

 

mvn install:install-file -DgroupId=com.taobao.diamond -DartifactId=diamond-utils -Dversion=2.0.5.4.taocode-SNAPSHOT -Dpackaging=jar -Dfile=F:\deploy\diamond-master\diamond-utils\target\diamond-utils-2.0.5.4.taocode-SNAPSHOT.jar

jar包引入:

<dependency>
 <groupId>com.taobao.diamond</groupId>
 <artifactId>diamond-client</artifactId>
 <version>2.0.5.4.taocode-SNAPSHOT</version>
</dependency>
<dependency>
 <groupId>com.taobao.diamond</groupId>
 <artifactId>diamond-utils</artifactId>
 <version>2.0.5.4.taocode-SNAPSHOT</version>
</dependency>

創建ApplicationConfigurer.java進行讀取diamond的配置內容,此文件暫時只能加載properties格式的配置內容

 

package com.wakeboy.config;

import com.github.pagehelper.util.StringUtil;
import com.taobao.diamond.manager.DiamondManager;
import com.taobao.diamond.manager.ManagerListener;
import com.taobao.diamond.manager.impl.DefaultDiamondManager;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.ConfigurationRuntimeException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.concurrent.Executor;

/**
 * @program: ytsafe-parent
 * @Date: 2020/5/18 13:57
 * @Author: liuhx
 * @Description:加載配置中心配置信息
 * @Version 1.0
 */
@Configuration
public class ApplicationConfigurer {

    private static final Logger logger = LoggerFactory.getLogger(ApplicationConfigurer.class);

    //diamond系統配置的dataId
    String dataId;

    @Bean
    public PropertySourcesPlaceholderConfigurer createPropertySourcesPlaceholderConfigurer() throws ConfigurationException, IOException {
        PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();

        //加載diamond配置信息
        loadDiamondConfig();

        if(!StringUtil.isEmpty(dataId)){
            String[] dataIds=dataId.split(",");
            for (int i = 0; i < dataIds.length; i++) {
                //diamond客戶端調用服務端獲取配置信息
                DiamondManager manager = new DefaultDiamondManager(dataIds[i], new ManagerListener() {
                    @Override
                    public Executor getExecutor() {
                        return null;
                    }

                    @Override
                    public void receiveConfigInfo(String configInfo) {
                        //配置信息動態修改將觸發此方法
                        System.out.println("receive config: " + configInfo);
                        propertyPlaceholderConfigurer.setProperties(getProperties(new StringReader(configInfo)));
                    }
                });
                /**
                 * 同步獲取一份有效的配置信息,按照<strong>本地文件->diamond服務器->上一次正確配置的snapshot</strong>
                 * 的優先順序獲取, 如果這些途徑都無效,則返回null
                 *
                 * @param timeout
                 *            從網絡獲取配置信息的超時,單位毫秒
                 * @return 配置信息
                 */
                String configInfo = manager.getAvailableConfigureInfomation(1000);
                //關閉
                //manager.close();
                //解析Propertie配置信息
                propertyPlaceholderConfigurer.setProperties(getProperties(new StringReader(configInfo)));
            }
        }
        return propertyPlaceholderConfigurer;
    }
    /***
    * @Description: 獲取所有屬性
    * @param  * @param in
    * @Return: java.util.Properties
    * @Author: liuhx
    * @Date: 2020/5/19 12:13
    */
    private Properties getProperties(StringReader in) {
        Map<String,String> map=getPropertisMap(in);
        Properties properties = new Properties();
        for (String key : map.keySet()) {
            properties.setProperty(key, map.get(key));
        }
        return properties;
    }
    /***
    * @Description: 解析文件內容
    * @param  * @param in
    * @Return: java.util.Map
    * @Author: liuhx
    * @Date: 2020/5/19 12:12
    */
    private Map getPropertisMap(StringReader in) {
        Map<String,String> map=new HashMap<String,String>();
        PropertiesConfiguration.PropertiesReader reader = new PropertiesConfiguration.PropertiesReader(in);
        try {
            while (reader.nextProperty()) {
                String key = reader.getPropertyName();
                String value = reader.getPropertyValue();
                map.put(key, value);
            }
        } catch (IOException ioex) {
            throw new ConfigurationRuntimeException(ioex);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                logger.error("load config exception", e);
            }finally {
                return map;
            }
        }
    }
    /**
    * @Description: 加載diamond配置信息
    * @param  * @param
    * @Return: void
    * @Author: liuhx
    * @Date: 2020/5/19 15:41
    */
    private void loadDiamondConfig(){
        URL url = this.getClass().getClassLoader().getResource("diamond.properties");
        if (url != null) {
            File file = new File(url.getFile());
            Properties prop = new Properties();
            try {
                prop.load(new FileInputStream(file));
                dataId=prop.getProperty("diamond.dataId");
            } catch (IOException e) {
            }
        }
    }
}

創建diamond.properties配置文件

diamond.port=8081
diamond.config.ip=127.0.0.1
diamond.dataId=1,2

項目啓動截圖