天天看點

阿裡面試官:聊聊基于Dubbo服務治理、服務降級以及重試原理?1 服務治理2 服務降級3 重試

1 服務治理

就是看看你有沒有服務治理的思想,因為這是做過複雜微服務的人肯定會遇到的問題。

1.1 調用鍊路自動生成

現在流行的微服務架構由大量服務組成。服務一多,一旦出問題就難以定位,這時就需要基于Dubbo做的分布式系統中,自動記錄各服務間的調用,然後自動生成各服務間的依賴關系和調用鍊路生成一張圖顯示出來。

服務A   => 服務B   => 服務E
                  => 服務F
       => 服務C
                  => 服務G
       => 服務D
      
阿裡面試官:聊聊基于Dubbo服務治理、服務降級以及重試原理?1 服務治理2 服務降級3 重試

1.2 服務通路壓力以及時長統計

需自動統計各個接口和服務之間的調用次數以及通路延時,而且要分成兩個級别:

  • 接口粒度

    每個服務的每個接口每天被調用多少次,TP50/TP90/TP99,三個檔次的請求延時分别是多少

  • 從入口開始

    一個完整的請求鍊路經過幾十個服務之後,完成一次請求,每天全鍊路走多少次,全鍊路請求延時的TP50/TP90/TP99,分别是多少

這些東西都搞定了之後,後面才可以來看目前系統的壓力主要在哪裡,來确定如何擴容和優化。

1.3 其他

  • 服務分層(避免循環依賴)
  • 調用鍊路失敗監控和報警
  • 服務鑒權
  • 每個服務的可用性的監控(接口調用成功率?幾個9?99.99%,99.9%,99%)

2 服務降級

涉及到複雜分布式系統中必備的一個話題,因為分布式系統互相來回調用,任何一個系統故障了,你不降級,直接服務雪崩。

比如服務A調用服務B,結果服務B挂了,服務A重試幾次調用服務B,還是不行,則直接降級,走備用邏輯,給使用者傳回響應。

public interface HelloService {

   void sayHello();
}
      
public class HelloServiceImpl implements HelloService {

    public void sayHello() {
        System.out.println("hello world......");
    }
}
      
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <dubbo:application name="dubbo-provider" />
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    <dubbo:protocol name="dubbo" port="20880" />
    <dubbo:service interface="com.javaedge.service.HelloService" ref="helloServiceImpl" timeout="10000" />
    <bean id="helloServiceImpl" class="com.zhss.service.HelloServiceImpl" />

</beans>
      
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <dubbo:application name="dubbo-consumer"  />

    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

    <dubbo:reference id="fooService" interface="com.test.service.FooService"  timeout="10000" check="false" mock="return null">
    </dubbo:reference>

</beans>
      

現在就是mock,如果調用失敗統一傳回null。

但可将mock修改為true,然後在跟接口同一個路徑下實作一個Mock類,命名規則:

接口名稱 + Mock      

然後在Mock類裡實作自己的降級邏輯:

public class HelloServiceMock implements HelloService {
    public void sayHello() {
    // 降級邏輯
    }
}
      

3 重試

3.1 失敗重試

分布式系統中網絡請求如此頻繁,要是因為網絡問題不小心失敗了一次,就需要重試。

consumer調用provider要是失敗了(比如抛異常),此時應該是可以重試的,或者調用逾時了也可以重試。

<dubbo:reference id="xxxx" interface="xx" check="true" 
    async="false" retries="3" timeout="2000"/>
      

某個服務的接口,要耗費5s,你這邊不能幹等着,你這邊配置了timeout之後,我等待2s,還沒傳回,我直接就撤了,不能一直在你這耗着

3.2 逾時重試

同上,如果不小心網絡慢一點,逾時了,又該如何重試呢。

如果是逾時了,timeout就會設定逾時時間;如果是調用失敗了自動就會重試指定的次數

結合具體業務場景設定這些參數

  • timeout

    一般設定為200ms,我們認為不能超過200ms還沒傳回

  • retries

    3次,設定retries,一般發生在讀請求時

    比如你要查詢某個資料,你可以設定retries,如果第一次沒讀到,報錯,重試指定的次數,嘗試再讀取2次。

參考

  • 《Java工程師面試突擊第1季-中華石杉老師》