springboot+cloud 學習(五)統一配置中心 spring cloud config + cloud bus + WebHooks +RibbitMQ

前言

微服務要實現集中管理微服務配置、不一樣環境不一樣配置、運行期間也可動態調整、配置修改後能夠自動更新的需求,Spring Cloud Config同時知足了以上要求。Spring Cloud Config 分爲Config Server和Config Client兩部分,是一個能夠橫向擴展,集中式的配置服務器。spring boot config支持三種存儲方式:本地資源、SVN、GIT。
這裏只介紹GIT的方式。git

Spring Cloud Config 原理圖如圖所示:web

1、新建一個maven項目:config-server

pom.xml以下:spring

<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.skyworth.tvmanage</groupId>
    <artifactId>config-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <!-- 必需要引入 springboot parent ,幫咱們實現了不少jar包的依賴管理 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <dependencyManagement>
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 版本集中配置 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>

        <!-- springboot 自動集成了mvc,直接引用web組件便可 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- eureka client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- config server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

        <!-- bus ribbitmq-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-monitor</artifactId>
        </dependency>

    </dependencies>
</project>

 

application.yml :apache

server:
  port: 8888
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          #服務的git倉庫地址
          uri: https://gitee.com/willpan_z/tvmanage
 #用戶名和密碼
          username: ****
          password: ****
          #本地git配置路徑
          basedir: F:\eclipse-workspace\config         
      #分支 
      label: tvmanage-config
eureka:
  instance:
    hostname: config-server
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://skyworth:skyworth1@eureka-server:8761/eureka/,http://skyworth:skyworth2@eureka-server2:8762/eureka/,http://skyworth:skyworth3@eureka-server3:8763/eureka/
#暴露bus-refresh接口用於更新git上的配置
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh
  

include: bus-refresh 表示暴露 endpoints 的 /actuator/bus-refresh接口 出去,默認是「health」,「info」bootstrap

在啓動類Application上開啓配置中心的註解:@EnableConfigServer:瀏覽器

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

啓動服務,先模擬測試一下,在git上直接新建一個common.yml,輸入http://localhost:8888/tvmanage-config/common-a.yml,安全

訪問成功(注:tvmanage-config爲碼雲上分支的名稱,若是沒有放在分支下,去掉便可)springboot

配置服務中心能夠從遠程程序獲取配置信息,http請求地址和資源文件映射以下:,可參考服務器

·        /{application}/{profile}[/{label}]mvc

·        /{application}-{profile}.yml

·        /{label}/{application}-{profile}.yml

·        /{application}-{profile}.properties

·        /{label}/{application}-{profile}.properties

另外從config-server的控制檯能夠看出,當yml文件從遠端git下載後,會在本地也備份一份,固然這個本地路徑是能夠配置的,

配置命令:spring.cloud.config.server.git.basedir: F:\eclipse-workspace\config

config client 端配置

pom.xml依賴:

<!-- eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- config -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>

        <!-- bus ribbitmq-->
        <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>

    </dependencies>

 

在resources目錄下新建文件bootstrap.yml(這裏有個坑是,eureka的註冊不能寫在遠端,由於要先在eureka註冊後,才能經過eureka服務去找遠端yml)內容:

#前綴路徑
#server:
#  servlet:
#    context-path: /tvmanage # 訪問地址:http://localhost:8090/tvmanage/
server:
  port: 8082
spring:
  application:
    name: management-equip
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG-SERVER
      #對應的配置服務中的應用名稱
      name: common
      #對應config server中配置文件的{label 分支}
      label: tvmanage-config
      #對應config server中配置文件的{profile 環境}
      profile: dev
#服務註冊
eureka:
  instance:
    hostname: equip
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://skyworth:skyworth1@eureka-server:8761/eureka/,http://skyworth:skyworth2@eureka-server2:8762/eureka/,http://skyworth:skyworth3@eureka-server3:8763/eureka/
   

 

啓動類沒有特別須要加的東西。

測試

依次啓動eureka-server,config-server,equip-server,打開瀏覽器訪問:http://localhost:8888/tvmanage-config/common-dev.yml,返回內容:

 

配置中心的自動刷新(spring cloud bus + RibbitMQ + WebHooks)

先說說更新原理

 

GIT上的webhook更新調用config server的/monitor(spring-cloud-config-monitor)觸發RefreshRemoteApplicationEvent事件,

而後spring cloud busStreamListener監聽RemoteApplicationEvent,經過mq發佈到每一個config client,

而後client接收RemoteApplicationEvent事件來實現refresh。

注:這裏簡單說一下spring cloud bus 和spring cloud stream ,2者都是用來消息代理的,bus主要利用廣播機制實現自動刷新配置,stream主要用於服務間的消息調用。

其實,bus也是基於stream的,它使用了一部分stream的功能。

spring cloud bus實現自動刷新配置的方式有2種:

1. 第一種,bus 的refresh操做發生在client端,而後client端通知消息總線bus這個更新信息,bus再通知其餘client端更新

2. 第二種,bus的refresh操做發生在config server端,config server通知bus,再通知其餘client端去更新

這裏咱們使用第二種方式,原理圖以下:

 

這裏的遠端GIT使用的是Gitee(碼雲),其 WebHooks 配置方法(本地測試的話,還須要一個內網穿透,這裏使用的是natapp,就很少說了):

 

這裏設置好了,啓動相關服務(eureka server,config server),點擊測試一下。

當啓動好config server後,咱們打開RibbitMQ:http://localhost:15672 能夠看到cloud bus 自動生成了一個隊列,點擊測試後會有一個消息過來。

 

通常爲了安全,在git傳輸文件的時候都會進行ssh加密傳輸,這裏簡單說一下公匙的應用。

首先使用git bush 生成公匙,輸入 ssh -keygen

而後根據信息找到公匙生成的位置,打開id_rsa.pub,複製其中的內容

 

最後在Gitee上找到公匙的管理,添加複製進去就OK了

 

config client 測試自動刷新配置

在配置文件yml中增長一個自定義屬性:

girl:
  age: 20
  name: lili

而後在config client 的controller中或者啓動類中獲取這個自定義屬性(注意增長@RefreshScope 局部刷新註解):

@RestController
@RequestMapping("/tvmanage/equip")
@RefreshScope public class EquipController {

    @Value("${girl.age}")
    private String girl_age;

    @RequestMapping("hi")
    public String hi(){
        return "hello ,"+ girl_age;
    }
}

 

而後,咱們把yml中 age改成21,客戶端直接訪問hi()方法,http://localhost:8081/tvmanage/equip/hi ,自動刷新成功

相關文章
相關標籤/搜索