天天看點

SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)

内容概述

Config 分布式配置中心

Bus 消息總線

Stream 消息驅動

Sleuth+Zipkin 鍊路追蹤

一、config-概述

疑問:什麼是springcloud的config,有什麼用?

分析:

springcloud用來管理分布式微服務的配置檔案。

• Spring Cloud Config 解決了在分布式場景下多環境配置檔案的管理和維護。

• 好處:

• 集中管理配置檔案

• 不同環境不同配置,動态化的配置更新

• 配置資訊改變時,不需要重新開機即可更新配置資訊到服務

二、config-快速入門-gitee搭建遠端倉庫

​ 為了讓微服務的各個應用都能擷取到配置,我們将配置放在雲端,建立基于碼雲gitee,搭建的遠端git代碼倉庫。

​ 該倉庫就是為了放置配置檔案,和我們之前搭建的git代碼倉庫無不同。

config有兩部分組成:

1. config server :通過遠端的git代碼倉庫,管理配置檔案。

2. config client : 就是之前開發的springcloud的各種需要進行配置的應用,連接配接config server擷取配置檔案。

操作:

  1. 登入碼雲

    https://gitee.com/

  2. 建立遠端倉庫
  3. 使用用戶端連接配接遠端倉庫
  4. 上傳配置檔案到倉庫

    配置檔案的名稱要求: 帶有-,前面是配置名稱,後面是profile的名稱。後面配置需要使用。

    SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)

三、config-快速入門-config server搭建

​ 搭建config server應用。

操作步驟:

  1. 建立spring cloud子產品
  2. 添加依賴
    <dependencies>
    
            <!-- config-server -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-config-server</artifactId>
            </dependency>
    
        </dependencies>
               
  3. 編寫啟動類,添加啟用config server注解
    @SpringBootApplication
    @EnableConfigServer // 啟用config server功能
    public class ConfigServerApp {
    
        public static void main(String[] args) {
            SpringApplication.run(ConfigServerApp.class,args);
        }
    }
    
               
  4. 配置檔案
    server:
      port: 9527
    
    spring:
      application:
        name: config-server
      # spring cloud config
      cloud:
        config:
          server:
            # git 的 遠端倉庫位址
            git:
              uri: https://gitee.com/itheima_cch/itheima-configs.git
          label: master # 分支配置
    
               
  5. 通路config server

    http://localhost:9527/master/config-dev.yml

    說明: master是分支名。

    ​ config-dev.yml是倉庫中的檔案名

四、config-快速入門-config client搭建

​ 搭建config client應用。需要配置檔案的應用都是用戶端。這裡有config-provider,config-consumer。

案例中以config-provider應用為例。

  1. 在config-provider應用中,添加依賴
    <!--config client -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-config</artifactId>
            </dependency>
               
  2. 在應用中建立配置檔案:bootstrap.yml

    bootstrap.yml也是spring boot的預設配置檔案,并且優先級要比application.yml高。

SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)
  1. 配置bootstrap.yml
    # 配置config-server位址
    # 配置獲得配置檔案的名稱等資訊
    spring:
      cloud:
        config:
          # 配置config-server位址
          uri: http://localhost:9527
          # 配置獲得配置檔案的名稱等資訊
          name: config # 檔案名
          profile: dev # profile指定,  config-dev.yml
          label: master # 分支
    
    
               
  2. 編寫controller,擷取配置檔案中的資料
SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)
SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)
  1. 啟動eureka-server-config和config-provider進行測試。
    SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)

五、config-快速入門-config client重新整理

​ spring cloud config可以在git倉庫中配置檔案内容發生變化的時候,不需要重新開機就能擷取新的配置檔案。

服務端config server: 無需做任何設定,當git中的配置檔案修改後,自動擷取最新配置檔案。

用戶端config client: config-provider預設不會擷取最新配置檔案

config client重新整理操作步驟:

  1. 在 config 用戶端引入 actuator 依賴【案例已經添加】
  2. 擷取配置資訊類上,添加 @RefreshScope 注解
    @RestController
    @RequestMapping("/goods")
    @RefreshScope // 開啟重新整理功能
    public class GoodsController {
               
  3. 添加配置 bootstrap.yml

    management.endpoints.web.exposure.include: refresh

management:
  endpoints:
    web:
      exposure:
        include: '*'     # 暴漏的endpoint,*表示所有
           
  1. 使用curl工具發送post請求

    curl -X POST http://localhost:8001/actuator/refresh

六、config-快速入門-內建Eureka

疑問: 用戶端配置config server的uri是固定寫死的位址,我們需要從注冊中心中擷取。

SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)

​ 将config server注冊到Eureka中,config client從注冊中心通過application name擷取config server的位址。

  1. config server服務端配置

    添加eureka用戶端坐标

    <!-- eureka-client -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
               
    配置檔案(已經添加)
    spring:
      application:
        name: config-server
               
  2. config client用戶端配置,config-provider

    bootstrap.yml

    spring:
      cloud:
        config:
          # 配置config-server位址
          #uri: http://localhost:9527
          # 配置獲得配置檔案的名稱等資訊
          name: config # 檔案名
          profile: dev # profile指定,  config-dev.yml
          label: master # 分支
          discovery:
            enabled: true
            service-id: config-server
               

