服务网格 ASM(Service Mesh)的宽松泳道能力可以帮助用户实现在一个全量版本的基础上部署多套非全量环境。但在一些场景中,调用链路上存在消息队列,而ASM暂时还不支持消息队列协议,因此需要进行一些适配工作,以使得流量标签能够在消息队列中传递。本文介绍如何在宽松泳道中适配消息队列。
使用前提
在宽松泳道中使用消息队列,需要确保消息队列和应用满足以下要求。
消息队列
需要支持在消息中设置自定义元数据。
需要消费者支持指定特征进行过滤,只消费携带该指定特征的消息。
应用部署
在消费者主动拉取的消息队列中,由于消费者无法感知泳道相关的服务发现信息,为了确保消息被正确消费,需要确保在任意泳道中合法部署消费者和生产者,如下图:
合法部署:在一条泳道中,消息队列的生产者和消费者要么同时存在,要么同时不存在。
不合法部署:泳道中存在单独的生产者或消费者。
适配方案
消息队列生产者将泳道标签写入消息
在适配时,我们需要请求链路中的请求即使经过了消息队列,也可以维持泳道特征,泳道中应用产生的消息才可以被正确的消费者消费,同时消费者可以将消息中携带的特征还原到发送给上游的请求中。因此,生产者应用APP-B在写入消息队列时,需要将应用所在泳道信息和下游请求中携带的泳道标签一同写入到消息中。同时,消费者的消费过滤条件字段也需要包含应用所在泳道的信息,如下图。
应用所在泳道:即过滤key。由于应用所在的泳道由其工作负载携带的标签决定,因此通过读取应用标签(可以通过环境变量将标签值暴露给应用)可以获取到应用所在的泳道。
下游请求中携带的泳道标签:在经过网关引流后,网关发出的请求中会携带泳道的标识,用于网格代理将请求路由到正确的泳道中,ASM会通过请求头
x-asm-prefer-tag
在整个HTTP调用链路上透传该标识。
消息队列消费者按照所在泳道消费消息
您应该通过配置使消费者只订阅当前所在泳道的过滤key,使得消息队列中的消息能够被正确消费。
消息应用已部署到泳道v1和v2中:可以看到,两条泳道都进行了全量部署,APP-C(v1)消费过滤key为v1的消息,最终将消费由应用APP-B(v1)生产的消息。APP-C(v2)消费过滤key为v2的消息,最终消费由应用APP-B(v2)生产的消息。
消息应用未在泳道v2中部署:生产者和消费者部署在v1泳道,泳道v2则只部署了APP-A(v2)和APP-C(v2)。当APP-A(v2)收到请求后,由于APP-B未部署v2版本,因此ASM宽松泳道将消息路由至APP-B(v1),因此,APP-B(v1)无论接收到来自哪个泳道的消息,都将过滤key写为其所在泳道(v1)的标签值,以确保其可以被APP-C(v1)消费。APP-C(v1)消费消息后,将消息中携带的用到标识取出,使消息再转发给APP-D时,可以将泳道标识为v2的消息,转发给APP-D(v2)。
消费者应用将消息中获取的泳道标识写入发出的请求
如果消费者应用不是调用链的最终环节,即该应用在消费消息后还需要进一步调用其他应用,则需要将消息中携带的泳道标识写入到所有发出的消息中,以便ASM网格代理能利用标识进行后续的请求路由。
经过适配后,消费者应用会为发出的请求添加请求头x-asm-prefer-tag
,并将其值设置为从消息队列消费的消息中携带的泳道标识。 当请求经过ASM网格代理时,ASM网格代理会根据x-asm-prefer-tag
请求头的值,将请求路由至正确的泳道。