重試
什麼是重試
重試就是在調用失敗時,會再次調用,如果在配置的調用次數內都失敗,則認爲此次請求異常,會拋出一個異常。
Dubbo 在調用服務失敗後,會默認重試兩次。Dubbo 的路由機制確保會將超時的請求路由到其他機器上,而不是本機重試,所以 Dubbo 的重試機制也能一定程度的保證服務的質量。
測試
我們先將服務提供者修改一下,故意讓其超時,然後運行 producer 和 consumer 兩個模塊。
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) {
System.out.println("updateName 函數開始運行");
//故意讓其超時
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "修改後的名稱:" + name;
}
}
在瀏覽器輸入 http://localhost:8081/change/HelloDubbo ,遠程調用服務提供者提供的服務,結果如下:
在服務提供者的輸出中我們可以發現這個函數確實被調用了三次,證明除了一開始的第一次調用之外,還重試了兩次,即重試機制的默認缺省值爲2次。
然後我們修改一下重試次數,在消費者的配置中將其修改爲1次。
#設置重試次數爲1次
dubbo.consumer.retries=1
再次啓動兩個模塊,可以發現,函數只執行了兩次(初始一次+重試一次),證明我們的重試設置生效了。
注意
只有在冪等方法上才能使用重試機制,在非冪等方法上不能使用重試。那麼,什麼是冪等方法呢?其實,只要多次運行方法所產生的最終效果是一致的,就可以被稱爲冪等方法。
本地存根
什麼是本地存根
在消費者遠程調用服務提供者的服務實現之前,如果我們需要做一些參數驗證、緩存、小功能之類的,需要滿足要求再調用服務提供者提供的遠程服務,這個功能可以通過本地存根來實現。
我們可以將本地存根理解爲預處理信息。本地存根可以在提供者中實現,也可以在消費者中實現,如果在消費者中已經實現了本地存根,那麼提供者的將不起作用。
實現
我們選擇在 api 層開發本地存根
編寫本地存根代碼
package edu.szu.api.serviceStub;
import edu.szu.api.service.NameService;
public class NameServiceStub implements NameService {
private final NameService nameService;
// 構造函數傳入真正的遠程代理對象
public NameServiceStub(NameService nameService){
this.nameService = nameService;
}
@Override
public String updateName(String name) {
System.out.println("執行本地存根");
try {
if(name.equals("Tony")) return "返回一個本地存根";
return nameService.updateName(name);
} catch (Exception e) {
return "返回一個本地存根";
}
}
}
然後我們需要在消費者中指定本地存根的路徑,一個本地存根的功能就實現了。
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(stub = "edu.szu.api.serviceStub.NameServiceStub")
NameService nameService;
@Override
public String change(String name) {
return nameService.updateName(name);
}
}
測試
我們首先在瀏覽器中輸入 http://localhost:8081/change/Tony,遠程調用服務提供者提供的服務,結果如下:
在控制檯顯示如下:
顯然我們的本地存根生效了。