用簡單的方式來做不同AP的設定同步,使用 SpringCloud 跟 RabbitMQ
Spring Cloud Config Server
簡單說,你Server端可以從GitHub上或是本地檔案載入設定檔,當Client端啟動時會去Server上拉需要的設定參數下來
build.gradle
buildscript {
ext {
springBootVersion = '1.2.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("io.spring.gradle:dependency-management-plugin:0.5.2.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'io.spring.dependency-management'
jar {
baseName = 'Demo-Server'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile("org.springframework.cloud:spring-cloud-config-server:1.0.2.RELEASE")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
}
}
server:
port: 8888
spring:
cloud:
config:
server:
git :
uri: https://github.com/samzhu/microservices-lab-configuration
bootstrap.yml
spring:
application:
name: config-service
ConfigServerApplication.java
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
build.gradle
buildscript {
ext {
springBootVersion = '1.2.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("io.spring.gradle:dependency-management-plugin:0.5.2.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'io.spring.dependency-management'
jar {
baseName = 'Demo-Client'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.cloud:spring-cloud-config-client:1.0.2.RELEASE')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-actuator')
testCompile("org.springframework.boot:spring-boot-starter-test")
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
}
}
application.yml
server:
port: 8080
spring:
application:
name: config-client
cloud:
config:
uri: http://localhost:8888
Application.java
package demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;
@SpringBootApplication
public class Application {
@Autowired
void setEnvironment(Environment e) {
System.out.println(e.getProperty("configuration.projectName"));
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
ProjectNameRestController.java
package demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope
public class ProjectNameRestController {
@Value("${configuration.projectName}")
private String projectName;
@RequestMapping("/project-name")
public String projectName() {
return this.projectName;
}
}
啟動後Client可以從Server取得GitHub上的設定值
config-client.properties
configuration.projectName=Spring Cloud
向Server端確認參數
curl -X GET 'http://localhost:8888/config-client/master'
{
"name": "config-client",
"profiles": [
"master"
],
"label": "master",
"propertySources": [
{
"name": "https://github.com/samzhu/microservices-lab-configuration/config-client.properties",
"source": {
"configuration.projectName": "Spring Cloud"
}
}
]
}
向Client取得project-name
curl -X GET 'http://localhost:8080/project-name'
Spring Cloud
更新GitHub上的檔案
configuration.projectName=Spring Cloud Sam Test
觸發Client更新
curl -X POST 'http://localhost:8080/refresh'
[
"configuration.projectName"
]
再檢查可以發現已經更新了
curl -X GET 'http://localhost:8080/project-name'
Spring Cloud Sam Test
但是這樣子還是必須每一台 Client 去觸發 Refresh,所以 Spring Cloud 提供一個做法透過 RabbitMQ 來觸發
build.gradle 增加 dependencies
compile('org.springframework.cloud:spring-cloud-starter-bus-amqp:1.0.3.RELEASE')
application.yml 增加 rabbitmq 部分
spring:
rabbitmq:
addresses: ${vcap.services.${PREFIX:}rabbitmq.credentials.uri:amqp://${RABBITMQ_HOST:192.168.56.102}:${RABBITMQ_PORT:5672}}
練習安裝在Ububtu上
echo "deb http://www.rabbitmq.com/debian/ testing main" | sudo tee -a /etc/apt/sources.list.d/rabbitmq.list
# 加入 APT repository
wget https://www.rabbitmq.com/rabbitmq-signing-key-public.asc
sudo apt-key add rabbitmq-signing-key-public.asc
sudo apt-get update
# 安裝 RabbitMQ server 套件
sudo apt-get install rabbitmq-server
# 啟用 RabbitMQ Management Web Console
sudo rabbitmq-plugins enable rabbitmq_management
# 開啟遠端使用者可登入 web console
sudo sh -c "echo '[{rabbit, [{loopback_users, []}]}].' > /etc/rabbitmq/rabbitmq.config"
sudo service rabbitmq-server restart
# 開啟瀏覽器使用 guest guest 登入觀察
http://192.168.56.102:15672/
之後啟動兩個 Client
java -jar Demo-Client-0.0.1-SNAPSHOT.jar
java -jar Demo-Client-0.0.1-SNAPSHOT.jar --server.port=9000
重複上面動作 更新 GitHub檔案後
對 Client 8080 送出更新指令
curl -X POST 'http://localhost:8080/bus/refresh'
可以發現 Client 9000 也更新了
curl -X GET 'http://localhost:9000/project-name'