<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] 上一篇文章,留了一個懸念,`Config Client` 實現配置的實時更新,我們可以使用 `/refresh` 接口觸發,如果所有客戶端的配置的更改,都需要手動觸發客戶端 `/refresh` ,當服務越來越多的時候,那豈不是維護成本很高,顯然不太合適,而使用`Spring Cloud Bus` 消息總線實現方案,可以優雅的解決以上問題,那就是通過消息代理中間件`RabbitMQ` 加 `Git`的`Webhooks`來觸發配置的更新,那具體是怎么實現的,我會通過圖文形式介紹。 # Spring Cloud Bus `Spring Cloud Bus` 將分布式系統的節點通過輕量級消息代理連接起來。用于在集群中傳播狀態更改(例如配置更改事件)或其他管理指令。`Spring Cloud Bus` 的一個核心思想是通過分布式的啟動器對 `Spring Boot` 應用進行擴展,也可以用來建立一個或多個應用之間的通信頻道。目前唯一實現的方式是用 `AMQP` 消息代理作為通道,但是相同的基本功能集(還有一些取決于傳輸)在其他傳輸的路線圖上 ## 消息總線 消息總線是一種通信工具,可以在機器之間互相傳輸消息、文件等。消息總線扮演著一種消息路由的角色,擁有一套完備的路由機制來決定消息傳輸方向。發送段只需要向消息總線發出消息而不用管消息被如何轉發。 `Spring cloud bus` 通過輕量消息代理連接各個分布的節點。管理和傳播所有分布式項目中的消息,本質是利用了MQ的廣播機制在分布式的系統中傳播消息,目前常用的有`Kafka`和`RabbitMQ` 。 下面是一個配置中心刷新配置的例子 ![架構圖][11] [圖片來源于網絡如有侵權請私信刪除] - 1、提交代碼觸發`post`請求給`bus/refresh` - 2、`server`端接收到請求并發送給`Spring Cloud Bus` - 3、`Spring Cloud bus`接到消息并通知給其它客戶端 - 4、其它客戶端接收到通知,請求`Server`端獲取最新配置 - 5、全部客戶端均獲取到最新的配置 ## 消息代理 消息代理(`Message Broker`)是一種消息驗證、傳輸、路由的架構模式。消息代理是一個中間件產品,它的核心是一個消息的路由程序,用來實現接收和分發消息,并根據設定好的消息處理流來轉發給正確的應用。它包括獨立的通信和消息傳遞協議,能夠實現組織內部和組織間的網絡通信。設計代理的目的就是為了能夠從應用程序中傳入消息,并執行一些特別的操作。 和組織間的網絡通信。設計代理的目的就是為了能夠從應用程序中傳入消息,并執行一些特別的操作。 現有的消息代理開源產品: - `ActiveMQ` - `Kafka` - `RabbitMQ` - `RocketMQ` 目前`Spring Cloud Bus` 支持 `RabbitMQ` 和 `Kafka,spring-cloud-starter-bus-amqp` 、`spring-cloud-starter-bus-kafka` ## RabbitMQ簡介 RabbitMQ是一個開源的AMQP實現,服務器端用Erlang語言編寫,支持多種客戶端,如:`Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP`等,支持`AJAX`。用于在分布式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。 `AMQP`,即`Advanced message Queuing Protocol`,高級消息隊列協議,是應用層協議的一個開放標準,為面向消息的中間件設計。消息中間件主要用于組件之間的解耦,消息的發送者無需知道消息使用者的存在,反之亦然。 `AMQP`的主要特征是面向消息、隊列、路由(包括點對點和發布/訂閱)、可靠性、安全。 Github:[https://github.com/rabbitmq](https://github.com/rabbitmq) 官網地址:[http://www.rabbitmq.com](http://www.rabbitmq.com) ## 安裝RabbitMQ **安裝RabbitMQ 可以參考之前的文章** CentOs7.3 搭建 RabbitMQ 3.6 單機服務: [https://segmentfault.com/a/1190000010693696](https://segmentfault.com/a/1190000010693696) CentOs7.3 搭建 RabbitMQ 3.6 Cluster 集群服務: [https://segmentfault.com/a/1190000010702020](https://segmentfault.com/a/1190000010702020) Spring Boot 中使用 RabbitMQ: [https://segmentfault.com/a/1190000011577243](https://segmentfault.com/a/1190000011577243) # 準備工作 以下項目修改不做過多解釋,部分代碼不再展示,請閱讀上篇文章,**Spring Cloud(十)高可用的分布式配置中心 Spring Cloud Config 中使用 Refresh:**[http://www.ymq.io/2017/12/23/spring-cloud-config-eureka-refresh/](http://www.ymq.io/2017/12/23/spring-cloud-config-eureka-refresh/) 把上一篇,示例代碼下載,才可以進行一下的操作,下載地址在文章末尾 `spring-cloud-eureka-service` `spring-cloud-config-server` `spring-cloud-eureka-provider-1` `spring-cloud-eureka-provider-2` `spring-cloud-eureka-provider-3` `spring-cloud-feign-consumer` # Config Server 在項目`spring-cloud-config-server` 進行以下操作 ## 添加依賴 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> ``` ## 添加配置 在 `application.properties` 添加以下配置.關閉安全認證 **RabbitMQ** 的 `ymq`用戶是手動創建的,具體閱讀上面 安裝`RabbitMQ` 部分 ```sh #關閉刷新安全認證 management.security.enabled=false spring.rabbitmq.host=192.168.252.126 spring.rabbitmq.port=5672 spring.rabbitmq.username=ymq spring.rabbitmq.password=123456 ``` # Config Client 修改第上一篇文章項目 `spring-cloud-eureka-provider-1` `spring-cloud-eureka-provider-2` `spring-cloud-eureka-provider-3` ## 添加依賴 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> ``` ## 添加配置 在 `application.properties` 添加以下配置.關閉安全認證 ```sh spring.rabbitmq.host=192.168.252.126 spring.rabbitmq.port=5672 spring.rabbitmq.username=ymq spring.rabbitmq.password=123456 ``` # 測試服務 ## 啟動RabbitMQ **啟動MQ服務** ```sh $ service rabbitmq-server start Redirecting to /bin/systemctl start rabbitmq-server.service ``` **查看MQ狀態** ``` $ service rabbitmq-server status ``` ```sh [root@node6 rabbitmq]# service rabbitmq-server status Redirecting to /bin/systemctl status rabbitmq-server.service ● rabbitmq-server.service - RabbitMQ broker Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled; vendor preset: disabled) Active: active (running) since Fri 2017-12-29 17:44:10 CST; 9min ago Process: 2814 ExecStop=/usr/sbin/rabbitmqctl stop (code=exited, status=0/SUCCESS) Main PID: 2948 (beam) Status: "Initialized" CGroup: /system.slice/rabbitmq-server.service ├─2948 /usr/lib64/erlang/erts-8.0.3/bin/beam -W w -A 64 -P 1048576 -t 5000000 -stbt db -zdbbl 32000 -K true -- -root /usr/lib64/erlang -progname erl -- -home /var/lib/rabbitmq -- -pa /usr... ├─3131 /usr/lib64/erlang/erts-8.0.3/bin/epmd -daemon ├─3233 erl_child_setup 1024 ├─3240 inet_gethost 4 └─3241 inet_gethost 4 Dec 29 17:44:08 node6 rabbitmq-server[2948]: RabbitMQ 3.6.10. Copyright (C) 2007-2017 Pivotal Software, Inc. Dec 29 17:44:08 node6 rabbitmq-server[2948]: ## ## Licensed under the MPL. See http://www.rabbitmq.com/ Dec 29 17:44:08 node6 rabbitmq-server[2948]: ## ## Dec 29 17:44:08 node6 rabbitmq-server[2948]: ########## Logs: /var/log/rabbitmq/rabbit@node6.log Dec 29 17:44:08 node6 rabbitmq-server[2948]: ###### ## /var/log/rabbitmq/rabbit@node6-sasl.log Dec 29 17:44:08 node6 rabbitmq-server[2948]: ########## Dec 29 17:44:08 node6 rabbitmq-server[2948]: Starting broker... Dec 29 17:44:10 node6 rabbitmq-server[2948]: systemd unit for activation check: "rabbitmq-server.service" Dec 29 17:44:10 node6 systemd[1]: Started RabbitMQ broker. Dec 29 17:44:10 node6 rabbitmq-server[2948]: completed with 6 plugins. [root@node6 rabbitmq]# ``` ## 啟動項目 按照順序依次啟動項目 `spring-cloud-eureka-service` `spring-cloud-config-server` `spring-cloud-eureka-provider-1` `spring-cloud-eureka-provider-2` `spring-cloud-eureka-provider-3` `spring-cloud-feign-consumer` 啟動該工程后,訪問服務注冊中心,查看服務是否都已注冊成功:[http://127.0.0.1:8761/](http://127.0.0.1:8761/) ![查看服務注冊情況][22] ## Exchanges ![檢查 springCloudBus][33] **任何發送到`Fanout Exchange` 的消息都會被轉發到與該`Exchange`綁定(`Binding`)的所有`springCloudBus` 隊列`Queue`上。** ## 檢查Queues 瀏覽器打開 :[http://192.168.252.128:15672/](http://192.168.252.128:15672/) ![檢查 springCloudBus][44] ## 修改配置 修改`Git`倉庫配置,在 `content=hello dev` 后面加上 `Spring Cloud Bus Test` ![修改git 倉庫配置][55] ## 查看 Config Server 通過 `Postman` 發送 `GET` 請求到:[http://localhost:8888/springCloudConfig/dev/master](http://localhost:8888/springCloudConfig/dev/master) 查看 `Config Server` 是否是最新的值 ![Config Server 已經是新的值][66] ## 查看 Config Client 命令窗口,通過`curl http://127.0.0.1:9000/hello` 訪問服務,或者在瀏覽器訪問`http://127.0.0.1:9000/hello` F5 刷新 **發現沒有得到最新的值** **因為我們沒有主動觸發`Config Server bus/refresh`接口** ![訪問服務][77] ## 刷新配置 通過 `Postman` 發送 `POST`請求到:[http://localhost:8888/bus/refresh](http://localhost:8888/bus/refresh) ,我們可以看到以下內容: **注意是 `PSOT` 請求** ![訪問:http://localhost:8888/bus/refresh][88] **三個`Config Client` 客戶端控制臺,分別會打印以下內容**意思就是,收到遠程更新請求,`config.client,KEYS` 刷新, `key` 是 `content` ```sh 2017-12-29 18:38:49.023 INFO 28944 --- [jeTgrKRGzgj9g-1] o.s.cloud.bus.event.RefreshListener : Received remote refresh request. Keys refreshed [config.client.version, content] 2017-12-29 18:38:49.025 INFO 28944 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-PROVIDER/localhost:eureka-provider:8081: registering service... 2017-12-29 18:38:49.035 INFO 28944 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-PROVIDER/localhost:eureka-provider:8081 - registration status: 204 2017-12-29 18:38:49.067 INFO 28944 --- [jeTgrKRGzgj9g-1] o.s.a.r.c.CachingConnectionFactory : Created new connection: SpringAMQP#31e87320:0/SimpleConnection@39151d4e [delegate=amqp://ymq@192.168.252.126:5672/, localPort= 64885] ``` ## 再次查看 Config Client 訪問:[http://localhost:8081/](http://localhost:8081/) ,[http://localhost:8082/](http://localhost:8082/) ,[http://localhost:8083/](http://localhost:8083/) 已經刷新了配置 ![訪問服務][99] # 擴展閱讀 ## Git webhooks 現在雖然可以不用重啟服務就更新配置了,但還是需要我們手動操作,這樣還是不可取的。所以,這里就要用到Git的webhooks來達到自動更新配置。 打開git上配置倉庫的地址,添加`webhooks`,上面`Payload URL`我寫的域名,當然我沒有部署,上面的`Payload URL`就填寫我們的配置中心觸發刷新的地址,當然這里不能寫`localhost`啦,要外網訪問地址才行。 還有這里面有個Secret的秘鑰驗證,如果這里填寫的話,在配置文件上要寫上`encrypt.key`與之對應。 ![添加webhooks][10] [10]: http://www.ymq.io/images/2017/SpringCloud/config-bus/10.png [11]: http://www.ymq.io/images/2017/SpringCloud/config-bus/11.png [22]: http://www.ymq.io/images/2017/SpringCloud/config-bus/22.png [33]: http://www.ymq.io/images/2017/SpringCloud/config-bus/33.png [44]: http://www.ymq.io/images/2017/SpringCloud/config-bus/44.png [55]: http://www.ymq.io/images/2017/SpringCloud/config-bus/55.png [66]: http://www.ymq.io/images/2017/SpringCloud/config-bus/66.png [77]: http://www.ymq.io/images/2017/SpringCloud/config-bus/77.png [88]: http://www.ymq.io/images/2017/SpringCloud/config-bus/88.png [99]: http://www.ymq.io/images/2017/SpringCloud/config-bus/99.png ## 局部刷新 某些場景下(例如灰度發布),我們可能只想刷新部分微服務的配置,此時可通過`/bus/refresh`端點的`destination`參數來定位要刷新的應用程序。 例如:`/bus/refresh?destination=customers:8000`,這樣消息總線上的微服務實例就會根據`destination`參數的值來判斷是否需要要刷新。其中,`customers:8000`指的是各個微服務的`ApplicationContext ID`。 `destination`參數也可以用來定位特定的微服務。例如:`/bus/refresh?destination=customers:**`,這樣就可以觸發`customers`微服務所有實例的配置刷新。 ## 跟蹤總線事件 一些場景下,我們可能希望知道`Spring Cloud Bus`事件傳播的細節。此時,我們可以跟蹤總線事件(`RemoteApplicationEvent`的子類都是總線事件)。 跟蹤總線事件非常簡單,只需設置`spring.cloud.bus.trace.enabled=true`,這樣在`/bus/refresh`端點被請求后,訪問`/trace`端點就可獲得類似如下的結果: 發送 `GET`請求到:[http://localhost:8888/trace](http://localhost:8888/trace) ```json [ { "timestamp": 1514543931362, "info": { "method": "GET", "path": "/eureka-provider/dev/master", "headers": { "request": { "accept": "application/json, application/*+json", "user-agent": "Java/1.8.0_112", "host": "localhost:8888", "connection": "keep-alive" }, "response": { "X-Application-Context": "config-server:8888", "Content-Type": "application/json;charset=UTF-8", "Transfer-Encoding": "chunked", "Date": "Fri, 29 Dec 2017 10:38:51 GMT", "status": "200" } }, "timeTaken": "6002" } }, { "timestamp": 1514543927451, "info": { "method": "GET", "path": "/eureka-provider/dev/master", "headers": { "request": { "accept": "application/json, application/*+json", "user-agent": "Java/1.8.0_112", "host": "localhost:8888", "connection": "keep-alive" }, "response": { "X-Application-Context": "config-server:8888", "Content-Type": "application/json;charset=UTF-8", "Transfer-Encoding": "chunked", "Date": "Fri, 29 Dec 2017 10:38:47 GMT", "status": "200" } }, "timeTaken": "4927" } }, { "timestamp": 1514543925254, "info": { "method": "GET", "path": "/eureka-provider/dev/master", "headers": { "request": { "accept": "application/json, application/*+json", "user-agent": "Java/1.8.0_112", "host": "localhost:8888", "connection": "keep-alive" }, "response": { "X-Application-Context": "config-server:8888", "Content-Type": "application/json;charset=UTF-8", "Transfer-Encoding": "chunked", "Date": "Fri, 29 Dec 2017 10:38:45 GMT", "status": "200" } }, "timeTaken": "2862" } }, { "timestamp": 1514543923565, "info": { "method": "POST", "path": "/bus/refresh", "headers": { "request": { "cache-control": "no-cache", "postman-token": "0e497ec1-0c03-4dc2-bb61-ce2a266227d3", "user-agent": "PostmanRuntime/7.1.1", "accept": "*/*", "host": "127.0.0.1:8888", "accept-encoding": "gzip, deflate", "content-length": "0", "connection": "keep-alive" }, "response": { "X-Application-Context": "config-server:8888", "status": "200" } }, "timeTaken": "6616" } } ] ``` # 源碼下載 **GitHub:**[https://github.com/souyunku/spring-cloud-examples/tree/master/spring-cloud-config-bus-rabbitMQ](https://github.com/souyunku/spring-cloud-examples/tree/master/spring-cloud-config-bus-rabbitMQ) **碼云:**[https://gitee.com/souyunku/spring-cloud-examples/tree/master/spring-cloud-config-bus-rabbitMQ](https://gitee.com/souyunku/spring-cloud-examples/tree/master/spring-cloud-config-bus-rabbitMQ)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看