1 服務治理
就是看看你有沒有服務治理的思想,因為這是做過複雜微服務的人肯定會遇到的問題。
1.1 調用鍊路自動生成
現在流行的微服務架構由大量服務組成。服務一多,一旦出問題就難以定位,這時就需要基于Dubbo做的分布式系統中,自動記錄各服務間的調用,然後自動生成各服務間的依賴關系和調用鍊路生成一張圖顯示出來。
服務A => 服務B => 服務E
=> 服務F
=> 服務C
=> 服務G
=> 服務D

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季-中華石杉老師》