七、Bus 消息總線-概述

疑問:

​ 通過config server我們遠端統一管理配置檔案,但是當配置發生變化的時候,我們需要依次的執行:

http://localhost:8001/actuator/refresh 進行應用配置的重新整理,不太友善

什麼是bug總線?

• Spring Cloud Bus 是用輕量的消息中間件将分布式的節點連接配接起來,可以用于廣播配置檔案的更改或者服務的監控管理。關鍵的思想就是,消息總線可以為微服務做監控,也可以實作應用程式之間相通信。

• Spring Cloud Bus 可選的消息中間件包括 RabbitMQ 和 Kafka 。

SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)

為什麼要用bus?

當config server中的配置檔案發生變化,通過bus通知所有的用戶端應用,讓他們自己去重新整理,達到隻需要發生一個指令,所有連接配接在config server中的用戶端都可以重新整理配置的作用。

八、Bus 消息總線-快速入門

​ config-server通過bus發送消息

​ config-client通過bus接收消息

準備工作:

​ 因為bus總線可以讓多個用戶端同時更新,所有我們将config-consumer也作為一個config-client。

config-consumer子產品。

  1. <!--config client -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-config</artifactId>
            </dependency>
               
  2. 進行配置

    直接複制config-provider\src\main\resources\bootstrap.yml檔案,無需修改。

  3. 在controller上添加重新整理注解,并使用配置資訊
    @RestController
    @RequestMapping("/order")
    @RefreshScope
    public class OrderController {
    
    
        @Value("${itheima}")
        private String itheima;
    
        @Autowired
        private GoodsFeignClient goodsFeignClient;
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
            Goods goods = goodsFeignClient.findGoodsById(id);
    
            goods.setTitle(goods.getTitle()+"--"+itheima);
    
            return goods;
        }
    
    
    }
               
  4. 通路測試
SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)

通路1會傳回降級的資訊,就不會出現兩次配置資訊。

使用BUS操作步驟:

  1. 分别在 config-server 和 config-client中引入 bus依賴:bus-amqp
    <!-- bus -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-bus-amqp</artifactId>
            </dependency>
               
  2. 分别在 config-server 和 config-client中配置 RabbitMQ(3個子產品都配置)

    bootstrap.yml和config-server的application.yml

    #配置rabbitmq資訊
      rabbitmq:
        host: 192.168.200.129
        port: 5672
        username: guest
        password: guest
        virtual-host: /
               
    注意位置:是spring節點的屬性
  3. 在config-server中設定暴露監控斷點:bus-refresh

    是通過actuator來實作,添加對actuator的依賴

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
               
    暴漏endpoint的配置
    # 暴露bus的重新整理端點
    management:
      endpoints:
        web:
          exposure:
            include: 'bus-refresh'
               
  4. 啟動測試

    通路的是config-server的重新整理節點:

    curl -X POST http://localhost:9527/actuator/bus-refresh

九、Stream消息驅動-概述

疑問:什麼是Stream消息驅動?有什麼用?

• Spring Cloud Stream 是一個建構消息驅動微服務應用的架構。

• Stream 解決了開發人員無感覺的使用消息中間件的問題,因為Stream對消息中間件的進一步封裝,可以做到代碼層面對中間件的無感覺,甚至于動态的切換中間件,使得微服務開發的高度解耦,服務可以關注更多自己的業務流程。

• Spring Cloud Stream目前支援兩種消息中間件RabbitMQ和Kafka

Stream消息驅動有什麼用?

​ 和具體的消息中間件解耦

十、Stream消息驅動-元件

• Spring Cloud Stream 建構的應用程式與消息中間件之間是通過綁定器 Binder相關聯的。綁定器對于應用程式而言起到了隔離作用, 它使得不同消息中間件的實作細節對應用程式來說是透明的。

元件:

綁定器 Binder

動作:

• binding 是我們通過配置把應用和spring cloud stream 的 binder 綁定在一起

• output:發送消息 Channel,内置 Source接口

• input:接收消息 Channel,内置 Sink接口

十一、Stream消息驅動-消息生産者

疑問: 如何發送消息?

  1. 建立消息生産者子產品,引入依賴 starter-stream-rabbit
    <dependencies>
    
            <!--spring boot web-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
    
            <!-- stream -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
            </dependency>
    
        </dependencies>
               
  2. 編寫啟動類。
    @SpringBootApplication
    public class ProducerApp {
        public static void main(String[] args) {
    
            SpringApplication.run(ProducerApp.class,args);
        }
    }
               
  3. 編寫配置,定義 binder,和 bingings
    server:
      port: 8000
    
    spring:
      cloud:
        stream:
          # 定義綁定器,綁定到哪個消息中間件上
          binders:
            itheima_binder: # 自定義的綁定器名稱
              type: rabbit # 綁定器類型
              environment: # 指定mq的環境
                spring:
                  rabbitmq:
                    host: localhost
                    port: 5672
                    username: guest
                    password: guest
                    virtual-host: /
          bindings:
            output: # channel名稱
              binder: itheima_binder #指定使用哪一個binder
              destination: itheima_exchange # 消息目的地,交換機的名稱
    
    
               

    配置兩個方面:

    ​ binders:主要就是操作的MQ的消息隊列資訊(必配)

    ​ bindings: 生産者就是發送消息的資訊(生産者配置output)

  4. 定義消息發送業務類。添加 @EnableBinding(Source.class),注入MessageChannel output ,完成消息發送
