通俗易懂的 Dubbo 教程(九):服務降級

什麼是服務降級?

當服務器壓力比較大的時候,我們可以通過服務降級,屏蔽掉一些非關鍵服務,給它們定義一個降級後的返回策略,從而降低核心業務的壓力。

通俗的說,服務降級就是在遠程調用失敗(例如超時)之後,直接採用降級措施,返回一個我們已經定義好的提示。例如,在12306搶票高峯時,明明票還有,但查詢列表總是空的,過了高峯之後再次查詢,又會恢復正常,這可能是因爲超時或者網絡問題導致查詢失敗,最後不得不採用了服務降級進行處理,給我們返回一個已經定義好的值。

如何實現服務降級

Dubbo 中有一個 mock 的配置,我們可以通過這個配置實現服務降級。其中,mock 的配置有兩種:

  1. 通過 boolean 值指定是否實行服務降級,其中默認爲 false,當配置爲 true 時,缺省通過在服務名後面加上 Mock 後綴的類來指定降級後的返回值
  2. 直接 return null,統一返回空

需要注意的是,mock 只會在非業務異常的時候執行,比如超時,又或者是網路異常。

測試

首先我們來看一下不做服務降級會是什麼後果,我們在服務提供者中故意令其超時,由於 Dubbo 默認超時時間爲1s,我們就令其睡眠兩秒,代碼如下:

package edu.szu.producer.serviceImpl;

import com.alibaba.dubbo.config.annotation.Service;
import edu.szu.api.service.NameService;
import org.springframework.stereotype.Component;

@Component
@Service
public class NameServiceImpl implements NameService {

    @Override
    public String updateName(String name) {
        //讓其超時
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "遠程調用的值:" + name;
    }
}

然後運行服務提供者與服務消費者,果不其然,直接報錯。

在這裏插入圖片描述
在這裏插入圖片描述

然後我們添加 return null 的降級設置,代碼如下,看看其效果

package edu.szu.consumer.serviceImpl;

import com.alibaba.dubbo.config.annotation.Reference;
import edu.szu.api.service.NameService;
import edu.szu.consumer.service.ChangeService;
import org.springframework.stereotype.Component;

@Component
public class ChangeServiceImpl implements ChangeService {

    //定義服務降級的策略:直接返回空
    @Reference(mock = "return null")
    NameService nameService;

    @Override
    public String change(String name) {
        return nameService.updateName(name);
    }
}

顯然它會直接返回空,這需要我們做進一步的處理。需要注意的是,當我們將 mock 設置爲 return null 時,它不會進行遠程調用,而是直接返回一個空就行了。
在這裏插入圖片描述
在這裏插入圖片描述
在某些情況下,直接返回空對我們的用戶不太友好,這時我們可以給用戶返回一個我們之前定義好的值。首先我們在 api 模塊中指定一個服務降級的處理策略,其中這個處理類名缺省爲在服務名上加上 Mock 後綴,且應該與服務接口在同路徑下。

package edu.szu.api.service;

public class NameServiceMock implements NameService {

    //定義服務降級的返回值
    @Override
    public String updateName(String name) {
        return "服務降級了!";
    }
}

然後在消費者中配置 mock 屬性爲 true。

package edu.szu.consumer.serviceImpl;

import com.alibaba.dubbo.config.annotation.Reference;
import edu.szu.api.service.NameService;
import edu.szu.consumer.service.ChangeService;
import org.springframework.stereotype.Component;

@Component
public class ChangeServiceImpl implements ChangeService {

    //定義服務降級的策略
    @Reference(mock = "true")
    NameService nameService;

    @Override
    public String change(String name) {
        return nameService.updateName(name);
    }
}

然後我們發起一次遠程調用,由於調用超時,顯然是失敗的,但由於我們進行了服務降級,會返回我們指定的返回值。

在這裏插入圖片描述
另外,該方法與直接 return null 不同的是,如果我們的遠程調用成功了,不會執行服務降級,會返回遠程調用的結果,而 return null 事實上根本不進行遠程調用就直接返回空了。

進階

當然,我們也可以通過 Admin 控制檯來實現服務降級。
在這裏插入圖片描述
我們發現對服務可以進行屏蔽與容錯操作,其中,屏蔽表示對服務不發起遠程調用,直接返回空就行了;而容錯則表示在對該服務的方法調用失敗後,再返回空,這兩個是不同的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章