4. 接口协议选型:HTTP/REST、gRPC、WebSocket 对比

说到接口协议选型,很多团队容易陷入「技术狂热」或「路径依赖」。我个人习惯先把场景想清楚,再选协议。日志采集这个场景,说白了就是三个核心诉求:可靠送达、低延迟、不丢数据。

你想想看,一个审计日志丢了,可能意味着合规检查过不了。所以选协议这事,不能只看性能数据,得把可靠性放在第一位。

4.1 三种协议的核心差异

先看一张总对比表。这张表我每次做架构评审都会贴出来,它能帮团队快速对齐认知。

维度 HTTP/REST gRPC WebSocket
通信模型 请求-响应(同步) 请求-响应/流式(双向) 全双工(异步)
数据序列化 JSON/XML(文本) Protobuf(二进制) JSON/自定义(文本或二进制)
连接开销 高(每次新建TCP) 中(长连接 + HTTP/2) 低(一次握手,持续复用)
流式支持 不支持(需轮询/长轮询) 原生支持(Server/Client/Bidi) 原生支持(双向流式)
生态成熟度 极高(所有语言/框架) 高(CNCF项目,跨语言) 中(浏览器兼容性有限)
适用场景 简单查询、CRUD、开放API 微服务间高性能调用、流式日志 实时推送、高频低延迟通信

这张表里有一个关键点:WebSocket的连接开销最低,但状态管理最复杂。我在一个金融项目中就吃过这个亏——用了WebSocket做日志采集,结果连接粒度过细,服务端维护了20万个长连接,内存直接撑爆了。

4.2 HTTP/REST:接地气但不够「聪明」

HTTP/REST的优势在于「简单」。只要懂HTTP,谁都能调。但这恰恰也是它的短板。

举个例子:采集端要上报100条日志。用REST的话,要么发100次POST,要么包一个大JSON一次性提交。第一种方式,连接开销巨大;第二种方式,中间一旦断了,100条全丢。

核心结论:REST适合低频、小数据量的日志上报,或者作为兜底方案。频率超过每秒1000条时,HTTP的握手开销会让你抓狂。

我曾经帮一个客户排查日志延迟问题,发现他们用短连接每5秒发一次POST。高峰期,Nginx直接每秒新建3000个连接,CPU烧到90%。后来换成连接池+批量提交,CPU直接降到30%。

4.3 gRPC:高性能但「重」

gRPC的优势很明显:Protobuf的序列化效率高,HTTP/2的多路复用让单连接可以承载大量请求。对日志采集来说,它的流式接口是神来之笔。

看一个典型的gRPC日志服务定义:

service LogCollector {
  // 单条上报(简单但低效)
  rpc Log (LogEntry) returns (Ack);

  // 批量流式上报(推荐做法)
  rpc LogStream (stream LogEntry) returns (Summary);
}

这里有个设计要点:LogStream 是单向流(客户端流),采集端可以持续往一个TCP连接里塞日志,服务端只需要回应一个最终的汇总确认。我去年做的一个物联网日志平台,日均10亿条日志,就是用这个模式扛下来的。

但gRPC有个坑:调试困难。二进制协议没法像REST那样用curl直接测。我在项目中遇到过,开发环境一切正常,一上生产发现gRPC的keepalive参数没配好,连接频繁断开又重连,日志堆积了好几百万条。

我的建议:如果团队对Protobuf不熟,或者没有好的gRPC调试工具(如grpcurl、BloomRPC),慎用。gRPC的「快」是给有准备的人的。

4.4 WebSocket:实时但「粘手」

WebSocket能让服务端主动推送数据,这对日志采集来说是双刃剑。

好处是:日志来了就能推,延迟在毫秒级。坏处是:你没法控制服务端的推送节奏。

我曾经设计过一个实时审计看板,要求日志延迟小于100ms。团队一开始选了WebSocket,结果采集端日志量突然暴涨,服务端来不及处理,直接把WebSocket连接上的流控窗口打爆了。后来我们加了一层背压机制(backpressure),让采集端在推送前先检查服务端队列深度,这才稳住。

特别注意:WebSocket没有标准的流控协议。你需要自己实现限速、重连、心跳、会话恢复。别小看这些「脏活」——我见过一个项目,WebSocket断线重连后,客户端没做去重,服务端收到了50GB的重复日志。

再说一个浏览器兼容性问题。很多内网环境的浏览器是旧版IE或Chrome,WebSocket的支持程度参差不齐。如果你的采集端是浏览器,那还是老老实实走HTTP吧。

4.5 我的选型决策框架

说了这么多,到底怎么选?我归纳了一个三步决策法,在多个项目中验证过。

  1. 看数据量:单台采集节点每秒少于1000条 → HTTP/REST够用。每秒1000~10000条 → gRPC。每秒上万条且要求低延迟 → 考虑WebSocket或gRPC的流式模式。
  2. 看网络条件:内网高带宽 → 三种都行,优先gRPC。公网跨机房 → 首选gRPC(二进制小、连接复用)。弱网环境(丢包率高) → 需要自定义可靠传输层,HTTP/REST配合重试机制更稳妥。
  3. 看团队能力:团队熟悉Java+Spring → REST最顺手。团队有C++/Go基础 → gRPC发挥空间大。团队小而全栈 → 别碰WebSocket,维护成本太高。

这里画一个决策流程图,我希望大家在评审时直接拿这张图去对。

日志采集接口协议选型决策流程 日均日志量 > 1亿条? 延迟 < 200ms? 是 是 否 WebSocket + 背压 gRPC 流式 否 单条日志 > 10KB? 是 否 HTTP/REST 批量 gRPC 单条/流式 确定候选协议,进入下一节 (安全评估 & 性能压测)

这张图我用了很多次。你只要顺着回答三个「是/否」问题,就能快速锁定候选协议。注意,这只是「初筛」,后面的安全性评估和压测才是重头戏。

4.6 协议混搭是一种思路

最后聊点实际的。大部分系统不会只用一种协议。我见过一个成熟的审计日志系统,它用了三层协议:

  • 采集层到缓冲层:gRPC流式,追求高性能低时延。
  • 缓冲层到存储层:HTTP REST批处理,因为数据已经做了本地缓冲,不要求实时。
  • 监控告警层:WebSocket推送,让运维人员能在仪表盘上看到实时日志流量。

这其实是一种「协议路由」的架构思维。不要死守一种协议,让数据在不同的生命周期阶段走最合适的通道。

一个小习惯:我在系统设计文档里,每个接口旁边都会标注「协议 + 安全机制」,例如:gRPC/TLS + 双向认证。这样做评审时,一眼就能看出哪个接口的防护薄弱。

协议选型没有银弹。我见过用HTTP REST扛住100万QPS的团队,也见过WebSocket实现不当导致线上故障的案例。关键不在协议本身,而在于你是否把协议的特性吃透了,并且为它的短板做好了防御设计。