import org.springframework.cloud.stream.messaging.Source;

@Component
@EnableBinding(Source.class)
public class MessageProducer {

    @Autowired
    private MessageChannel output;

    public void send(){
        String msessage = "hello stream~~~";

        //發送消息
        output.send(MessageBuilder.withPayload(msessage).build());

        System.out.println("消息發送成功~~~");

    }
}

           

通過controller發送消息

@RestController
public class ProducerController {

    @Autowired
    private MessageProducer producer;


    @RequestMapping("/send")
        public String sendMsg(){
        producer.send();
        return "success";
    }
}

           
  1. 測試

    http://localhost:8000/send

十二、Stream消息驅動-消息消費者

疑問: 如何接收消息?

  1. 建立消息消費者子產品,引入依賴 starter-stream-rabbit
    <dependencies>
    
            <!--spring boot web-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
    
            <!-- stream -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
            </dependency>
    
        </dependencies>
               
  2. @SpringBootApplication
    public class ConsumerApp {
        public static void main(String[] args) {
    
            SpringApplication.run(ConsumerApp.class,args);
        }
    }
    
               
  3. server:
      port: 9000
    
    spring:
      cloud:
        stream:
          # 定義綁定器,綁定到哪個消息中間件上
          binders:
            itheima_binder: # 自定義的綁定器名稱
              type: rabbit # 綁定器類型
              environment: # 指定mq的環境
                spring:
                  rabbitmq:
                    host: localhost
                    port: 5672
                    username: guest
                    password: guest
                    virtual-host: /
          bindings:
            input: # channel名稱
              binder: itheima_binder #指定使用哪一個binder
              destination: itheima_exchange # 消息目的地
               
  4. 定義消息接收業務類。添加 @EnableBinding(Sink.class),使用

    @StreamListener(Sink.INPUT),完成消息接收。

import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
/**
 * 消息接收類
 */
@EnableBinding({Sink.class})
@Component
public class MessageListener {

    @StreamListener(Sink.INPUT)
    public void receive(Message message){

        System.out.println(message);
        System.out.println(message.getPayload());
    }
}
           

十三、Sleuth+Zipkin 鍊路追蹤-概述

疑問:微服務調用複雜,出現問題如何發現?

鍊路追蹤是什麼?幹嗎用?

• Spring Cloud Sleuth 其實是一個工具,它在整個分布式系統中能跟蹤一個使用者請求的過程,捕獲這些跟蹤資料,就能建構微服務的整個調用鍊的視圖,這是調試和監控微服務的關鍵工具。

• 耗時分析

• 可視化錯誤

• 鍊路優化

• Zipkin 是 Twitter 的一個開源項目,它緻力于收集服務的定時資料,以解決微服務架構中的延遲問題,包括資料的收集、存儲、查找和展現。

SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)

總結:

Sleuth 收集spring cloud調用中的資料

Zipkin 圖形化的展示收集的資料

十四、Sleuth+Zipkin 鍊路追蹤-快速入門

分析:搭建Sleuth+Zipkin 鍊路追蹤。Sleuth是個依賴,直接添加。Zipkin 是開源項目,需要啟動應用。

  1. 安裝啟動zipkin。 java –jar zipkin.jar
    SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)
  2. 通路zipkin web界面。 http://localhost:9411/
    SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)
  3. 在服務提供方和消費方分别引入 sleuth 和 zipkin 依賴
    <!-- sleuth-zipkin -->
            <!--<dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-sleuth</artifactId>
            </dependency>-->
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-zipkin</artifactId>
            </dependency>
               
    zipkin依賴了sleuth,添加了zipkin,兩個就都有了。
  4. 分别配置服務提供方和消費方。

    sleuth-provider

    spring:
      application:
        name: sleuth-provider
      zipkin:
        base-url: http://localhost:9411/  # 設定zipkin的服務端路徑
    
      sleuth:
        sampler:
          probability: 1 # 采集率 預設 0.1 百分之十。
               
    sleuth-consumer
    spring:
      application:
        name: sleuth-consumer # 設定目前應用的名稱。将來會在eureka中Application顯示。将來需要使用該名稱來擷取路徑
      zipkin:
        base-url: http://localhost:9411/  # 設定zipkin的服務端路徑
    
      sleuth:
        sampler:
          probability: 1 # 采集率 預設 0.1 百分之十。
    
    
    logging:
      level:
        com.itheima: debug
    
               
  5. 啟動,測試

    http://localhost:9411/

    調用花費時間:

SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)

調用的請求:

SpringCloud(三、Config、Bus、Stream 、Sleuth+Zipkin)