1. 程式人生 > 其它 >SpringCloud Hystrix要點及Geteway入門

SpringCloud Hystrix要點及Geteway入門

技術標籤:HystrixGatewayspringcloudspring cloud

Hystrix與Geteway簡介


前言

  Hystrix(英文含義:豪豬)由Netflix公司開發的,後來由Spring Cloud Hystrix基於這款框架實現了斷路器、執行緒隔離等一系列服務保護功能,該框架的目標在於通過控制訪問遠端系統、服務和第三方庫的節點,從而延遲和故障提供更強大的容錯能力。

  Hystrix具備服務降級、服務熔斷、執行緒和訊號隔離、請求快取、請求合併以及服務監控等強大功能。是一種微服務的保護機制。
  Hystrix防止某個單元出現故障.從而引起依賴關係引發故障的蔓延,最終導致整個系統的癱瘓。
  Spring Cloud Gateway 裡明確的區分了 Router 和 Filter,並且一個很大的特點是內建了非常多的開箱即用功能,並且都可以通過 SpringBoot 配置或者手工編碼鏈式呼叫來使用。


提示:以下是本篇文章正文內容,下面案例可供參考

一、服務降級

  服務降級:伺服器忙碌或者網路擁堵時,不讓客戶端等待並立刻返回一個友好提示,fallback(備選方案)。

  場景:呼叫服務超時,服務本身 內部錯誤,服務的執行緒資源耗盡

1.區域性服務降級

1.1 在服務提供方設定

  在服務提供方進行區域性服務設定,首先設定自身呼叫超時的峰值,峰值內正常執行,超出峰值需要有兜底的方法處理,作服務降級fallback呼叫。

(1)引入Hystrix依賴

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

(2)在service中對超時方法進行設定,訪問超時呼叫兜底方法
  ( 降級方法(邏輯)編寫的原則是方法的形參和返回值必須要和被降級的方法保持一致。)

   /**
     超時訪問的方法,新增@HystrixCommand註解
     */
    @HystrixCommand(fallbackMethod = "timeoutHandler",commandProperties = {
            //設定峰值,超過 3 秒,就會呼叫兜底方法,這個時間也可以由feign控制
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
    })
    public String paymentInfo_Timeout(Integer id){
    	//設定超時呼叫時間
        int interTime = 5;
        //int i = 10/0;
        try{
            TimeUnit.SECONDS.sleep(interTime);
        }catch (Exception e){
            e.printStackTrace();
        }
        return "執行緒池:" + Thread.currentThread().getName() + "  ,paymentInfo_Timeout,id:" + id + "耗時" + interTime + "秒鐘";
    }
   // 定義服務出現異常之後,兜底的方法
   //降級方法(邏輯)編寫的原則是方法的形參和返回值必須要和被降級的方法保持一致。
    public String timeoutHandler(Integer id){
        return "服務異常,請重試......";
    }
}

(3)在啟動類上加上@EnableCircuitBreaker 作用:開啟服務熔斷
(4)執行測試結果
(5)同樣在service的方法中設定一個異常(替換上一步的超時設定),用於模擬測試

 public String paymentInfo_Timeout(Integer id){
        //int interTime = 5;
        //定義一個異常,用於測試
        int i = 10/0;
}        

(6)測試結果。
在發生服務不可用(呼叫超時或方法內部異常)時,都會進行降級呼叫來處理問題。

1.2 在消費方設定

(1)首先取消上述對於服務提供方的降級呼叫設定
(2)引入Hystrix依賴

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

(3)在啟動類上加上@EnableCircuitBreaker 作用:開啟服務熔斷
(4) 在controller層設定服務降級的邏輯編寫,訪問超時呼叫兜底方法

    @HystrixCommand(fallbackMethod = "handeException", commandProperties = {
            //設定峰值,超過 1.5 秒,就會呼叫兜底方法
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value = "1500")
    })
    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    public String paymentInfo_Timeout(@PathVariable("id")Integer id){
        log.info("paymentInfo_timeout");
        return orderService.paymentInfo_Timeout(id);
    }
	//定義兜底方法
    public String handeException(Integer id){
        return "服務呼叫異常,請稍後再試.....";
    }

(5)執行測試結果
(6)在服務提供方的service的方法中設定一個異常,返回一個值,用於測試結果

public String paymentInfo_Timeout(Integer id){
    	//設定超時呼叫時間
        //int interTime = 5;
        //定義異常
        int i = 10/0;
        /*try{
            TimeUnit.SECONDS.sleep(interTime);
        }catch (Exception e){
            e.printStackTrace();
        }
        return "執行緒池:" + Thread.currentThread().getName() + "  ,paymentInfo_Timeout,id:" + id + "耗時" + interTime + "秒鐘";*/
        return "發生內部異常";
    }

2.全域性服務降級

(1)全域性服務降級

