服务网格GRPC协议多种编程语言实践-5.GRPC协议Headers网格实践

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 在服务网格的流量管理和可观测性实现上,Headers发挥着非常关键的作用。相比而言,HTTP协议的Headers实现较为容易,因为HTTP是同步阻塞式的请求响应模式,可以很容易在GET/POST/UPDATE/DELETE方法中定义和使用读写Header的API。GRPC协议的Headers则要复杂一些,各种编程语言在4种不同通信模型中,读写Header的形式的差异化很大,同时还要考虑流式和异步的编程实现。本篇首先介绍4种编程语言的Headers编程实践,然后讲述在服务网格实践中,GRPC协议Headers的两个重要实践:流量管理和可观测性。

在服务网格的流量管理和可观测性实现上,Headers发挥着非常关键的作用。相比而言,HTTP协议的Headers实现较为容易,因为HTTP是同步阻塞式的请求响应模式,可以很容易在GET/POST/UPDATE/DELETE方法中定义和使用读写Header的API。GRPC协议的Headers则要复杂一些,各种编程语言在4种不同通信模型中,读写Header的形式的差异化很大,同时还要考虑流式和异步的编程实现。

本篇首先介绍4种编程语言的Headers编程实践,然后讲述在服务网格实践中,GRPC协议Headers的两个重要实践:流量管理和可观测性。

1 GRPC协议Headers编程实践

服务端获取Headers

GRPC通信模型编程语言 Java Go NodeJs Python
基本方法 实现拦截器ServerInterceptor接口的interceptCall(ServerCall<ReqT, RespT> call,final Metadata m,ServerCallHandler<ReqT, RespT> h)方法,通过String v = m.get(k)获取header信息,get方法入参类型为Metadata.Key<String> metadata.FromIncomingContext(ctx)(md MD, ok bool)MD是一个map[string][]string call.metadata.getMap(),返回值类型是[key: string]: MetadataValueMetadataValue类型定义为string/Buffer context.invocation_metadata(),返回值类型为2-tuple数组,2-tuple的形式为('k','v'),使用m.key, m.value遍历获取键值对
Unary RPC 对Headers无感知 在方法中直接调用metadata.FromIncomingContext(ctx),上下文参数ctx来自Talk的入参 在方法内直接调用call.metadata.getMap() 在方法内直接调用context.invocation_metadata()
Server streaming RPC 同上 在方法中直接调用metadata.FromIncomingContext(ctx),上下文参数ctx从TalkOneAnswerMore的入参stream中获取:stream.Context() 同上 同上
Client streaming RPC 同上 在方法中直接调用metadata.FromIncomingContext(ctx),上下文参数ctx从TalkMoreAnswerOne的入参stream中获取:stream.Context() 同上 同上
Bidirectional streaming RPC 同上 在方法中直接调用metadata.FromIncomingContext(ctx),上下文参数ctx从TalkBidirectional的入参stream中获取:stream.Context() 同上 同上

客户端发送Headers

GRPC通信模型编程语言 Java Go NodeJs Python
基本方法 实现拦截器ClientInterceptor接口的interceptCall(MethodDescriptor<ReqT, RespT> m, CallOptions o, Channel c)方法,实现返回值类型ClientCall<ReqT, RespT>start((Listener<RespT> l, Metadata h))方法,通过h.put(k, v)填充header信息,put方法入参k的类型为Metadata.Key<String>v的类型为String metadata.AppendToOutgoingContext(ctx,kv ...) context.Context metadata=call.metadata.getMap()
metadata.add(key, headers[key])
metadata_dict = {}
变量填充metadata_dict[c.key] = c.value
最终转为list tuple类型list(metadata_dict.items())
Unary RPC 对Headers无感知 在方法中直接调用metadata.AppendToOutgoingContext(ctx,kv) 在方法内直接使用基本方法 在方法内直接使用基本方法
Server streaming RPC 同上 同上 同上 同上
Client streaming RPC 同上 同上 同上 同上
Bidirectional streaming RPC 同上 同上 同上 同上

Propaganda Headers

