Spring Cloud Hystrix理解與實踐(一):搭建簡單監控集群


 

 前言

  在分布式架構中,所謂的斷路器模式是指當某個服務發生故障之后,通過斷路器的故障監控,向調用方返回一個錯誤響應,這樣就不會使得線程因調用故障服務被長時間占用不釋放,避免故障的繼續蔓延Spring Cloud Hystrix實現了斷路器,線程隔離等一系列服務保護功能,它是基於Netflix的開源框架Hystrix實現的。

  目的不是介紹Hystrix的與原理、及其使用等(有時間也要記錄啊),而是通過實戰搭建一個簡單的監控集群,使用Hystrix Dashboard儀表盤動態監控展示以此來加深對Hystrix的認識與理解,為什么要記錄呢?這是因為網上資料甚少(或版本過低,不適用),同時加之書中的Spring Cloud版本與現在Spring Boot 2.x差距明顯。

  本文主要參考《Spring Cloud 微服務實戰》(PDF電子版,需要的朋友可以私聊或評論)

 


 

一、Hystrix 儀表盤

1、認識Hystrix儀表盤

  HystrixCommand與HystrixObserableCommand實例執行過程中記錄的重要信息稱之為Hystrix儀表盤,以供內部或者外部進行查詢使用。Spring Cloud整合儀表盤組件Hystrix Dashboard,主要用來實時監控Hystrix的各項指標信息,可以幫我們快速發現系統中存在的問題,從而及時地采取應對措施。

  1)加入依賴

  特別注意Spring Boot 2.x版本引入的hystrix-dashboard依賴,不然可能訪問不了http://localhost:port/hystrix儀表盤頁面,注解@EnableHsytrixDashboard也可能找不到

 <!-- hystrix 容錯機制 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency>
        <!-- actuator監控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- Spring Boot 2.x以上版本 spring-cloud-starter-netflix-hystrix-dashboard 儀表盤,
        以下版本則需要spring-cloud-starter-hystrix-dashboard-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency> 

  2)添加配置

# 應用實例
spring:
  application:
    name: hystrix-dashboard

server:
  port: 8000

# actuator開放所有端點,Spring Boot 2.x與1.x不同,具體請查詢
management:
  endpoints:
    web:
      exposure:
        include: "*"

  3)增加注解:應用主類加上@EnableHsytrixDashboard,啟用Hystrix Dashboard功能。

@EnableHystrixDashboard // 開啟Hystrix儀表盤
@SpringBootApplication
public class HystrixMonitorApplication {

    public static void main(String[] args) {
        SpringApplication.run(HystrixMonitorApplication.class, args);
    }

}

  4)訪問http://localhost:8000/hystrix界面如下:

          

2、監控頁面介紹

從界面中我們就可以看到Hystrix Dashboard支持不同的三種監控方式:

  1) 默認的集群監控:通過URL http://turbine-hostname:port/turbine.stream

  2) 指定的集群監控:通過URL http://turbine-hostname:port/turbine.stream?cluster=[clusterName]開啟

  3) 單體應用的監控:URL http://hystrix-app:port/hystrix.stream開啟,實現對具體某個服務實例的監控

   前兩者關於集群的監控需要整合turbine才能實現,而對於單體實例節點需要訪問實例的/hystrix.stream接口實現,我們自然需要為服務實例添加端點。只需要添加acutator與hystrix依賴,應用主程序類開啟斷路器@EnableCircuitBreaker注解與@EnableHystrixDashboard注解即可。

其中的參數:

  1)Delay:用來控制服務器上輪詢監控信息的延遲時間,默認為2000ms。可以通過該配置該屬性降低客戶端的網絡和CPU消耗。

  2)Ttile:對應進入監控后的的標題,如Hystrix,則進入監控頁面后如下圖紅框標題

此外,我們在URL框輸入我們需要監聽的某個服務實例/hystrix.stream接口,如http://localhost:8081/hystrix.stream,就可以進入監控頁面

 

 

                      

監控頁面參數介紹:

1) 實心圓與曲線的含義

  實心圓顏色:健康度從綠色、黃色、橙色、紅色遞減

  實心圓大小:會根絕實例的請求流量發生變化,流量越大實心圓就越大。

  曲線:用來記錄2分鍾內流量的相對變化,可以通過它來觀察流量的上升與下降。

2) 其它的指標參數:鼠標停留會顯示相應的說明

          

 

二、簡單監控架構

