写点什么

「微服务的细节」—— 如何支持多协议?

作者:袁世超
  • 2023-05-09
    北京
  • 本文字数:1066 字

    阅读完需:约 3 分钟

在实际场景中,你有很多理由需要在微服务体系中支持多协议,如何支持呢?

1. 端口偏移

设想一个场景

  • 你的微服务体系中已经有一套统一的 RPC 协议,

  • 但是不能满足新的需求了,你需要引入一种全新的协议,并且无法在当前协议上进行扩展,

那么就可以采用端口偏移的方式。


实现方式也很简单,例如当前协议的端口号为 port,那么就可以约定 port+5 为新协议的端口号。

2. 协议探测

设想一个场景

  • 你的微服务体系比较乱,不同的业务线使用不同的 RPC 协议,

  • 但是不同业务线互调的需求越来越多了,你需要提供一套统一的体系来治理这个问题,

那么就可以在统一的框架中采用协议探测的方式。


brpc是个典型案例,记得戈君老师在一次直播中也谈到:同一端口多协议支持这一特性为 brpc 在百度内的推广扫清了很多障碍。


实现方式在官方文档中也有清晰的描述:

brpc server 一个端口支持多种协议,大部分时候这对部署和运维更加方便。由于不同协议的格式大相径庭,严格地来说,一个端口很难无二义地支持所有协议。出于解耦和可扩展性的考虑,也不太可能集中式地构建一个针对所有协议的分类器。我们的做法就是把协议归三类后逐个尝试:

  • 第一类协议:标记或特殊字符在最前面,比如baidu_std,hulu_pbrpc 的前 4 个字符分别是 PRPC 和 HULU,解析代码只需要检查前 4 个字节就可以知道协议是否匹配,最先尝试这类协议。这些协议在同一个连接上也可以共存。

  • 第二类协议:有较为复杂的语法,没有固定的协议标记或特殊字符,可能在解析一段输入后才能判断是否匹配,目前此类协议只有 http。

  • 第三类协议:协议标记或特殊字符在中间,比如 nshead 的 magic_num 在第 25-28 字节。由于之前的字段均为二进制,难以判断正确性,在没有读取完 28 字节前,我们无法判定消息是不是 nshead 格式的,所以处理起来很麻烦,若其解析排在 http 之前,那么<=28 字节的 http 消息便可能无法被解析,因为程序以为是“还未完整的 nshead 消息”。

考虑到大多数链接上只会有一种协议,我们会记录前一次的协议选择结果,下次首先尝试。对于长连接,这几乎把甄别协议的开销降到了 0;虽然短连接每次都得运行这段逻辑,但由于短连接的瓶颈也往往不在于此,这套方法仍旧是足够快的。在未来如果有大量的协议加入,我们可能得考虑一些更复杂的启发式的区分方法。


代码也写的很优雅:https://github.com/apache/brpc/blob/master/src/brpc/input_messenger.cpp#L76-L167

3. 元数据路由

如果是公有云产品,例如 MSE 和 TSF,需要考虑标准化和兼容性,那么可以基于元数据路由来实现。


在实例注册时将支持的“协议”和“端口”作为“元数据”带上来,在调用的时候通过元数据路由筛选出支持该协议的实例。

发布于: 刚刚阅读数: 4
用户头像

袁世超

关注

还未添加个人签名 2017-11-30 加入

还未添加个人简介

评论

发布
暂无评论
「微服务的细节」—— 如何支持多协议?_微服务_袁世超_InfoQ写作社区