服務網格的可觀測性能力是通過Sidecar實現的,對於業務服務源代碼來說是近零侵入的。可觀測性包括數據採集、數據存儲、數據展示和聚合分析。主要有三個維度:Metrics、Logging、Tracing,分別用於可聚合數據、離散事件、請求鏈路的可觀測性。相應地,阿里雲生態下,ASM打通了ARMS(https://www.aliyun.com/product/arms)、Log Service(https://www.aliyun.com/product/sls)、TracingAnalysis(https://www.aliyun.com/product/xtrace),供用戶使用服務網格的可觀測性能力。
本篇只涉及請求鏈路,這個維度最容易展示VM中非容器應用網格化帶來的增益,以拋磚引玉。
1 近零侵入
本篇示例容器中的微服務源代碼依然使用http_springboot_demo。拋開雲原生,單看這個springboot開發的微服務,如果要實現全鏈路請求的採集,需要有一行主動打點的日誌,維護並記錄requestId
作為全鏈路唯一鍵的請求和響應信息。這個信息由日誌採集agent上報,然後由日誌系統根據requestid
提供查詢和聚合。代碼示意如下:
@GetMapping(path = "/hello/{msg}")
public String sayHello(@PathVariable String msg) {
String url = "http://" + HTTP_HELLO_BACKEND + ":8001/hello/" + msg;
String backServiceResult = helloService.sayHello(url);
String result = HELLO + " " + msg;
log.info("打點日誌...")
return result + backServiceResult;
}
public String sayHello(String url) {
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
...
這個微服務網格化後,微服務源代碼不再需要主動打點,相應地也無需維護全鏈路唯一鍵。這些工作Sidecar都已經實現了,而且是基於CNCF雲原生生態下的OpenTracing(/OpenTelemetry)標準實現的,無論從專業性還是標準上,都優於業務代碼自己打點。而這個『近零侵入』的地方就是“propagate tracing headers”——需要業務代碼傳遞如下header到下游。僅此而已。代碼示意如下:
@GetMapping(path = "/hello/{msg}")
public String sayHello(@PathVariable String msg, @RequestHeader Map<String, String> headers) {
String url = "http://" + HTTP_HELLO_BACKEND + ":8001/hello/" + msg;
String backServiceResult = helloService.sayHello(url, headers);
String result = HELLO + " " + msg;
return result + backServiceResult;
}
上面這段代碼,較之前述一段,少了第6行主動打點,多了RequestHeader
參數。傳遞給下游的代碼示意如下:
public String sayHello(String url, Map<String, String> headers) {
Map<String, String> tracingHeaders = buildTracingHeaders(headers,
"x-request-id",
"x-b3-traceid",
"x-b3-spanid",
"x-b3-parentspanid",
"x-b3-sampled",
"x-b3-flags",
"x-ot-span-context");
Request request = new Request.Builder()
//propagate tracing headers
.headers(Headers.of(tracingHeaders))
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
之所以說是『近零侵入』是因為RequestHeader
參數在多數業務代碼中本身就存在,就算不存在也可以直接從spring容器context中直接拿到,因此侵入的代價就是構造並傳遞上面代碼段中的header map。而這帶來的好處是省去了主動打點代碼及其維護成本。
2 搭建實驗環境
本篇實驗繼續使用第2篇的組件拓撲,如下圖所示。本篇的重點是確認完整的端到端鏈路的可追蹤性。
由於Sidecar負責上報鏈路追蹤的數據,業務代碼無需感知具體的鏈路追蹤系統。ASM支持阿里雲鏈路追蹤產品TracingAnalysis,也支持用戶自建Zipkin。對於虛擬機的網格化鏈路追蹤而言,只需在啟動參數中提供鏈路追蹤系統即可。余文詳述。
TracingAnalysis
由於ASM已經在數據平面創建了TracingAnalysis相關的POD,我們只需為虛擬機提供一個鏈路追蹤服務即可。示意如下:
apiVersion: v1
kind: Service
metadata:
labels:
app: tracing
component: zipkin
name: zipkin-slb
namespace: istio-system
spec:
ports:
- name: zipkin
port: 9411
protocol: TCP
targetPort: 9411
selector:
app: tracing
component: zipkin
type: LoadBalancer
k get svc zipkin-slb -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
zipkin-slb LoadBalancer 172.19.10.62 39.107.229.139 9411:31170/TCP 178m
通過如下命令模擬dns將鏈路追蹤服務提供給虛擬機:
zipkin_clusterIp=$(k get svc zipkin-slb -n istio-system | grep zipkin | awk -F ' ' '{print $4}')
echo "$zipkin_clusterIp zipkin.istio-system" >dns_record
VMS=("$VM_PUB_1" "$VM_PUB_2" "$VM_PUB_3")
for vm in "${VMS[@]}"; do
ssh root@"$vm" "sed -i '/zipkin.istio-system/d' /etc/hosts"
ssh root@"$vm" "cat >> /etc/hosts" <dns_record
done
rm -rf dns_record
最後在VM中向/var/lib/istio/envoy/sidecar.env
追加一行:
ISTIO_AGENT_FLAGS="--zipkinAddress zipkin.istio-system:9411 --serviceCluster vm1-hello2-en"
Zipkin
自建zipkin的方式參見文檔:向自建系統導出ASM鏈路追蹤數據,其他步驟與TracingAnalysis一致。
實驗環境
與第2篇類似,通過如下腳本啟動本篇實驗實例的相關各組件:
sh asm/ack.deploy.sh
sh asm/asm.deploy.sh
sh asm/asm_traffic_shift.sh
sh asm/dns.fake.sh
3 鏈路追蹤驗證
使用如下腳本發起端到端調用:
IP=$(k -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
for i in {1..1000}; do
resp=$(curl -s "$IP":8008/hello/eric)
echo "$resp" >>test_traffic_shift_result
done
全局拓撲
TracingAnalysis提供了全局拓撲,通過這個拓撲圖,我們可以一目瞭然地看到VM中的應用和ack容器中的POD一樣,作為端到端鏈路上的一個endpoint存在。示意如下。
Tracing
登錄TracingAnalysis或者自建zipkin系統查看tracing。如下圖所示,VM中的Sidecar上報了hello2應用鏈路的inbound
和outbound
數據,與hello1/hello3 POD形成完整的調用鏈路。
全鏈路聚合
通過TracingAnalysis的全鏈路聚合,可以完整地看到hello2的三個版本vm1-hello2-en
/vm2-hello2-fr
/vm3-hello2-es
鏈路追蹤數據的聚合信息。
到此,基於ASM的POD和VM可觀測性實踐驗證完畢。通過本篇實驗,我們可以看到,非容器應用網格化後直接具備了強大的服務可觀測性能力。
尾
由於時間和精力關係,本系列到此結束。希望在雲原生之下,服務網格能為我們的產品帶來一些不同和驚喜。