1、監控單實例的架構

  (1)架構圖

 

         

 

  (2)過程說明

    • 服務提供者:HELLO-SERVICE,提供一個接口如:http:/HELLO-SERVER/hello,讓消費者通過restTemplate(封裝好的HTTP)調用消費
    • 服務消費者:RIBBON-CONSUMER,會有ribbon承擔負載均衡的作用,分別輪詢訪問HELLO-SERVER-1與HELLO-SERVICE-2
    • 注冊中心:Spring Cloud Eureka,主要負責服務治理:服務的注冊、續約、剔除(更新)等
    • Hystrix儀盤表:通過/hystrix.stream接口監控某個服務實例,動態展示儀表盤數據。

  然而現在只針對一個實例來監控,而分布式系統中往往有很多實例,我們就需要利用Turbine和Hystrix Dashboard配置實現對集群的監控

 

2、監控聚合服務

  需要通過Turbine來聚合RIBBON-CONSUMER-1與服務RIBBON-CONSUMER-2成一個服務展示監控信息,並輸出到Hystrix Dashboard中,只顯示一張監控圖,但是注意Hosts的數量為2

                

 

  (1)架構圖

        

  (2)過程說明

    同上述“單實例監控”,不同的是這次服務消費者有RIBBON-CONSUMER-1與RIBBON-CONSUMER-2兩個,通過/turbine.stream接口聚合兩個服務實例(實則就是同一個服務不同實例)成一個服務,共同動態展示整個集群的動態數據。對於集群來說關注的是服務集群的高可用性,所以Turbine會將相同服務作為整體看待。

 

三、代碼實踐

1、實踐前的准備

  首先本示例使用的是Idea+Maven構造的項目工程的,所以先熟悉下idea如何構建一個簡單的Spring Boot項目

  1)新建項目:File->New->Project

  

  2)選擇Spring Initializr,選擇默認的https://start.spring.io(需要聯網),點擊Next

  

  3)填寫項目信息

  

  4)選擇依賴,這里我們只需要選擇web依賴即可,之后再加入相關Spring Cloud Hystrix的依賴,這是因為Spring Boot版本與Spring Cloud版本有相對應的關系,不然會沖突項目到處都是坑

  

  5)查看Spring Boot與Spring Cloud的版本對應關系從官網(https://spring.io/projects/spring-cloud)中查看,這里使用的是Spring Boot 2.0.6.RELEASE與Spring Cloud Fincley.SR1

 

   

  6)我們需要搭建以下的架構

            

 

  從圖中我們知道我們需要:

  1)兩個Eureaka Server提供高可用的注冊中心:

    分別對應工程eureka-server與eureke-slave-server,配置文件中register-with-eureka與fetch-registry保持默認true,相互注冊進行同步維護服務實例列表。

  2)兩個服務提供者實例提供HELLO-SERVICE/hello服務:

    對應工程hello-service,打包成jar包。

    通過命令 java -jar hello-service-0.0.1-SNAPSHOT.jar --server.port=8081 開啟實例HELLO-SERVICE-1

    通過命令 java -jar hello-service-0.0.1-SNAPSHOT.jar --server.port=8082 開啟實例HELLO-SERVICE-2

  3)兩個服務消費者實例消費HELLO-SERVICE/hello服務

    對應工程ribbon-consumer,使用ribbon開啟負載均衡,使用hystrix開啟斷路器功能,之后打包jar包。

    通過命令 java -jar ribbon-consumer-0.0.1-SNAPSHOT.jar --server.port=8083 開啟實例RIBBON-CONSUMER-1

    通過命令 java -jar ribbon-consumer-0.0.1-SNAPSHOT.jar --server.port=8084 開啟實例RIBBON-CONSUMER-2

  4)開啟Spring Cloud Circuit Breaker 斷路器

    引入相關依賴,應用程序中開啟注解即可,具體請看下面示例。

  5)消費者開啟負載均衡器

    服務消費者直接通過調用被@LoadBalanced注解修飾過的RestTemplate來實現面向服務的接口調用

  6)開啟Hystrix Dashboard儀表盤

    引入hystrix dashboard、turbine等相關依賴,應用程序中開啟注解即可,具體請看下面示例。

 

2、代碼示例 

1)服務治理工程:eureka-service與eureka-slave-service

pom.xml文件內容:eureka-service與eureka-slave-service都相同

<properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
        <spring-cloud-eureka.version>1.4.6.RELEASE</spring-cloud-eureka.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring Cloud Eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency>
        <!-- 可以刪除(需要同時刪除Test類),但是為了不麻煩就保留了 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

eureka-service的application.yml文件:

server:
  port: 5678
eureka:
  instance:
    hostname: master
  # slave注冊中心url
  client:
    service-url:
      defaultZone: http://slave:5679/eureka/
  # 關閉保護模式
  server:
    enable-self-preservation: false

eureka-slave-service的application.yml文件:

server:
  port: 5679
eureka:
  instance:
    hostname: slave
  client:
    service-url:
      defaultZone: http://master:5678/eureka/
  server:
    enable-self-preservation: false

注:需要在hosts文件中添加slave/master域名解析。

應用程序類開啟@EnableEurekaServer注解,表明是注冊中心服務器

@EnableEurekaServer
@SpringBootApplication
public class EurekaSlaveServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaSlaveServerApplication.class, args);
    }

}

2)服務提供者工程:hello-service

pom.xml文件內容:

注:這里加入的依賴是spring-cloud-starter-eureka,不是spring-cloud-starter-eureka-server

<properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
        <spring-cloud-eureka.version>1.4.6.RELEASE</spring-cloud-eureka.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

application.yml配置文件:

spring:
  application:
    name: hello-service
# 注冊中心url
eureka:
  client:
    service-url:
      defaultZone: http://master:5678/eureka/,http://slave:5679/eureka/

  instance:
    # 定義服務失效的時間,默認為90s。
    lease-expiration-duration-in-seconds: 60
    # 續約任務的調用時間間隔,默認為30s
    lease-renewal-interval-in-seconds: 10

應用程序增加注解@EnableEurekaClient

@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }

}

編寫/hello接口,提供消費者調用

@RestController
public class HelloController {


    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(){
        return "Hello World";
    }
}

3)服務消費者工程:ribbon-consumer

消費者服務工程是相對比較復雜的,需要幾個步驟:

  • 實現ribbon負載均衡功能:增加@LoadBalanced
  • 實現hystrix斷路器容錯功能:增加@EnableCircuitBreaker
  • 增加actuator監控:增加actuator/hystrix.stream端點,提供hystrix儀表盤monitor使用
  • 編寫容錯降級服務:發生異常超時等情況之后,做相應容錯處理
  • 重新注冊restTemplate:增加@LoadBalanced實現負載均衡
  • 開啟請求緩存:對請求數據做緩存,減少壓力
  • 指定groupName與commandName

pom文件:既然要監控服務實例,自然要在該服務中添加Hystrix與actuator依賴。

<properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
        <spring-cloud-eureka.version>1.4.6.RELEASE</spring-cloud-eureka.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency>
        <!-- ribbon 負載均衡 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency>
        <!-- hystrix 容錯機制 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency>
        <!-- actuator監控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

HelloService: 實現請求處理+降級服務+命令名指定+請求緩存(http://HELLO-SERVER/hello接口並沒有涉及數據交互,這里只做展示)

@Service
public class HelloService {

    private final Logger logger = LoggerFactory.getLogger(HelloService.class);

    @Autowired
    private RestTemplate restTemplate;


    /**
     * 消費者調用服務,並且開啟斷路器指定回調函數
     * 同步執行實現
     * @return
     */
    @CacheResult // 請求命令開啟緩存(可以指定緩存key)
    @HystrixCommand(fallbackMethod = "helloFallback", groupKey = "HelloGroup", commandKey = "HelloKey") // 指定熔斷回調函數
    public String helloService(){
        long start = System.currentTimeMillis();
        // 模擬消息服務時間, getForEntity調用HELLO-SERVER服務的hello接口
        String result = restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
        long end = System.currentTimeMillis();
        logger.info("Spend time: "+(end - start));
        return result;

    }

    /**
     * 通過@CacheKey指定緩存key
     * @param id
     * @return
     */
    @CacheResult
    @HystrixCommand
    public User getUserById(@CacheKey String id){
       User user = restTemplate.getForObject("http://HELLO-SERVICE/hello", User.class);
       return user;
    }

    /**
     * 更新數據:更新緩存(刪除失效緩存)
     * @param user
     */
    @CacheRemove(commandKey = "getUserById")
    @HystrixCommand
    public void update(@CacheKey("id") User user){
        restTemplate.postForObject("http://HELLO-SERVICE/hello", user, User.class);
    }

    /**
     * 獲取cache key
     * @param id
     * @return
     */
    public String getUserByCacheKey(String id){
        logger.info("獲取緩存key....");
        return id;
    }
    /**
     * 消費者調用服務,並且開啟斷路器指定回調函數
     * 異步執行實現
     * @return
     */
    @HystrixCommand(fallbackMethod = "helloFallback") // 指定熔斷回調函數
    public Future<String> helloAsyncService(){
        return new AsyncResult<String>(){
            @Override
            public String invoke(){
               return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
            }
        };
    }

    /**
     * 降級服務
     * @return
     */
    public String helloFallback(){
        return "error";
    }
}
View Code

ConsumerController:對外調用接口/ribbon-consumer。

@RestController
public class ConsumerController {

    @Autowired
    HelloService helloService;


    @RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
    public String helloConsumer(){
        return helloService.helloService();
    }
}

應用程序類RibbonConsumerApplication:開啟斷路器,開啟服務發現,注冊restTemplate,開啟負載均衡

注:可以用@SpringCloudApplication代替,因為@SpringCloudApplication=@EnableCircuitBreaker+@EnableDiscoveryClient+@SpringBootApplication

@EnableCircuitBreaker // 開啟斷路器,也可以使用@SpringCloudApplication
@EnableDiscoveryClient // 開啟服務發現,也可以使用@SpringCloudApplication
@SpringBootApplication
public class RibbonConsumerApplication {


    /**
     * 注冊RestTemplate bean
     * 並開啟負載均衡
     * @return
     */
    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class, args);
    }

}

application.yml文件:

# 服務消費者
spring:
  application:
    name: ribbon-consumer

# 注冊中心地址
eureka:
  client:
    service-url:
      defaultZone: http://master:5678/eureka/,http://slave:5679/eureka/
server:
  port: 9000
# 開放所有端點,與Spring boot 1.x版本有差異
management:
  endpoints:
    web:
      exposure:
        include: "*"

 

4)儀盤表Hystrix Dashboard工程:hystrix-dashboard

pom文件:注意這里的hystrix-dashboard依賴於Spring boot 1.x引入的版本是不同的,具體看注釋

<properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
        <spring-cloud-eureka.version>1.4.6.RELEASE</spring-cloud-eureka.version>
    </properties>

    <dependencies>
        <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>
        <!-- hystrix 容錯機制 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency>
        <!-- actuator監控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- Spring Boot 2.x以上版本 spring-cloud-starter-netflix-hystrix-dashboard 儀表盤,
        以下版本則需要spring-cloud-starter-hystrix-dashboard-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

 

應用程序類:開啟儀表盤注解@EnableHystrixDashboard

@EnableHystrixDashboard // 開啟Hystrix儀表盤
@SpringBootApplication
public class HystrixMonitorMonitorApplication {

    public static void main(String[] args) {
        SpringApplication.run(HystrixMonitorMonitorApplication.class, args);
    }

}

application.yml:

spring:
  application:
    name: hystrix-dashboard

server:
  port: 8000

# 開放所有端點
management:
  endpoints:
    web:
      exposure:
        include: "*"

5)turbine集群監控工程:turbine-monitor

通過turbine來聚合RIBBON-CONSUMER服務的監控信息,並提供/turbine.stream接口輸出給Hystrix Dashboard進行展示

pom.xml文件:增加turbine依賴+actuator依賴

 <properties>
        <java.turbineversion>1.8</java.turbineversion>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
        <spring-cloud-eureka.version>1.4.6.RELEASE</spring-cloud-eureka.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- actuator監控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-turbine</artifactId>
            <version>${spring-cloud-eureka.version}</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

application.yml文件:

spring:
  application:
    name: turbine-monitor
server: port: 8001 # 注冊中心地址 eureka: client: service-url: defaultZone: http://master:5678/eureka/,http://slave:5679/eureka/ turbine: # 指定需要收集監控信息的服務名(一定是大寫,服務注冊后都是大寫) app-config: RIBBON-CONSUMER # 同一主機上的服務通過主機+端口區分(默認同一個主機上聚合成一個服務) combine-host-port: true # 當啟動多個turbine服務構建不同的聚合集群,該參數可以區分不同的聚合集群 # 同時可以在Hystrix Stream的URL中指定Cluster參數指定 cluster-name-expression: new String("default") # 指定聚合哪些集群,多個使用","分割,默認為default。 aggregator: cluster-config: default

