SpringCloud Bus消息總線


在微服務架構中,通常會使用輕量級的消息代理來構建一個共用的消息主題來連接各個微服務實例,它廣播的消息會被所有在注冊中心的微服務實例監聽和消費,也稱消息總線。 

SpringCloud中也有對應的解決方案,SpringCloud Bus 將分布式的節點用輕量的消息代理連接起來,可以很容易搭建消息總線,配合SpringCloud config 實現微服務應用配置信息的動態更新。

 

消息總線其實通過消息中間主題模式他使用廣播消息的機制被所有在注冊中心微服務實例進行監聽和消費。以廣播形式將消息推送給所有注冊中心服務列表


消息代理屬於中間件。設計代理的目的就是為了能夠從應用程序中傳入消息,並執行一些特別的操作。開源產品很多如ActiveMQ、Kafka、RabbitMQ、RocketMQ等
目前springCloud僅支持RabbitMQ和Kafka。本文采用RabbitMQ實現這一功能。

 

圖示:

  

 

 通過客戶端去通知每個服務 更新配置文件

  

升級  通過消息總線的方式:

 

 

 

 消息總線框架底層是MQ實現的,引入相應的jar包,底層框架實現好了,每個服務里面引入了相應的jar包后,自動創建隊列 綁定交換機等等

 配置文件的應用場景就很符合。

 

 環境搭建:

       

 每個服務對於分布式配置中心來說是 client端

 配置文件環境 dev test  pre prd

 配置文件命名規范  client服務名稱(注冊中心名稱)-版本.yml 

 

創建好這個文件

 

 

互聯網項目場景中的配置文件 不是存放在本底的  是存放在遠程服務器

寫在本地 需要重啟服務器  !!

下面開始搭建分布式配置中心 SpringCloude  組件  Config

   

1、配置文件存放在git 或者 svn

2、搭建分布式配置中心服務

3、客戶端讀取分布式配置中心服務

 

 configServer端:

配置文件:

  pom:

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.toov5</groupId>
  <artifactId>SpringCloud-eureka-server</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <!-- 管理依賴 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!--SpringCloud eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
            <!-- hystrix斷路器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        
    </dependencies> 
    <!-- 注意: 這里必須要添加, 否者各種依賴有問題 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
  
</project>

yml:

###服務注冊到eureka地址
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka
spring:
  application:
    ####注冊中心應用名稱
    name: config-server
  cloud:
    config:
      server:
        git:
          ###git環境地址
          uri: https://gitee.com/toov5/distributed_configuration_file.git
          ####搜索目錄
          search-paths:
            - Test  
      ####讀取分支      
      label: master
####端口號      
server:
  port: 8888

啟動:

package com.toov5.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer
public class AppServerConfig {
   
    public static void main(String[] args) {
        SpringApplication.run(AppServerConfig.class, args);
    }
}

啟動Eureka后啟動 configServer

 

 訪問地址: http://127.0.0.1:8888//appConfig-dev.yml

 

Client端:

pom:

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.toov5</groupId>
  <artifactId>SpringCloud_config_client</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>

    <dependencies>
        <!-- SpringBoot整合Web組件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
            <version>2.0.2.RELEASE</version>
        </dependency>
        <!-- SpringBoot整合eureka客戶端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.0.2.RELEASE</version>
        </dependency>

    </dependencies>
    <!-- 注意: 這里必須要添加, 否者各種依賴有問題 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
  
</project>

Controller:

package com.toov5.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {
     @Value("${userAge}")  //配置中心的 我們這個字段在本地沒有配置
     private String userAge;
     
     @RequestMapping("/getUserAge")
     public String getUerAge() {
          return userAge;
     }
}

啟動類:

package com.toov5.controller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class AppClientConfig {
  public static void main(String[] args) {
    SpringApplication.run(AppClientConfig.class, args);
}
}

yml:

對應命名規范去配置!

spring:
  application: 
    ####注冊中心應用名稱    對應命名規范去配置 appConfig-dev.yml
    name:  appConfig
  cloud:
    config:
    ####讀取后綴
      profile: dev   #對應命名規范去配置
      ####讀取config-server注冊地址
      discovery:
        service-id: config-server   ##服務的名字
        enabled: true
#####    eureka服務注冊地址    
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka    
server:
  port: 8882  