由于链路追踪需要将上游传递过来的链路元数据透传给下游,以形成同一条请求链路的完整信息,我们需要将服务端获取的Headers信息中,和链路追踪相关的Headers透传给向下游发起请求的客户端。这就是"Propaganda Headers"的概念。

如上所述,除了Java语言的实现,其他语言的通信模型方法都对header有感知,因此可以将"服务端读取-传递-客户端发送"这三个动作顺序地在4种通信模型方法内部实现。

Java语言读取和写入Headers是通过两个拦截器分别实现的,因此Propaganda Headers无法在一个顺序的流程里实现,且考虑到并发因素,以及只有读取拦截器知道链路追踪的唯一ID,我们无法通过最直觉的缓存方式搭建两个拦截器的桥梁。

那么只能借助上下文了。幸好Java语言的实现提供了一种Metadata-Context Propagation的机制。

propagation.png

在服务器拦截器读取阶段,通过ctx.withValue(key, metadata)将Metadata/Header存入Context,其中keyContext.Key<String>类型。然后在客户端拦截器中,通过key.get()将Metadata从Context读出,get方法默认使用Context.current()上下文,这就保证了一次请求的Headers读取和写入使用的是同一个上下文。

有了Propaganda Headers的实现,基于GRPC的链路追踪就有了机制上的保证。

2 网格拓扑

完成GRPC的Headers处理后,我们进入部署和验证目录tracing。该目录下包含4种编程语言的部署脚本。我们以go版本为例,执行如下脚本进行部署和验证。

cd go
# 部署
sh apply.sh
# 验证
sh test.sh

部署后的服务网格拓扑如下图所示。

grpc-tracing-topology.png

3 流量转移

在VirtualService中通过定义Header键值的匹配条件,可以实现根据请求动态地进行流量转移。如果再结合前一篇中讲述的按API切流、按版本切流的实践,就可以完成应用级的精细化流量管理

进入服务网格(ASM)实例,新建VirtualService,将如下内容复制保存。这个VirtualService定义了Header中server-version=go的请求100%流量路由到go版本服务。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  namespace: grpc-best
  name: grpc-server-vs
spec:
  hosts:
    - "*"
  gateways:
    - grpc-gateway
  http:
    - match:
      - headers:
          server-version:
            exact: go
      route:
        - destination:
            host: grpc-server-svc
            subset: v2
          weight: 100

4 链路追踪

进入服务网格(ASM)实例,在功能设置中勾选启用链路追踪,采样方式选择阿里云XTrace。

在本地执行如下请求脚本,向Ingressgateway发起多次请求。

