本文參考了:
http://blog.didispace.com/springcloud7/
http://blog.didispace.com/springcloud8/
問題:如何實現對配置信息的實時更新?
雖然,我們已經能夠通過/refresh接口和Git倉庫的Web Hook來實現Git倉庫中的內容修改觸發應用程序的屬性更新。但是,如果所有觸發操作均需要我們手工去維護Web Hook中的應用位置的話,隨著系統的不斷擴張,會變的越來越難以維護,而消息代理中間件是解決該問題最為合適的方案。
消息代理有這樣一個功能:消息代理中間件可以將消息路由到一個或多個目的地。利用這個功能,我們就能完美的解決該問題,下面我們來說說Spring Cloud Bus中的具體實現方案。
消息總線和RabbitMQ結合實現
RabbitMQ的基礎知識和使用方法
1、簡介
MQ(Message Queue)消息隊列,用于應用系統解耦、消息異步分發。 RabbitMQ是一個在AMQP基礎上完整的,可復用的企業消息系統。
其優點如下:
1)Reliability-可靠性高。
2)Flexible Routing-路由靈活。
3)Clustering-支持集群。
4)Federation-支持互聯。
5)Tracing-便于追蹤。
RabbitMQ的安裝與使用實踐。
實踐環境:Window7 x64系統。
2、安裝
安裝Erland,通過官方下載頁面http://www.erlang.org/downloads
獲取exe安裝包,直接打開并完成安裝。
安裝RabbitMQ,通過官方下載頁面https://www.rabbitmq.com/download.html
獲取exe安裝包。
下載完成后,直接運行安裝程序。
RabbitMQ Server安裝完成之后,會自動的注冊為服務,并以默認配置啟動起來。
3、RabbitMQ啟動
Rabbit管理
我們可以直接通過配置文件的訪問進行管理,也可以通過Web的訪問進行管理。下面我們將介紹如何通過Web進行管理。
執行rabbitmq-plugins enable rabbitmq_management命令,開啟Web管理插件,這樣我們就可以通過瀏覽器來進行管理了。
#rabbitmq-plugins enable rabbitmq_management
The following plugins have been enabled:
mochiweb
webmachine
rabbitmq_web_dispatch
amqp_client
rabbitmq_management_agent
rabbitmq_management
Applying plugin configuration to rabbit@SHPWSUN3... started 6 plugins.
打開瀏覽器并訪問:http://localhost:15672/
并使用默認用戶guest登錄,密碼也為guest。我們可以看到如下圖的管理頁面:
下面我們開始具體介紹Spring Cloud Bus的配置,并以一個Spring Cloud Bus與Spring Cloud Config結合的例子來實現配置內容的實時更新。
準備工作:需要用到已經實現的關于Spring Cloud Config的幾個工程:
config-repo:定義在Git倉庫中的一個目錄,其中存儲了應用名為configsample的多環境配置文件,配置文件中有一個from參數。
config-server-eureka:配置了Git倉庫,并注冊到了Eureka的服務端。
config-client-eureka:通過Eureka發現Config Server的客戶端,應用名為configsample,用來訪問配置服務器以獲取配置信息。該應用中提供了一個/from接口,它會獲取config-repo/configsample-dev.properties中的from屬性返回。
擴展config-client-eureka應用
修改pom.xml增加spring-cloud-starter-bus-amqp模塊。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
最終的POM文件如下:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
在配置文件中增加關于RabbitMQ的連接和用戶信息
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=springcloud
spring.rabbitmq.password=123456
最終配置如下:
spring.application.name=configsample
#spring.cloud.config.uri=http://localhost:7001/
server.port=7002
#
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
#
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server
spring.cloud.config.profile=dev
management.security.enabled=false
spring.cloud.config.failFast=true
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=springcloud
spring.rabbitmq.password=123456
啟動config-server-eureka,再啟動兩個config-client-eureka(使用不同的端口7002、7003),我們可以在config-client-eureka中的控制臺中看到如下內容,在啟動時候,客戶端程序多了一個/bus/refresh請求。
o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/bus/refresh],methods=[POST]}" onto public void org.springframework.cloud.bus.endpoint.RefreshBusEndpoint.refresh(java.lang.String)
先訪問兩個config-client-eureka的/from請求,會返回當前config-repo/didispace-dev.properties中的from屬性。
接著,我們修改config-repo/configsample-dev.properties中的from屬性值,并發送POST請求到其中的一個/bus/refresh。
最后,我們再分別訪問啟動的兩個config-client-eureka的/from請求,此時這兩個請求都會返回最新的config-repo/configsample-dev.properties中的from屬性。
到這里,我們已經能夠通過Spring Cloud Bus來實時更新總線上的屬性配置了。
架構優化
既然Spring Cloud Bus的/bus/refresh接口提供了針對服務和實例進行配置更新的參數,那么我們的架構也可以做出一些調整。在之前的架構中,服務的配置更新需要通過向具體服務中的某個實例發送請求,再觸發對整個服務集群的配置更新。雖然能實現功能,但是這樣的結果是,我們指定的應用實例就會不同于集群中的其他應用實例,這樣會增加集群內部的復雜度,不利于將來的運維工作,比如:我們需要對服務實例進行遷移,那么我們不得不修改Web Hook中的配置等。所以我們要盡可能的讓服務集群中的各個節點是對等的。
因此,我們將之前的架構做了一些調整,如下圖所示:
在Config Server中也引入Spring Cloud Bus,將配置服務端也加入到消息總線中來。
spring.application.name=config-server
server.port=7001
# \u914D\u7F6E\u670D\u52A1\u6CE8\u518C\u4E2D\u5FC3
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# git\u4ED3\u5E93\u914D\u7F6E
spring.cloud.config.server.git.uri=https://git.coding.net/weimin/cloud.git/
spring.cloud.config.server.git.searchPaths=config-center/config-repo
spring.cloud.config.server.git.username=weimin
spring.cloud.config.server.git.password=730309
management.security.enabled=false
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=springcloud
spring.rabbitmq.password=123456
/bus/refresh請求不在發送到具體服務實例上,而是發送給Config Server,并可通過destination參數來指定需要更新配置的服務或實例。
通過上面的改動,我們的服務實例就不需要再承擔觸發配置更新的職責。同時,對于Git的觸發等配置都只需要針對Config Server即可,從而簡化了集群上的一些維護工作。
消息總線和Kafka結合實現
簡介
Kafka是一個由LinkedIn開發的分布式消息系統,它于2011年初開源,現在由著名的Apache基金會維護與開發。Kafka使用Scala實現,被用作LinkedIn的活動流和運營數據處理的管道,現在也被諸多互聯網企業廣泛地用作為數據流管道和消息系統。
首先,我們需要從官網上下載安裝介質。下載地址為:http://kafka.apache.org/downloads.html。本例中采用的版本為:Kafka-0.10.2.1
由于Kafka的設計中依賴了ZooKeeper,所以我們可以在bin和config目錄中除了看到Kafka相關的內容之外,還有ZooKeeper相關的內容。其中bin目錄存放了Kafka和ZooKeeper的命令行工具,bin根目錄下是適用于Linux/Unix的shell,而bin/windows下的則是適用于windows下的bat。我們可以根據實際的系統來設置環境變量,以方便后續的使用和操作。而在config目錄中,則是用來存放了關于Kafka與ZooKeeper的配置信息。
然后:啟動ZooKeeper,執行命令:zookeeper-server-start config/zookeeper.properties,該命令需要指定zookeeper的配置文件位置才能正確啟動,kafka的壓縮包中包含了其默認配置,開發與測試環境不需要修改。
最后:啟動Kafka,執行命令:kafka-server-start config/server.properties,該命令也需要指定Kafka配置文件的正確位置,如上命令中指向了解壓目錄包含的默認配置。若在測試時,使用外部集中環境的ZooKeeper的話,我們可以在該配置文件中通過zookeeper.connect參數來設置ZooKeeper的地址和端口,它默認會連接本地2181端口的ZooKeeper;如果需要設置多個ZooKeeper節點,可以為這個參數配置多個ZooKeeper地址,并用逗號分割。比如:zookeeper.connect=127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002。
創建Topic,執行命令:kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test,通過該命令,創建一個名為“test”的Topic,該Topic包含一個分區一個Replica。在創建完成后,可以使用kafka-topics --list --zookeeper localhost:2181命令來查看當前的Topic。
Kafka整合Spring Cloud Bus
上面使用Rabbit實現消息總線的案例中,我們已經通過引入spring-cloud-starter-bus-amqp模塊,完成了使用RabbitMQ來實現的消息總線。若我們要使用Kafka來實現消息總線時,只需要把spring-cloud-starter-bus-amqp替換成spring-cloud-starter-bus-kafka模塊,在pom.xml的dependenies節點中進行修改,具體如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
如果我們在啟動Kafka時均采用了默認配置,那么我們不需要再做任何其他配置就能在本地實現從RabbitMQ到Kafka的切換。
在config-server啟動時,我們可以在控制臺中看到如下輸出:
2017-06-01 14:28:31,739 INFO main c.p.c.Application:57 - Started Application in 0.9 seconds (JVM running for 17.254)
2017-06-01 14:28:31,833 INFO main o.s.c.s.b.k.p.KafkaTopicProvisioner:106 - Using kafka topic for outbound: springCloudBus
2017-06-01 14:28:32,044 INFO main o.a.z.ZooKeeper:100 - Client environment:zookeeper.version=3.4.8--1, built on 02/06/2016 03:18 GMT
2017-06-01 14:28:32,044 INFO main o.a.z.ZooKeeper:100 - Client environment:host.name=peer1
2017-06-01 14:28:32,045 INFO main o.a.z.ZooKeeper:100 - Client environment:java.version=1.8.0_111
2017-06-01 14:28:32,045 INFO main o.a.z.ZooKeeper:100 - Client environment:java.vendor=Oracle Corporation
2017-06-01 14:28:32,045 INFO main o.a.z.ZooKeeper:100 - Client environment:java.home=C:\Programs\Java\jdk1.8.0_111\jre
2017-06-01 14:28:32,045 INFO main o.a.z.ZooKeeper:100 - Client environment:java.class.path=D:\Workspace\cloud\spring-bus\config-server-eureka-kafka\target\classes;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-config-server\1.3.0.RELEASE\spring-cloud-config-server-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-config-client\1.3.0.RELEASE\spring-cloud-config-client-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\1.5.3.RELEASE\spring-boot-autoconfigure-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-commons\1.2.0.RELEASE\spring-cloud-commons-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-context\1.2.0.RELEASE\spring-cloud-context-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-web\4.3.8.RELEASE\spring-web-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-aop\4.3.8.RELEASE\spring-aop-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-beans\4.3.8.RELEASE\spring-beans-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-context\4.3.8.RELEASE\spring-context-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-core\4.3.8.RELEASE\spring-core-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\Users\wsun3\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.8.8\jackson-databind-2.8.8.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-actuator\1.5.3.RELEASE\spring-boot-starter-actuator-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter\1.5.3.RELEASE\spring-boot-starter-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-logging\1.5.3.RELEASE\spring-boot-starter-logging-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\ch\qos\logback\logback-classic\1.1.11\logback-classic-1.1.11.jar;C:\Users\wsun3\.m2\repository\ch\qos\logback\logback-core\1.1.11\logback-core-1.1.11.jar;C:\Users\wsun3\.m2\repository\org\slf4j\jcl-over-slf4j\1.7.25\jcl-over-slf4j-1.7.25.jar;C:\Users\wsun3\.m2\repository\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;C:\Users\wsun3\.m2\repository\org\slf4j\log4j-over-slf4j\1.7.25\log4j-over-slf4j-1.7.25.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-actuator\1.5.3.RELEASE\spring-boot-actuator-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-web\1.5.3.RELEASE\spring-boot-starter-web-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\1.5.3.RELEASE\spring-boot-starter-tomcat-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.14\tomcat-embed-core-8.5.14.jar;C:\Users\wsun3\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.14\tomcat-embed-el-8.5.14.jar;C:\Users\wsun3\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.14\tomcat-embed-websocket-8.5.14.jar;C:\Users\wsun3\.m2\repository\org\hibernate\hibernate-validator\5.3.5.Final\hibernate-validator-5.3.5.Final.jar;C:\Users\wsun3\.m2\repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\Users\wsun3\.m2\repository\org\jboss\logging\jboss-logging\3.3.1.Final\jboss-logging-3.3.1.Final.jar;C:\Users\wsun3\.m2\repository\com\fasterxml\classmate\1.3.3\classmate-1.3.3.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-webmvc\4.3.8.RELEASE\spring-webmvc-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-expression\4.3.8.RELEASE\spring-expression-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\security\spring-security-crypto\4.2.2.RELEASE\spring-security-crypto-4.2.2.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\security\spring-security-rsa\1.0.3.RELEASE\spring-security-rsa-1.0.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\bouncycastle\bcpkix-jdk15on\1.55\bcpkix-jdk15on-1.55.jar;C:\Users\wsun3\.m2\repository\org\bouncycastle\bcprov-jdk15on\1.55\bcprov-jdk15on-1.55.jar;C:\Users\wsun3\.m2\repository\org\eclipse\jgit\org.eclipse.jgit\4.6.0.201612231935-r\org.eclipse.jgit-4.6.0.201612231935-r.jar;C:\Users\wsun3\.m2\repository\com\jcraft\jsch\0.1.53\jsch-0.1.53.jar;C:\Users\wsun3\.m2\repository\com\googlecode\javaewah\JavaEWAH\1.1.6\JavaEWAH-1.1.6.jar;C:\Users\wsun3\.m2\repository\org\apache\httpcomponents\httpclient\4.5.3\httpclient-4.5.3.jar;C:\Users\wsun3\.m2\repository\org\apache\httpcomponents\httpcore\4.4.6\httpcore-4.4.6.jar;C:\Users\wsun3\.m2\repository\commons-codec\commons-codec\1.10\commons-codec-1.10.jar;C:\Users\wsun3\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\wsun3\.m2\repository\org\yaml\snakeyaml\1.17\snakeyaml-1.17.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-eureka\1.3.0.RELEASE\spring-cloud-starter-eureka-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter\1.2.0.RELEASE\spring-cloud-starter-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-netflix-core\1.3.0.RELEASE\spring-cloud-netflix-core-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot\1.5.3.RELEASE\spring-boot-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-netflix-eureka-client\1.3.0.RELEASE\spring-cloud-netflix-eureka-client-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\com\netflix\eureka\eureka-client\1.6.2\eureka-client-1.6.2.jar;C:\Users\wsun3\.m2\repository\org\codehaus\jettison\jettison\1.3.7\jettison-1.3.7.jar;C:\Users\wsun3\.m2\repository\stax\stax-api\1.0.1\stax-api-1.0.1.jar;C:\Users\wsun3\.m2\repository\com\netflix\netflix-commons\netflix-eventbus\0.3.0\netflix-eventbus-0.3.0.jar;C:\Users\wsun3\.m2\repository\com\netflix\netflix-commons\netflix-infix\0.3.0\netflix-infix-0.3.0.jar;C:\Users\wsun3\.m2\repository\commons-jxpath\commons-jxpath\1.3\commons-jxpath-1.3.jar;C:\Users\wsun3\.m2\repository\joda-time\joda-time\2.9.9\joda-time-2.9.9.jar;C:\Users\wsun3\.m2\repository\org\antlr\antlr-runtime\3.4\antlr-runtime-3.4.jar;C:\Users\wsun3\.m2\repository\org\antlr\stringtemplate\3.2.1\stringtemplate-3.2.1.jar;C:\Users\wsun3\.m2\repository\antlr\antlr\2.7.7\antlr-2.7.7.jar;C:\Users\wsun3\.m2\repository\com\google\code\gson\gson\2.8.0\gson-2.8.0.jar;C:\Users\wsun3\.m2\repository\org\apache\commons\commons-math\2.2\commons-math-2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\archaius\archaius-core\0.7.4\archaius-core-0.7.4.jar;C:\Users\wsun3\.m2\repository\javax\ws\rs\jsr311-api\1.1.1\jsr311-api-1.1.1.jar;C:\Users\wsun3\.m2\repository\com\netflix\servo\servo-core\0.10.1\servo-core-0.10.1.jar;C:\Users\wsun3\.m2\repository\com\netflix\servo\servo-internal\0.10.1\servo-internal-0.10.1.jar;C:\Users\wsun3\.m2\repository\com\sun\jersey\jersey-core\1.19.1\jersey-core-1.19.1.jar;C:\Users\wsun3\.m2\repository\com\sun\jersey\jersey-client\1.19.1\jersey-client-1.19.1.jar;C:\Users\wsun3\.m2\repository\com\sun\jersey\contribs\jersey-apache-client4\1.19.1\jersey-apache-client4-1.19.1.jar;C:\Users\wsun3\.m2\repository\com\google\inject\guice\4.1.0\guice-4.1.0.jar;C:\Users\wsun3\.m2\repository\javax\inject\javax.inject\1\javax.inject-1.jar;C:\Users\wsun3\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\wsun3\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.8.8\jackson-core-2.8.8.jar;C:\Users\wsun3\.m2\repository\com\netflix\eureka\eureka-core\1.6.2\eureka-core-1.6.2.jar;C:\Users\wsun3\.m2\repository\org\codehaus\woodstox\woodstox-core-asl\4.4.1\woodstox-core-asl-4.4.1.jar;C:\Users\wsun3\.m2\repository\javax\xml\stream\stax-api\1.0-2\stax-api-1.0-2.jar;C:\Users\wsun3\.m2\repository\org\codehaus\woodstox\stax2-api\3.1.4\stax2-api-3.1.4.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-archaius\1.3.0.RELEASE\spring-cloud-starter-archaius-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\commons-configuration\commons-configuration\1.8\commons-configuration-1.8.jar;C:\Users\wsun3\.m2\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;C:\Users\wsun3\.m2\repository\com\google\guava\guava\18.0\guava-18.0.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-ribbon\1.3.0.RELEASE\spring-cloud-starter-ribbon-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon\2.2.2\ribbon-2.2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-transport\2.2.2\ribbon-transport-2.2.2.jar;C:\Users\wsun3\.m2\repository\io\reactivex\rxnetty-contexts\0.4.9\rxnetty-contexts-0.4.9.jar;C:\Users\wsun3\.m2\repository\io\reactivex\rxnetty-servo\0.4.9\rxnetty-servo-0.4.9.jar;C:\Users\wsun3\.m2\repository\com\netflix\hystrix\hystrix-core\1.5.10\hystrix-core-1.5.10.jar;C:\Users\wsun3\.m2\repository\org\hdrhistogram\HdrHistogram\2.1.9\HdrHistogram-2.1.9.jar;C:\Users\wsun3\.m2\repository\io\reactivex\rxnetty\0.4.9\rxnetty-0.4.9.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-codec-http\4.0.27.Final\netty-codec-http-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-codec\4.0.27.Final\netty-codec-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-handler\4.0.27.Final\netty-handler-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-transport-native-epoll\4.0.27.Final\netty-transport-native-epoll-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-common\4.0.27.Final\netty-common-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-buffer\4.0.27.Final\netty-buffer-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-transport\4.0.27.Final\netty-transport-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-core\2.2.2\ribbon-core-2.2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-httpclient\2.2.2\ribbon-httpclient-2.2.2.jar;C:\Users\wsun3\.m2\repository\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\netflix-commons\netflix-commons-util\0.1.1\netflix-commons-util-0.1.1.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-loadbalancer\2.2.2\ribbon-loadbalancer-2.2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\netflix-commons\netflix-statistics\0.1.1\netflix-statistics-0.1.1.jar;C:\Users\wsun3\.m2\repository\io\reactivex\rxjava\1.1.10\rxjava-1.1.10.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-eureka\2.2.2\ribbon-eureka-2.2.2.jar;C:\Users\wsun3\.m2\repository\com\thoughtworks\xstream\xstream\1.4.9\xstream-1.4.9.jar;C:\Users\wsun3\.m2\repository\xmlpull\xmlpull\1.1.3.1\xmlpull-1.1.3.1.jar;C:\Users\wsun3\.m2\repository\xpp3\xpp3_min\1.1.4c\xpp3_min-1.1.4c.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-bus-kafka\1.3.0.RELEASE\spring-cloud-starter-bus-kafka-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-stream-kafka\1.2.0.RELEASE\spring-cloud-starter-stream-kafka-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-stream-binder-kafka\1.2.0.RELEASE\spring-cloud-stream-binder-kafka-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-stream-binder-kafka-core\1.2.0.RELEASE\spring-cloud-stream-binder-kafka-core-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-stream-codec\1.2.1.RELEASE\spring-cloud-stream-codec-1.2.1.RELEASE.jar;C:\Users\wsun3\.m2\repository\com\esotericsoftware\kryo-shaded\3.0.3\kryo-shaded-3.0.3.jar;C:\Users\wsun3\.m2\repository\com\esotericsoftware\minlog\1.3.0\minlog-1.3.0.jar;C:\Users\wsun3\.m2\repository\org\objenesis\objenesis\2.1\objenesis-2.1.jar;C:\Users\wsun3\.m2\repository\org\apache\kafka\kafka_2.11\0.10.1.1\kafka_2.11-0.10.1.1.jar;C:\Users\wsun3\.m2\repository\net\sf\jopt-simple\jopt-simple\4.9\jopt-simple-4.9.jar;C:\Users\wsun3\.m2\repository\com\yammer\metrics\metrics-core\2.2.0\metrics-core-2.2.0.jar;C:\Users\wsun3\.m2\repository\org\scala-lang\scala-library\2.11.8\scala-library-2.11.8.jar;C:\Users\wsun3\.m2\repository\com\101tec\zkclient\0.9\zkclient-0.9.jar;C:\Users\wsun3\.m2\repository\org\apache\zookeeper\zookeeper\3.4.8\zookeeper-3.4.8.jar;C:\Users\wsun3\.m2\repository\io\netty\netty\3.7.0.Final\netty-3.7.0.Final.jar;C:\Users\wsun3\.m2\repository\org\scala-lang\modules\scala-parser-combinators_2.11\1.0.4\scala-parser-combinators_2.11-1.0.4.jar;C:\Users\wsun3\.m2\repository\org\apache\kafka\kafka-clients\0.10.1.1\kafka-clients-0.10.1.1.jar;C:\Users\wsun3\.m2\repository\net\jpountz\lz4\lz4\1.3.0\lz4-1.3.0.jar;C:\Users\wsun3\.m2\repository\org\xerial\snappy\snappy-java\1.1.2.6\snappy-java-1.1.2.6.jar;C:\Users\wsun3\.m2\repository\org\springframework\kafka\spring-kafka\1.1.4.RELEASE\spring-kafka-1.1.4.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\integration\spring-integration-kafka\2.1.0.RELEASE\spring-integration-kafka-2.1.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-bus\1.3.0.RELEASE\spring-cloud-bus-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-stream\1.2.1.RELEASE\spring-cloud-stream-1.2.1.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-validation\1.5.3.RELEASE\spring-boot-starter-validation-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-messaging\4.3.8.RELEASE\spring-messaging-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\integration\spring-integration-jmx\4.3.9.RELEASE\spring-integration-jmx-4.3.9.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-tuple\1.0.0.RELEASE\spring-tuple-1.0.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\integration\spring-integration-tuple\1.0.0.RELEASE\spring-integration-tuple-1.0.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\retry\spring-retry\1.2.0.RELEASE\spring-retry-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\integration\spring-integration-core\4.3.9.RELEASE\spring-integration-core-4.3.9.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-tx\4.3.8.RELEASE\spring-tx-4.3.8.RELEASE.jar
2017-06-01 14:28:32,046 INFO main o.a.z.ZooKeeper:100 - Client environment:java.library.path=C:\Programs\Java\jdk1.8.0_111\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Programs/Java/jre/bin/server;C:/Programs/Java/jre/bin;C:/Programs/Java/jre/lib/amd64;C:\app\wsun3\product\11.2.0\dbhome_1\bin;%JAVA_HOME%\bin;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Enterprise Vault\EVClient\;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Windows\CCM;C:\Windows\CCM;C:\Program Files (x86)\Sennheiser\SoftphoneSDK\;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;C:\Programs\Git\cmd;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Programs\JavaStudio\kafka_2.10-0.10.2.1\bin\windows;C:\Programs\erl8.3\bin;C:\Python27;C:\Program Files (x86)\CVSNT\;C:\Programs\JavaStudio\sts-bundle\sts-3.8.4.RELEASE;;.
2017-06-01 14:28:32,046 INFO main o.a.z.ZooKeeper:100 - Client environment:java.io.tmpdir=C:\Users\wsun3\AppData\Local\Temp\
2017-06-01 14:28:32,046 INFO main o.a.z.ZooKeeper:100 - Client environment:java.compiler=<NA>
2017-06-01 14:28:32,046 INFO main o.a.z.ZooKeeper:100 - Client environment:os.name=Windows 7
2017-06-01 14:28:32,046 INFO main o.a.z.ZooKeeper:100 - Client environment:os.arch=amd64
2017-06-01 14:28:32,047 INFO main o.a.z.ZooKeeper:100 - Client environment:os.version=6.1
2017-06-01 14:28:32,047 INFO main o.a.z.ZooKeeper:100 - Client environment:user.name=wsun3
2017-06-01 14:28:32,047 INFO main o.a.z.ZooKeeper:100 - Client environment:user.home=C:\Users\wsun3
2017-06-01 14:28:32,047 INFO main o.a.z.ZooKeeper:100 - Client environment:user.dir=D:\Workspace\cloud\spring-bus\config-server-eureka-kafka
2017-06-01 14:28:32,048 INFO main o.a.z.ZooKeeper:438 - Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=org.I0Itec.zkclient.ZkClient@45f241df
2017-06-01 14:28:32,091 INFO main-SendThread(peer1:2181) o.a.z.ClientCnxn:1032 - Opening socket connection to server peer1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
2017-06-01 14:28:32,095 INFO main-SendThread(peer1:2181) o.a.z.ClientCnxn:876 - Socket connection established to peer1/127.0.0.1:2181, initiating session
2017-06-01 14:28:32,200 INFO main-SendThread(peer1:2181) o.a.z.ClientCnxn:1299 - Session establishment complete on server peer1/127.0.0.1:2181, sessionid = 0x15c6231471c0006, negotiated timeout = 10000
2017-06-01 14:28:33,504 INFO main o.a.z.ZooKeeper:684 - Session: 0x15c6231471c0006 closed
從控制臺的輸出內容,我們可以看到config-server連接到了Kafka中,并使用了名為springCloudBus的Topic。
此時,我們可以使用kafka-topics --list --zookeeper localhost:2181命令來查看當前Kafka中的Topic,若已成功啟動了config-server并配置正確,我們就可以在Kafka中看到已經多了一個名為springCloudBus的Topic。
我們再啟動配置了spring-cloud-starter-bus-kafka模塊的config-client,可以看到控制臺中輸出如下內容:
2017-06-01 14:34:06,716 INFO main o.s.c.s.b.k.p.KafkaTopicProvisioner:106 - Using kafka topic for outbound: springCloudBus
2017-06-01 14:34:08,044 INFO main o.a.z.ZooKeeper:100 - Client environment:zookeeper.version=3.4.8--1, built on 02/06/2016 03:18 GMT
2017-06-01 14:34:08,044 INFO main o.a.z.ZooKeeper:100 - Client environment:host.name=peer1
2017-06-01 14:34:08,044 INFO main o.a.z.ZooKeeper:100 - Client environment:java.version=1.8.0_111
2017-06-01 14:34:08,045 INFO main o.a.z.ZooKeeper:100 - Client environment:java.vendor=Oracle Corporation
2017-06-01 14:34:08,045 INFO main o.a.z.ZooKeeper:100 - Client environment:java.home=C:\Programs\Java\jdk1.8.0_111\jre
2017-06-01 14:34:08,045 INFO main o.a.z.ZooKeeper:100 - Client environment:java.class.path=D:\Workspace\cloud\spring-bus\config-client-eureka-kafka\target\classes;C:\Users\wsun3\.m2\repository\org\springframework\retry\spring-retry\1.2.0.RELEASE\spring-retry-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-core\4.3.8.RELEASE\spring-core-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-web\1.5.3.RELEASE\spring-boot-starter-web-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter\1.5.3.RELEASE\spring-boot-starter-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot\1.5.3.RELEASE\spring-boot-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\1.5.3.RELEASE\spring-boot-autoconfigure-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-logging\1.5.3.RELEASE\spring-boot-starter-logging-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\ch\qos\logback\logback-classic\1.1.11\logback-classic-1.1.11.jar;C:\Users\wsun3\.m2\repository\ch\qos\logback\logback-core\1.1.11\logback-core-1.1.11.jar;C:\Users\wsun3\.m2\repository\org\slf4j\jcl-over-slf4j\1.7.25\jcl-over-slf4j-1.7.25.jar;C:\Users\wsun3\.m2\repository\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;C:\Users\wsun3\.m2\repository\org\slf4j\log4j-over-slf4j\1.7.25\log4j-over-slf4j-1.7.25.jar;C:\Users\wsun3\.m2\repository\org\yaml\snakeyaml\1.17\snakeyaml-1.17.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\1.5.3.RELEASE\spring-boot-starter-tomcat-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.14\tomcat-embed-core-8.5.14.jar;C:\Users\wsun3\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.14\tomcat-embed-el-8.5.14.jar;C:\Users\wsun3\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.14\tomcat-embed-websocket-8.5.14.jar;C:\Users\wsun3\.m2\repository\org\hibernate\hibernate-validator\5.3.5.Final\hibernate-validator-5.3.5.Final.jar;C:\Users\wsun3\.m2\repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\Users\wsun3\.m2\repository\org\jboss\logging\jboss-logging\3.3.1.Final\jboss-logging-3.3.1.Final.jar;C:\Users\wsun3\.m2\repository\com\fasterxml\classmate\1.3.3\classmate-1.3.3.jar;C:\Users\wsun3\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.8.8\jackson-databind-2.8.8.jar;C:\Users\wsun3\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\Users\wsun3\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.8.8\jackson-core-2.8.8.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-web\4.3.8.RELEASE\spring-web-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-beans\4.3.8.RELEASE\spring-beans-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-context\4.3.8.RELEASE\spring-context-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-webmvc\4.3.8.RELEASE\spring-webmvc-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-expression\4.3.8.RELEASE\spring-expression-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-aop\1.5.3.RELEASE\spring-boot-starter-aop-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-aop\4.3.8.RELEASE\spring-aop-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\aspectj\aspectjweaver\1.8.10\aspectjweaver-1.8.10.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-actuator\1.5.3.RELEASE\spring-boot-starter-actuator-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-actuator\1.5.3.RELEASE\spring-boot-actuator-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-config\1.3.0.RELEASE\spring-cloud-starter-config-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter\1.2.0.RELEASE\spring-cloud-starter-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-context\1.2.0.RELEASE\spring-cloud-context-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\security\spring-security-crypto\4.2.2.RELEASE\spring-security-crypto-4.2.2.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-commons\1.2.0.RELEASE\spring-cloud-commons-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\security\spring-security-rsa\1.0.3.RELEASE\spring-security-rsa-1.0.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\bouncycastle\bcpkix-jdk15on\1.55\bcpkix-jdk15on-1.55.jar;C:\Users\wsun3\.m2\repository\org\bouncycastle\bcprov-jdk15on\1.55\bcprov-jdk15on-1.55.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-config-client\1.3.0.RELEASE\spring-cloud-config-client-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-eureka\1.3.0.RELEASE\spring-cloud-starter-eureka-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-netflix-core\1.3.0.RELEASE\spring-cloud-netflix-core-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-netflix-eureka-client\1.3.0.RELEASE\spring-cloud-netflix-eureka-client-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\com\netflix\eureka\eureka-client\1.6.2\eureka-client-1.6.2.jar;C:\Users\wsun3\.m2\repository\org\codehaus\jettison\jettison\1.3.7\jettison-1.3.7.jar;C:\Users\wsun3\.m2\repository\stax\stax-api\1.0.1\stax-api-1.0.1.jar;C:\Users\wsun3\.m2\repository\com\netflix\netflix-commons\netflix-eventbus\0.3.0\netflix-eventbus-0.3.0.jar;C:\Users\wsun3\.m2\repository\com\netflix\netflix-commons\netflix-infix\0.3.0\netflix-infix-0.3.0.jar;C:\Users\wsun3\.m2\repository\commons-jxpath\commons-jxpath\1.3\commons-jxpath-1.3.jar;C:\Users\wsun3\.m2\repository\joda-time\joda-time\2.9.9\joda-time-2.9.9.jar;C:\Users\wsun3\.m2\repository\org\antlr\antlr-runtime\3.4\antlr-runtime-3.4.jar;C:\Users\wsun3\.m2\repository\org\antlr\stringtemplate\3.2.1\stringtemplate-3.2.1.jar;C:\Users\wsun3\.m2\repository\antlr\antlr\2.7.7\antlr-2.7.7.jar;C:\Users\wsun3\.m2\repository\com\google\code\gson\gson\2.8.0\gson-2.8.0.jar;C:\Users\wsun3\.m2\repository\org\apache\commons\commons-math\2.2\commons-math-2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\archaius\archaius-core\0.7.4\archaius-core-0.7.4.jar;C:\Users\wsun3\.m2\repository\javax\ws\rs\jsr311-api\1.1.1\jsr311-api-1.1.1.jar;C:\Users\wsun3\.m2\repository\com\netflix\servo\servo-core\0.10.1\servo-core-0.10.1.jar;C:\Users\wsun3\.m2\repository\com\netflix\servo\servo-internal\0.10.1\servo-internal-0.10.1.jar;C:\Users\wsun3\.m2\repository\com\sun\jersey\jersey-core\1.19.1\jersey-core-1.19.1.jar;C:\Users\wsun3\.m2\repository\com\sun\jersey\jersey-client\1.19.1\jersey-client-1.19.1.jar;C:\Users\wsun3\.m2\repository\com\sun\jersey\contribs\jersey-apache-client4\1.19.1\jersey-apache-client4-1.19.1.jar;C:\Users\wsun3\.m2\repository\org\apache\httpcomponents\httpclient\4.5.3\httpclient-4.5.3.jar;C:\Users\wsun3\.m2\repository\org\apache\httpcomponents\httpcore\4.4.6\httpcore-4.4.6.jar;C:\Users\wsun3\.m2\repository\commons-codec\commons-codec\1.10\commons-codec-1.10.jar;C:\Users\wsun3\.m2\repository\com\google\inject\guice\4.1.0\guice-4.1.0.jar;C:\Users\wsun3\.m2\repository\javax\inject\javax.inject\1\javax.inject-1.jar;C:\Users\wsun3\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\wsun3\.m2\repository\com\netflix\eureka\eureka-core\1.6.2\eureka-core-1.6.2.jar;C:\Users\wsun3\.m2\repository\org\codehaus\woodstox\woodstox-core-asl\4.4.1\woodstox-core-asl-4.4.1.jar;C:\Users\wsun3\.m2\repository\javax\xml\stream\stax-api\1.0-2\stax-api-1.0-2.jar;C:\Users\wsun3\.m2\repository\org\codehaus\woodstox\stax2-api\3.1.4\stax2-api-3.1.4.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-archaius\1.3.0.RELEASE\spring-cloud-starter-archaius-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\commons-configuration\commons-configuration\1.8\commons-configuration-1.8.jar;C:\Users\wsun3\.m2\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;C:\Users\wsun3\.m2\repository\com\google\guava\guava\18.0\guava-18.0.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-ribbon\1.3.0.RELEASE\spring-cloud-starter-ribbon-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon\2.2.2\ribbon-2.2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-transport\2.2.2\ribbon-transport-2.2.2.jar;C:\Users\wsun3\.m2\repository\io\reactivex\rxnetty-contexts\0.4.9\rxnetty-contexts-0.4.9.jar;C:\Users\wsun3\.m2\repository\io\reactivex\rxnetty-servo\0.4.9\rxnetty-servo-0.4.9.jar;C:\Users\wsun3\.m2\repository\com\netflix\hystrix\hystrix-core\1.5.10\hystrix-core-1.5.10.jar;C:\Users\wsun3\.m2\repository\org\hdrhistogram\HdrHistogram\2.1.9\HdrHistogram-2.1.9.jar;C:\Users\wsun3\.m2\repository\io\reactivex\rxnetty\0.4.9\rxnetty-0.4.9.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-codec-http\4.0.27.Final\netty-codec-http-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-codec\4.0.27.Final\netty-codec-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-handler\4.0.27.Final\netty-handler-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-transport-native-epoll\4.0.27.Final\netty-transport-native-epoll-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-common\4.0.27.Final\netty-common-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-buffer\4.0.27.Final\netty-buffer-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\io\netty\netty-transport\4.0.27.Final\netty-transport-4.0.27.Final.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-core\2.2.2\ribbon-core-2.2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-httpclient\2.2.2\ribbon-httpclient-2.2.2.jar;C:\Users\wsun3\.m2\repository\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\netflix-commons\netflix-commons-util\0.1.1\netflix-commons-util-0.1.1.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-loadbalancer\2.2.2\ribbon-loadbalancer-2.2.2.jar;C:\Users\wsun3\.m2\repository\com\netflix\netflix-commons\netflix-statistics\0.1.1\netflix-statistics-0.1.1.jar;C:\Users\wsun3\.m2\repository\io\reactivex\rxjava\1.1.10\rxjava-1.1.10.jar;C:\Users\wsun3\.m2\repository\com\netflix\ribbon\ribbon-eureka\2.2.2\ribbon-eureka-2.2.2.jar;C:\Users\wsun3\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\wsun3\.m2\repository\com\thoughtworks\xstream\xstream\1.4.9\xstream-1.4.9.jar;C:\Users\wsun3\.m2\repository\xmlpull\xmlpull\1.1.3.1\xmlpull-1.1.3.1.jar;C:\Users\wsun3\.m2\repository\xpp3\xpp3_min\1.1.4c\xpp3_min-1.1.4c.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-bus-kafka\1.3.0.RELEASE\spring-cloud-starter-bus-kafka-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-starter-stream-kafka\1.2.0.RELEASE\spring-cloud-starter-stream-kafka-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-stream-binder-kafka\1.2.0.RELEASE\spring-cloud-stream-binder-kafka-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-stream-binder-kafka-core\1.2.0.RELEASE\spring-cloud-stream-binder-kafka-core-1.2.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-stream-codec\1.2.1.RELEASE\spring-cloud-stream-codec-1.2.1.RELEASE.jar;C:\Users\wsun3\.m2\repository\com\esotericsoftware\kryo-shaded\3.0.3\kryo-shaded-3.0.3.jar;C:\Users\wsun3\.m2\repository\com\esotericsoftware\minlog\1.3.0\minlog-1.3.0.jar;C:\Users\wsun3\.m2\repository\org\objenesis\objenesis\2.1\objenesis-2.1.jar;C:\Users\wsun3\.m2\repository\org\apache\kafka\kafka_2.11\0.10.1.1\kafka_2.11-0.10.1.1.jar;C:\Users\wsun3\.m2\repository\net\sf\jopt-simple\jopt-simple\4.9\jopt-simple-4.9.jar;C:\Users\wsun3\.m2\repository\com\yammer\metrics\metrics-core\2.2.0\metrics-core-2.2.0.jar;C:\Users\wsun3\.m2\repository\org\scala-lang\scala-library\2.11.8\scala-library-2.11.8.jar;C:\Users\wsun3\.m2\repository\com\101tec\zkclient\0.9\zkclient-0.9.jar;C:\Users\wsun3\.m2\repository\org\apache\zookeeper\zookeeper\3.4.8\zookeeper-3.4.8.jar;C:\Users\wsun3\.m2\repository\io\netty\netty\3.7.0.Final\netty-3.7.0.Final.jar;C:\Users\wsun3\.m2\repository\org\scala-lang\modules\scala-parser-combinators_2.11\1.0.4\scala-parser-combinators_2.11-1.0.4.jar;C:\Users\wsun3\.m2\repository\org\apache\kafka\kafka-clients\0.10.1.1\kafka-clients-0.10.1.1.jar;C:\Users\wsun3\.m2\repository\net\jpountz\lz4\lz4\1.3.0\lz4-1.3.0.jar;C:\Users\wsun3\.m2\repository\org\xerial\snappy\snappy-java\1.1.2.6\snappy-java-1.1.2.6.jar;C:\Users\wsun3\.m2\repository\org\springframework\kafka\spring-kafka\1.1.4.RELEASE\spring-kafka-1.1.4.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\integration\spring-integration-kafka\2.1.0.RELEASE\spring-integration-kafka-2.1.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-bus\1.3.0.RELEASE\spring-cloud-bus-1.3.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\cloud\spring-cloud-stream\1.2.1.RELEASE\spring-cloud-stream-1.2.1.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\boot\spring-boot-starter-validation\1.5.3.RELEASE\spring-boot-starter-validation-1.5.3.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-messaging\4.3.8.RELEASE\spring-messaging-4.3.8.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\integration\spring-integration-jmx\4.3.9.RELEASE\spring-integration-jmx-4.3.9.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-tuple\1.0.0.RELEASE\spring-tuple-1.0.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\integration\spring-integration-tuple\1.0.0.RELEASE\spring-integration-tuple-1.0.0.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\integration\spring-integration-core\4.3.9.RELEASE\spring-integration-core-4.3.9.RELEASE.jar;C:\Users\wsun3\.m2\repository\org\springframework\spring-tx\4.3.8.RELEASE\spring-tx-4.3.8.RELEASE.jar
2017-06-01 14:34:08,100 INFO main o.a.z.ZooKeeper:100 - Client environment:java.library.path=C:\Programs\Java\jdk1.8.0_111\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Programs/Java/jre/bin/server;C:/Programs/Java/jre/bin;C:/Programs/Java/jre/lib/amd64;C:\app\wsun3\product\11.2.0\dbhome_1\bin;%JAVA_HOME%\bin;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Enterprise Vault\EVClient\;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Windows\CCM;C:\Windows\CCM;C:\Program Files (x86)\Sennheiser\SoftphoneSDK\;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;C:\Programs\Git\cmd;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Programs\JavaStudio\kafka_2.10-0.10.2.1\bin\windows;C:\Programs\erl8.3\bin;C:\Python27;C:\Program Files (x86)\CVSNT\;C:\Programs\JavaStudio\sts-bundle\sts-3.8.4.RELEASE;;.
2017-06-01 14:34:08,100 INFO main o.a.z.ZooKeeper:100 - Client environment:java.io.tmpdir=C:\Users\wsun3\AppData\Local\Temp\
2017-06-01 14:34:08,101 INFO main o.a.z.ZooKeeper:100 - Client environment:java.compiler=<NA>
2017-06-01 14:34:08,102 INFO main o.a.z.ZooKeeper:100 - Client environment:os.name=Windows 7
2017-06-01 14:34:08,102 INFO main o.a.z.ZooKeeper:100 - Client environment:os.arch=amd64
2017-06-01 14:34:08,102 INFO main o.a.z.ZooKeeper:100 - Client environment:os.version=6.1
2017-06-01 14:34:08,103 INFO main o.a.z.ZooKeeper:100 - Client environment:user.name=wsun3
2017-06-01 14:34:08,104 INFO main o.a.z.ZooKeeper:100 - Client environment:user.home=C:\Users\wsun3
2017-06-01 14:34:08,104 INFO main o.a.z.ZooKeeper:100 - Client environment:user.dir=D:\Workspace\cloud\spring-bus\config-client-eureka-kafka
2017-06-01 14:34:08,106 INFO main o.a.z.ZooKeeper:438 - Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=org.I0Itec.zkclient.ZkClient@3f267e1b
2017-06-01 14:34:08,161 INFO main-SendThread(peer1:2181) o.a.z.ClientCnxn:1032 - Opening socket connection to server peer1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
2017-06-01 14:34:08,164 INFO main-SendThread(peer1:2181) o.a.z.ClientCnxn:876 - Socket connection established to peer1/127.0.0.1:2181, initiating session
2017-06-01 14:34:08,208 INFO main-SendThread(peer1:2181) o.a.z.ClientCnxn:1299 - Session establishment complete on server peer1/127.0.0.1:2181, sessionid = 0x15c6231471c000a, negotiated timeout = 10000
2017-06-01 14:34:09,074 INFO main o.a.z.ZooKeeper:684 - Session: 0x15c6231471c000a closed
可以看到,config-client啟動時輸出了類似的內容,他們都訂閱了名為springCloudBus的Topic。
在啟動了config-server和config-client之后,為了更明顯地觀察消息總線刷新配置的效果,我們可以在本地啟動多個不同端口的config-client。此時,我們的config-server以及多個config-client都已經連接到了由Kafka實現的消息總線上。我們可以先訪問各個config-client上的/from請求,查看他獲取到的配置內容。然后,修改Git中對應的參數內容,再訪問各個config-client上的/from請求,可以看到配置內容并沒有改變。最后,我們向config-server發送POST請求:/bus/refresh,此時我們再去訪問各個config-client上的/from請求,就能獲得到最新的配置信息,各客戶端上的配置都已經加載為最新的Git配置內容。
從config-client的控制臺中,我們可以看到如下內容:
2017-06-01 14:43:19,196 INFO -L-1 o.s.c.b.e.RefreshListener:44 - Received remote refresh request. Keys refreshed [from]
2017-06-01 14:43:20,604 INFO -L-1 o.s.c.b.e.RefreshListener:44 - Received remote refresh request. Keys refreshed [from]
RefreshListener監聽類記錄了收到遠程刷新請求,并刷新了from屬性的日志。
完整示例:spring-bus