訪問結果:

如果此時 修改了配置文件,刷新出來的還是不變的!緩存到當前的jvm中了  重啟client端就OK了   可以做定時刷新

 

升級: 不重啟服務器自動刷新

 1.手動通知刷新單個jvm值

 2. 消息總線通知整個微服務刷新

 

1. 通過監控中心

   手動actuator端點刷新數據

   引入mavn 到client   

<!-- actuator監控中心 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

 

 yml

   開啟監控服務

  

management:
  endpoints:
    web:
      exposure:
        include: "*"

 此時的yml:

spring:
  application: 
    ####注冊中心應用名稱    對應命名規范去配置 appConfig-dev.yml
    name:  appConfig
  cloud:
    config:
    ####讀取后綴
      profile: dev   #對應命名規范去配置
      ####讀取config-server注冊地址
      discovery:
        service-id: config-server   ##服務的名字
        enabled: true
#####    eureka服務注冊地址    
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka    
server:
  port: 8882
  
  
#開啟所有服務端點權限  
management:
  endpoints:
    web:
      exposure:
        include: "*"
  

 

然后Controller 加上 刷新的注解   @RefreshScope

package com.toov5.controller;

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 IndexController {
     @Value("${userAge}")  //配置中心的 我們這個字段在本地沒有配置
     private String userAge;
     
     @RequestMapping("/getUserAge")
     public String getUerAge() {
          return userAge;
     }
}

對應的值 不用重啟就可以刷新了

 啟動后:修改git的文件值

發送post請求:

http://127.0.0.1:8882/actuator/refresh

 

有個缺點,如果configClient做個集群

如要去刷新每個 服務的值!  postman 搞一遍

 

升級:這樣就需要消息總線了!

 

   

 SpringCloud整合rabbitmq 和 kafka

 本文采用的是rabbitmq去作為案例講解:

  rabbitmq 的加交換機有四種: fanout  direct  topic  head

 

  在這個體系中  微服務有多少個 就會在MQ中創建多少個隊列,當手動刷新一個服務時候,會通過rabbitmq 去把消息同時發給交換機,然后通過交換機發送給其他的微服務 。

 

 

 環境的搭建:

   引入maven: bus的核心jar包

   client和servler端都需要引入   

    <!--核心jar包 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <!-- actuator監控中心 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

如果報錯添加:

 <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-bus-parent</artifactId>
                <version>2.0.0.RC2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

客戶端需要yml開啟bus刷新:client端

###開啟bus刷新
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh  

 同時需要配置mq的連接信息:

此時的client端yml:

spring:
  rabbitmq:
  ####連接地址
    host: 192.168.91.6
   ####端口號  
    port: 5672
   ####賬號
    username: admin
   ####密碼 
    password: admin
   ### 地址  主機獨立的virtualhost
    virtual-host: /admin_toov5
  application: 
    ####注冊中心應用名稱    對應命名規范去配置 appConfig-dev.yml
    name:  appConfig
  cloud:
    config:
    ####讀取后綴
      profile: dev   #對應命名規范去配置
      ####讀取config-server注冊地址
      discovery:
        service-id: config-server   ##服務的名字
        enabled: true
#####    eureka服務注冊地址    
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka    
server:
  port: 8882
  
###開啟bus刷新
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh

server:

###服務注冊到eureka地址
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka
spring:
  rabbitmq:
  ####連接地址
    host: 192.168.91.6
   ####端口號  
    port: 5672
   ####賬號
    username: admin
   ####密碼 
    password: admin
   ### 地址  主機獨立的virtualhost
    virtual-host: /admin_toov5
  application:
    ####注冊中心應用名稱
    name: config-server
  cloud:
    config:
      server:
        git:
          ###git環境地址
          uri: https://gitee.com/toov5/distributed_configuration_file.git
          ####搜索目錄
          search-paths:
            - Test  
      ####讀取分支      
      label: master
####端口號      
server:
  port: 8888

###開啟bus刷新
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh

 

底層會幫助創建 mq隊列 主題  兩個client  一個 server

 

 

 

 

 訪問一個接口  8882 的,其他的服務8883也會跟着改了!

http://127.0.0.1:8882/actuator/bus-refresh

 

就是玩了個  yml+jar包 而已

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM