一、簡介
微服務之間的調用模式是在不同進程間通過網絡遠程調用,內存間調用和遠程調用之間的巨大差異之一是遠程調用可能會失敗,或者在沒有響應的情況下掛起,直到達到超時限制。如果在無響應的服務提供者上有很多呼叫者,那麼就可能會用盡關鍵資源,如內存、CPU、網絡連接等,從而導致跨多個系統的級聯故障。爲解決這種問題,大神們提出了斷路器模式。
斷路器背後的基本思路很簡單。您將一個受保護的函數調用包裝在斷路器對象中,該對象監視故障。一旦故障達到一定閾值,斷路器跳閘,並且斷路器的所有進一步調用都將返回錯誤,而完全不進行保護呼叫。通常,如果斷路器跳閘,您還需要某種監視器警報。Hystrix就是Netflix 爲實現斷路器模式而開發的一個庫,方便開發者整合進自己的雲計算服務中。
二、Feign搭配Hystrix
繼續我們上一章所講,使用Feign客戶端搭配Hystrix。由於Feign中是自帶Hystrix庫的,所以我們不需要修改POM,代碼只需要再FeignClient那裏加上fallback,也就是回退:當電路斷開或出現錯誤時執行的默認代碼路徑。不過首先呢,我們先實現回退的處理邏輯,代碼如下。
package com.nan.feigndemo.client;
import org.springframework.stereotype.Component;
@Component
public class HelloServiceClientFallback implements HelloServiceClient {
@Override
public String hello(String name) {
return "Error: Hello service error";
}
}
代碼簡單實現一下我們的client接口。然後在FeignClient註解增加fallback屬性,如下。
package com.nan.feigndemo.client;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "HelloService", fallback = HelloServiceClientFallback.class)
public interface HelloServiceClient {
@RequestMapping("/hello")
String hello(@RequestParam("name") String name);
}
然後是配置文件,有一個重要屬性,feign.hystrix.enabled,這個值默認是true的,也就是說feign默認是開啓hystrix功能的,但是有的情況下我們用feign並不需要斷路器,例如訪問量較小的服務,這個屬性就需要改成false,爲了配合本教程,我還是顯示在配置文件中聲明一下,內容如下。
server:
port: 8080
spring:
application:
name: FeignDemo
eureka:
client:
serviceUrl:
defaultZone: http://node01:8081/eureka/,http://node02:8082/eureka/
feign:
hystrix:
enabled: true
代碼部分完了,接下來就是驗證了。首先我們只啓動Eureka server和feigndemo項目,service-hello項目不要啓動,然後在瀏覽器輸入http://localhost:8080/feigndemo?name=秦始皇,可以看到瀏覽器回顯 Error: Hello service error;然後啓動service-hello項目,在輸入接口訪問地址,瀏覽器回顯 Hello 秦始皇, this client port is 9091,斷路器發揮作用了。
三、Hystrix Dashboard
斷路器確實是個好東西,但是我們怎麼能清楚當前斷路器的狀況呢?還好,Spring cloud提供了一個可視化web頁面,就是Hystrix Dashboard,它以有效的方式顯示每個斷路器的運行狀況。我們繼續改進feigndemo項目,首先要加入Hystrix指標流包,就是增加依賴spring-boot-starter-actuator,
這將使/hystrix.stream
作爲管理端點。然後再加入Hystrix
Dashboard啓動器的依賴spring-cloud-starter-hystrix-dashboard,修改後的pom如下。
<?xml version="1.0" encoding="UTF-8"?>
<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.nan</groupId>
<artifactId>feigndemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>feigndemo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
然後市項目啓動入口文件,如下。
package com.nan.feigndemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrixDashboard
@EnableHystrix
public class FeigndemoApplication {
public static void main(String[] args) {
SpringApplication.run(FeigndemoApplication.class, args);
}
}
然後在瀏覽器輸入http://localhost:8080/hystrix,就會看到如下畫面。
最上面的長輸入框輸入http://localhost:8080/hystrix.stream,Title輸入test,然後就會看到如下畫面。
四、聚合監控Turbine
Hystrix Dashboard確實不錯,但也有缺點,就是隻監控一個應用,而云計算是需要多個應用協同工作的,所以Netflix又提供了一個聚合監控的工具Turbine,作用就是將多個服務的狀況集合到一個stream裏面,然後在dashboard看到所有服務,爲了方便此次驗證,我們新增一個user service,基本結構和hello service一樣,這裏就不重複貼代碼了,源碼請參考我的githu,https://github.com/ArnoWang1/springcloud_study,謝謝。
另外我們還要創建一個Turbine的項目,這個項目基本不用寫代碼,配置配置就好,項目pom如下。
<?xml version="1.0" encoding="UTF-8"?>
<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.nan</groupId>
<artifactId>turbinedemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>turbinedemo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR2</spring-cloud.version>
</properties>
<dependencies>
<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>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>aliyunmaven</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
</project>
項目啓動入口增加EnableTurbine註解。
package com.nan.turbinedemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
@SpringBootApplication
@EnableTurbine
public class TurbinedemoApplication {
public static void main(String[] args) {
SpringApplication.run(TurbinedemoApplication.class, args);
}
}
比較重要的是配置文件了,如下。
spring:
application:
name: turbine
server:
port: 7070
turbine:
app-config: FeignDemo
clusterNameExpression: new String("default")
aggregator:
clusterConfig: default
eureka:
client:
service-url:
defaultZone: http://node01:8081/eureka/,http://node02:8082/eureka/
新出現的就是turbine的配置了,其中app-config指eureka中使用了hystrix的服務,因爲我們的feigndemo使用了2個其他服務,所以這裏只需要配feigndemo項目,clusterNameExpression指的是集羣名稱,功能是可以自定義集羣名稱, 默認是appName,此時clusterConfig也需要配置成應用名稱;當clusterNameExpression爲default時,clusterConfig也是default;當clusterNameExpression配置metadata['cluster']元數據時,被監控應用則配置了類似eureka.instance.metadata-map.cluster:
ABC,clusterConfig需要配置成ABC。
OK,然後啓動turbine項目,在hystrix dashboard界面的stream輸入框中填入http://localhost:7070/turbine.stream,就可以在瀏覽器看到這裏顯示了我們的2個服務。
以上就是筆者目前所學,還是很初級的內容,如果有什麼錯誤和遺漏,還請見諒並指正,不勝感激