1.在消費方的啟動類上面要加上一個@EnableCircuitBreaker
2.在消費方的controller裡面,定義一個全域性降級的方法。

//全域性服務降級處理在服務消費方上面實現
// 全域性降級處理方法
public String globalHandler(){
    return "這是全域性處理降級邏輯的方法.......";
}

3.在controller上面 新增一個註解@DefaultProperties(defaultFallback = “handleAll”)
4.在指定的被降級的方法上新增一個@HystrixCommand

@RestController
@Slf4j
@DefaultProperties(defaultFallback = "globalHandler") //開啟全域性降級處理
public class OrderController {
    @Autowired
    OrderService orderService;
    
	@HystrixCommand //不寫fallbackMethod屬性,預設是全域性
	@GetMapping("/consumer/payment/hystrix/timeout/{id}") //服務超時
	public String paymentInfo_Timeout(@PathVariable("id")Integer id){
   		log.info("paymentInfo_timeout");
    	return orderService.paymentInfo_Timeout(id);
    }	
}

注意:降級邏輯的優先順序 區域性的降級邏輯>全域性的降級邏輯

(2)服務降級方法抽取

  1. 在消費方的啟動類上面要加上一個@EnableCircuitBreaker
  2. 在配置檔案裡面,開啟feign對Hystrix的支援
feign:
  hystrix:
    enabled: true
  1. 定義一個類,實現Feign客戶端。重寫裡面的方法(編寫降級處理方法)
@Component
public class FallBackService implements OrderService {
    @Override
    public String paymentInfo_OK(Integer id) {
        return "進行paymentInfo_OK方法降級處理......";
    }
    @Override
    public String paymentInfo_Timeout(Integer id) {
        return "進行paymentInfo_Timeout方法降級處理";
    }
}
  1. 使用@FeignClient註解,將這個類繫結到Feign客戶端上去
@Component
@FeignClient(value = "cloud-payment-service",fallback = FallBackService.class)
public interface OrderService {
    @GetMapping("/payment/hystrix/{id}")
    public String paymentInfo_OK(@PathVariable("id")Integer id);
    
    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfo_Timeout(@PathVariable("id")Integer id);
}
  1. 進行測試,檢視降級處理結果

二、服務熔斷

程式碼如下(示例):

1.服務熔斷的概述

  當用戶訪問某個服務,達到了最大的訪問量之後,直接拒絕使用者訪問。
  在SpringCloud框架中,熔斷機制通過Hystrix實現。Hystrix會監控微服務間呼叫的狀況。當失敗的呼叫到一定閾值時,預設是5秒內20次呼叫失敗,就會啟動熔斷機制。熔斷機制的註解是@HystrixCommand。

2.熔斷有哪幾種狀態

熔斷狀態機3個狀態:
  (1)Closed:關閉狀態,所有請求都正常訪問。
  (2)Open:開啟狀態,所有請求都會被降級。Hystix會對請求情況計數,當一定時間內失敗請求百分比達到閾值,則觸發熔斷,斷路器會完全開啟。預設失敗比例的閾值是50%,請求次數最少不低於20次。
  (3)Half Open:半開狀態,open狀態不是永久的,開啟後會進入休眠時間(預設是5S)。隨後斷路器會自動進入半開狀態。此時會釋放部分請求通過,若這些請求都是健康的,則會完全關閉斷路器,否則繼續保持開啟,再次進行休眠計時。

3.斷路器的工作原理

  統計使用者在指定的時間範圍(預設10s)之內的請求總數達到指定的數量之後,如果不健康的請求(超時、異常)佔總請求數量的百分比(50%)達到了指定的閾值之後,就會觸發熔斷。觸發熔斷後,斷路器就會開啟(open),此時所有請求都不能通過。在5s之後,斷路器會恢復到半開狀態(half open),會允許少量請求通過,如果這些請求都是健康的,那麼斷路器會回到關閉狀態(close).如果這些請求還是失敗的請求,斷路器還是恢復到開啟的狀態(open)。

4.如何開啟熔斷?

1.在指定請求方法上,開啟熔斷

@HystrixCommand(fallbackMethod = "handleCircuitBreaker",commandProperties = {
          @HystrixProperty(name="circuitBreaker.enabled", value="true"),  // 是否開啟斷路器
          @HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="10"),  //請求次數
          @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds", value="10000"), // 時間視窗期
          @HystrixProperty(name="circuitBreaker.errorThresholdPercentage", value="60"),  // 失敗率達到多少後跳閘
          //整體意思:10秒內 10次請求,有6次失敗,就跳閘
		})
public String enableCircuitBreaker(Integer id){
    if(id < 0){
        throw  new RuntimeException();
    }
    String uuid = UUID.randomUUID().toString();
    return "返回的uuid是:" + uuid;
}

2.使用XML的方式進行熔斷的配置

