服务网格的可观测性能力是通过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可观测性实践验证完毕。通过本篇实验,我们可以看到,非容器应用网格化后直接具备了强大的服务可观测性能力。
尾
由于时间和精力关系,本系列到此结束。希望在云原生之下,服务网格能为我们的产品带来一些不同和惊喜。