1. 程式人生 > >Spring Cloud中Hystrix的服務降級與異常處理

Spring Cloud中Hystrix的服務降級與異常處理

上篇文章我們看了自定義Hystrix請求命令的問題,使小夥伴們對Hystrix的使用有了進一步的瞭解,之前兩篇文章都有涉及到一個叫做fallbackMethod的東西,我們之前沒有細說這個東西,今天我們就來詳細說說這個fallbackMethod,也就是服務降級問題。

本文是Spring Cloud系列的第十二篇文章,瞭解前十一篇文章內容有助於更好的理解本文:

服務降級

前面兩篇文章中,fallbackMethod所描述的函式實際上就是一個備胎,用來實現服務的降級處理,在註解中我們可以通過fallbackMethod屬性來指定降級處理的方法名稱,在自定義Hystrix請求命令時我們可以通過重寫getFallback函式來處理服務降級之後的邏輯。使用註解來定義服務降級邏輯時,服務降級函式和@HystrixCommand註解要處於同一個類中,同時,服務降級函式在執行過程中也有可能發生異常,所以也可以給服務降級函式新增‘備胎’,如下:

@HystrixCommand(fallbackMethod = "error1")
public Book test2() {
    return restTemplate.getForObject("http://HELLO-SERVICE/getbook1", Book.class);
}

@HystrixCommand(fallbackMethod = "error2")
public Book error1() {
    //發起某個網路請求(可能失敗)
    return null;
}
public Book error2() {
    return new Book();
}

在實際開發中,並不是所有的請求都要提前預備好服務降級問題,如果我就是要將服務呼叫失敗的資訊展示給使用者,那麼此時就沒有必要新增斷路器了。

異常處理

我們在呼叫服務提供者時有可能會拋異常,預設情況下方法拋了異常會自動進行服務降級,交給服務降級中的方法去處理,在自定義Hystrix請求命令的方式下,我們可以在getFallback方法中呼叫getExecutionException方法來獲取丟擲的異常,舉個簡單的例子:

@Override
protected Book getFallback() {
    Throwable executionException = getExecutionException();
    System.out.println(executionException.getMessage());
    return
new Book("宋詩選注", 88, "錢鍾書", "三聯書店"); } @Override protected Book run() throws Exception { int i = 1 / 0; return restTemplate.getForObject("http://HELLO-SERVICE/getbook1", Book.class); }

此時訪問結果如下:

這裡寫圖片描述

控制檯列印的日誌如下:

這裡寫圖片描述

自動進行了服務降級。

如果我們採用了註解的方式,只需要在服務降級方法中新增一個Throwable型別的引數就能夠獲取到丟擲的異常的型別,如下:

@HystrixCommand(fallbackMethod = "error1")
public Book test2() {
    int i = 1 / 0;
    return restTemplate.getForObject("http://HELLO-SERVICE/getbook1", Book.class);
}

public Book error1(Throwable throwable) {
    System.out.println(throwable.getMessage());
    return new Book("百年孤獨", 33, "馬爾克斯", "人民文學出版社");
}

這裡寫圖片描述

控制檯列印的日誌也是/ by zero,我就不再貼圖片了。此時,如果有一個異常丟擲後我不希望進入到服務降級方法中去處理,而是直接將異常拋給使用者,那麼我們可以在@HystrixCommand註解中新增忽略異常,如下:

@HystrixCommand(fallbackMethod = "error1",ignoreExceptions = ArithmeticException.class)
public Book test2() {
    int i = 1 / 0;
    return restTemplate.getForObject("http://HELLO-SERVICE/getbook1", Book.class);
}

public Book error1(Throwable throwable) {
    System.out.println(throwable.getMessage());
    return new Book("百年孤獨", 33, "馬爾克斯", "人民文學出版社");
}

此時執行結果如下:

這裡寫圖片描述

這裡的實現原理很簡單,因為有一個名叫HystrixBadRequestException的異常不會進入到服務降級方法中去,當我們定義了ignoreExceptions為ArithmeticException.class之後,當丟擲ArithmeticException異常時,Hystrix會將異常資訊包裝在HystrixBadRequestException裡邊然後再丟擲,此時就不會觸發服務降級方法了。

OK,服務降級與異常處理我們就先說到這裡,有問題歡迎留言討論。

更多JavaEE資料請關注公眾號:

這裡寫圖片描述