#全域性服務降級,feign+hystrix整合,即 service 實現類的方式做全域性配置?
hystrix:
  command:
    default:
      circuitBreaker:
        enabled: true
          requestVolumeThreshold: 10
            sleepWindowInMilliseconds: 10000
              errorThresholdPercentage: 60

三、Hystrix DashBoard

  除了隔離依賴服務的呼叫以外,Hystrix還提供了準時呼叫監控(Hystrix DashBoard),Hystrix 會持續地記錄所有通過Hystrix發起的請求的執行資訊,並以統計報表和圖形的形式展示給使用者,包括每秒執行多少請求多少成功,多少失敗等。
  Netflix通過hystrix-metrics-event-stream專案實現了對以上指標的指控。SpringCloud也提供了Hystrix Dashboard的整合,對監控內容轉化為視覺化介面。

1.建立儀表盤監控模組

(1)在專案中建立儀表盤監控模組
(2)編寫啟動類,使用@EnableHystrixDashboard註解開啟儀表盤監控

@SpringBootApplication
@EnableHystrixDashboard //開啟儀表盤監控
public class HystrixDashboardApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixDashboardApplication.class,args);
    }
}

(3)編寫配置檔案

server:
  port: 9001 #埠號,自定義

(4)引入依賴
注意:所有被監控的服務都需要新增依賴:

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

(5)啟動測試:訪問 http://localhost:9001/hystrix

2. 監控實戰

(1)在http://localhost:9001/hystrix頁面中訪問http://localhost:8001/hystrix.stream
(2)訪問:http://localhost:8001/payment/circuit/1 ,請求資料
檢視請求量等資訊。
類如下圖所示:
在這裡插入圖片描述

四、Geteway閘道器

1.Geteway閘道器簡介

  Spring Cloud Gateway是Spring官方基於Spring 5.0,Spring Boot 2.0和Project Reactor等技術開發的閘道器,Spring Cloud Gateway旨在為微服務架構提供一種簡單而有效的統一的API路由管理方式。Spring Cloud Gateway作為Spring Cloud生態系中的閘道器,目標是替代ZUUL,其不僅提供統一的路由方式,並且基於Filter鏈的方式提供了閘道器基本的功能,例如:安全,監控/埋點,和限流等。

2.Gateway 的核心概念

三大核心概念:
(1)路由(Route):路由是閘道器的基本模組,由ID,目標URL,一系列的斷言和過濾器組成。斷言為真,則路由匹配。
(2)斷言(Predicate):輸入型別是一個ServerWebExchange。開發人員可以使用它匹配HTTP請求中的任何內容,例如headers或引數。如果請求和斷言相匹配,則進行路由。
(3)過濾(Filter):Gateway中的Filter分為兩種型別,分別是Gateway Filter和Global Filter。過濾器可以在請求被路由前或之後
對請求進行修改。

3.如何簡單使用gateway(入門案例)

(1)建立gateway模組
(2)引入POM依賴

 	<!--gateway-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--eureka-client gateWay作為閘道器,也要註冊進服務中心-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!-- gateway和web不能同時存在,即web相關jar包不能匯入 -->

(2)編寫application.yml配置檔案

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  ## GateWay配置
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 開啟從註冊中心動態建立路由的功能,利用微服務名進行路由
      routes:
        - id: payment_routh  # 路由ID , 沒有固定的規則但要求唯一,建議配合服務名
          uri: lb://cloud-payment-service  # 匹配後提供服務的路由地址,之前http://localhost:8001,換成
          predicates:
            - Path=/payment/**  # 斷言,路徑相匹配的進行路由

        - id: payment_routh2  # 路由ID , 沒有固定的規則但要求唯一,建議配合服務名
          uri: lb://cloud-payment-service  # 匹配後提供服務的路由地址,之前localhost:8001,cloud-payment-service
          predicates:
            - Path=/payment/lb/**  # 斷言,路徑相匹配的進行路由,lb 屬於GateWay 的關鍵字,代表是動態uri,即代表使用的是服務註冊中心的微服務名,它預設開啟使用負載均衡機制
            # 在這個時間之後失效
            #- After=2021-01-18T21:08:21.474+08:00[GMT+08:00]
            #- Before=2021-01-18T21:08:21.474+08:00[GMT+08:00]
            #- Between=2021-01-18T21:08:21.474+08:00[GMT+08:00],2021-01-18T22:08:21.474+08:00[GMT+08:00]
            
# 註冊進 eureka Server
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
    register-with-eureka: true
    fetch-registry: true

(3)建立啟動類

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

(4)測試結果

可使用閘道器埠呼叫業務邏輯,隱藏了業務微服務埠,使用閘道器服務對微服務進行保護。


總結

以上就是今天分享的內容,本文僅僅簡單介紹了Hystrix與Gateway閘道器的相關內容及使用。