USER_CONFIG=~/shop_config/ack_bj
alias k="kubectl --kubeconfig $USER_CONFIG"
INGRESS_IP=$(k -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

docker run -d --name grpc_client_node -e GRPC_SERVER="${INGRESS_IP}" registry.cn-beijing.aliyuncs.com/asm_repo/grpc_client_node:1.0.0 /bin/sleep 3650d
client_node_container=$(docker ps -q)

echo "Test in a loop:"
for i in {1..100}; do
  docker exec -e GRPC_SERVER="${INGRESS_IP}" -it "$client_node_container" node mesh_client.js ${INGRESS_IP} 6666
done

在服务网格(ASM)实例的左侧菜单中点击"链路追踪",查看请求链路信息。如下图所示,完整的链路包括:本地请求端-Ingressgateway-grpc-server-svc1-grpc-server-svc2-grpc-server-svc3

tracing_app_topology.png

tracing_app_waterfall.png

tracing_app_waterfall0.png

目录
相关文章
|
5天前
|
监控 负载均衡 数据安全/隐私保护
探索微服务架构下的服务网格(Service Mesh)实践
【5月更文挑战第6天】 在现代软件工程的复杂多变的开发环境中,微服务架构已成为构建、部署和扩展应用的一种流行方式。随着微服务架构的普及,服务网格(Service Mesh)作为一种新兴技术范式,旨在提供一种透明且高效的方式来管理微服务间的通讯。本文将深入探讨服务网格的核心概念、它在微服务架构中的作用以及如何在实际项目中落地实施服务网格。通过剖析服务网格的关键组件及其与现有系统的协同工作方式,我们揭示了服务网格提高系统可观察性、安全性和可操作性的内在机制。此外,文章还将分享一些实践中的挑战和应对策略,为开发者和企业决策者提供实用的参考。
|
12天前
|
运维 监控 负载均衡
探索微服务架构下的服务网格(Service Mesh)实践之路
【4月更文挑战第30天】 在现代云计算的大背景下,微服务架构以其灵活性和可扩展性成为众多企业转型的首选。然而,随着服务的激增和网络交互的复杂化,传统的服务通信模式已无法满足需求,服务网格(Service Mesh)应运而生。本文通过分析服务网格的核心组件、运作机制以及在企业中的实际应用案例,探讨了服务网格在微服务架构中的关键作用及其带来的变革,同时提出了实施过程中面临的挑战和解决策略。
|
13天前
|
运维 监控 负载均衡
探索微服务架构下的服务网格(Service Mesh)实践
【4月更文挑战第28天】 在现代云原生应用的后端开发领域,微服务架构已成为一种广泛采用的设计模式。随着分布式系统的复杂性增加,服务之间的通信变得愈加关键。本文将深入探讨服务网格这一创新技术,它旨在提供一种透明且高效的方式来管理、监控和保护微服务间的交互。我们将从服务网格的基本概念出发,分析其在实际应用中的优势与挑战,并通过一个案例研究来展示如何在现有的后端系统中集成服务网格。
|
7月前
|
监控 安全 Cloud Native
构建无缝的服务网格体验:分享在生产环境中构建和管理服务网格的最佳实践
构建无缝的服务网格体验:分享在生产环境中构建和管理服务网格的最佳实践
29 0
|
9月前
|
运维 Kubernetes Cloud Native
服务网格实施周期缩短 50%,丽迅物流基于阿里云 ACK 和 ASM 的云原生应用管理实践
通过本文介绍丽迅物流关于基于阿里云服务网格 ASM 如何加速企业业务云原生化进程的实践经验。
|
Prometheus 监控 Kubernetes
使用ASM网格拓扑观测多集群的流量控制与容灾场景
作为业内首个全托管Istio兼容的阿里云服务网格产品ASM,一开始从架构上就保持了与社区、业界趋势的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立。ASM产品是基于社区Istio定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了Istio组件与所管理的K8s集群的生命周期管理,使得架构更加灵活,提升了系统的可伸缩性。从2022年4月
ASM中GRPC/HTTP2流式传输场景的Sidecar资源占用调优
当应用使用GRPC流式传输时,数据经由Sidecar进行转发,由于Sidecar工作于7层,所以Sidecar会对GRPC消息元信息进行解析后在转发,在一些场景下(例如在单连接上建立大规模Stream)可能会造成Sidecar内存占用提升。本文将介绍Sidecar控制GRPC流式传输性能的相关参数和其作用机制,用户可以通过这些参数对Sidecar资源占用进行调整,已取得运行性能和资源消耗的平衡。S
153 0
ASM中GRPC/HTTP2流式传输场景的Sidecar资源占用调优
|
人工智能 自然语言处理 运维
站酷基于服务网格 ASM 的生产实践
随着站酷业务服务的持续改造,将持续基于阿里云服务网格 ASM 产品,获得更加丰富便捷的企业级特性,助力降本增效。
159 0
站酷基于服务网格 ASM 的生产实践
|
人工智能 自然语言处理 运维
站酷基于服务网格ASM的生产实践
随着站酷业务服务的持续改造,将持续基于阿里云服务网格 ASM 产品,获得更加丰富便捷的企业级特性,助力降本增效。
站酷基于服务网格ASM的生产实践
|
Kubernetes 安全 机器人
Lyft 微服务研发效能提升实践 | 3. 利用覆盖机制在预发环境中扩展服务网格
Lyft 微服务研发效能提升实践 | 3. 利用覆盖机制在预发环境中扩展服务网格
1200 0
Lyft 微服务研发效能提升实践 | 3. 利用覆盖机制在预发环境中扩展服务网格