應用程序類TurbineMonitorApplication :開啟turbine監控

@SpringBootApplication
@EnableTurbine // 開啟turbine集群監控
@EnableDiscoveryClient
public class TurbineMonitorApplication {

    public static void main(String[] args) {
        SpringApplication.run(TurbineMonitorApplication.class, args);
    }

}

 

至此,所有的項目已經構建完畢,我們現在可以理清整個架構圖,使架構圖更加具體易懂。通過端口+IP的指定,我們可以清楚集群中每個角色的信息:

啟動項目:

第一步:啟動高可用的注冊中心,訪問注冊中心http://slave:5679或者http://master:5678

實例列表中兩個eureka服務實例已經相互注冊

並且已經相互注冊為同步備份服務器,在http://slave:5679中(http://master:5678同理)

 

第二步:啟動服務提供者實例,開啟HELLO-SERVICE-1與HELLO-SERVICE-2服務

執行命令:

 java -jar hello-service-0.0.1-SNAPSHOT.jar --server.port=8081 開啟HELLO-SERVICE-1,保留CMD窗口

 java -jar hello-service-0.0.1-SNAPSHOT.jar --server.port=8082 開啟HELLO-SERVICE-2,保留CMD窗口

查看注冊中心是否已經注冊:

第三步:啟動服務消費者實例,開啟RIBBON-CONSUMER-1與RIBBON-CONSUMER-2服務

執行命令:

   java -jar ribbon-consumer-0.0.1-SNAPSHOT.jar --server.port=8083  開啟RIBBON-CONSUMER-1,保留CMD窗口

   java -jar ribbon-consumer-0.0.1-SNAPSHOT.jar --server.port=8084  開啟RIBBON-CONSUMER-2,保留CMD窗口

查看注冊中心是否已經注冊:

第四步:啟動turbine-monitor項目,訪問http://localhost:8001/turbine.stream

可能一開始的時候一直ping或者返回的data甚少,如下圖:

這是因為我們還沒有訪問http://localhost:8083/ribbon-consumer或者http://localhost:8084/ribbon-consumer接口,訪問后會有很多監控數據返回,如下圖:

 

第五步:啟動hystrix-dashboard項目,開啟hystrix儀表盤監控,輸入URL:http://localhost:8001/turbine.stream,點擊Monitor Stream,進入監控頁面

注:

  若一開始一直顯示Loading,原因同上,都是因為我們還沒有訪問http://localhost:8083/ribbon-consumer或者http://localhost:8084/ribbon-consumer接口

  若一開始Hosts的數目只有1的話,說明我們只訪問了http://localhost:8083/ribbon-consumer或者http://localhost:8084/ribbon-consumer接口其中一個,或者其中一個還沒啟用。同時啟動並訪問后就會顯示Hosts數目為2

正常是這樣的:

                    

 

第六步:觀察監控圖、負載均衡。

 1)觀察負載均衡:

  不斷訪問http://localhost:8083/ribbon-consumer或者http://localhost:8084/ribbon-consumer,可以看到服務提供實例不斷交替打印日志,實際上就是輪詢負載均衡

  

 2)觀察監控圖:

   代碼中已經有模擬超時,如果超時(默認為2000ms)則會顯示error字樣,監控圖中的超時數量會增加1

  

   增加訪問http://localhost:8083/ribbon-consumer或者http://localhost:8084/ribbon-consumer速度(不斷刷新),可以看到監控圖中的流量圖呈上升趨勢

  

 


 

總結

  Spring Cloud的兩個重要角色Spring Cloud ribbon與Spring Cloud Hystrix可以整合為Feign,Feign除了提供這兩個強大的功能外,還提供了一種聲明式的Web服務端定義方式。在Spring Cloud Feign的實現下,我們只需要創建一個接口並用注解的方式陪着它,即可完成對服務提供方的接口綁定,簡化了在使用Spring Cloud Ribbon時自行封裝服務調用客戶端的開發量。同時Spring Cloud Feign擴展了Spring MVC的注解支持。

  本文可能篇幅過長,但是每一步都很仔細,包括架構圖都是自己理解之后所畫。經過這段時間的學習,抽出差不多8小時的編寫(中間瀏覽器崩潰幾次,從頭來過三次),終於寫完了本篇博文,但是仍然有不足之處,敬請見諒,之后再慢慢摸索學習,希望自己能有所收獲!

 

 


免責聲明!

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



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