WebSocket、TCP 与 QUIC:三个时代、三种哲学、三次架构抉择

本文档面向系统架构师、技术负责人和高级后端工程师。需要你静下来看,需要对数据包、状态机、字节流有一定概念。我会尽量讲得通透,把原理、场景、取舍摊开来看。


一、先看一张全貌图

先把这三者的层次关系和核心定位看清楚。你可以把这篇文章当作一个完整的知识索引,后面的所有内容都在这个框架里展开。

text

┌─────────────────────────────────────────────────────────────────────────────────┐
│                              架构师眼中的三种网络通信形态                          │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│      “马车”              “公路上的轿车”               “全地形越野车”             │
│      (基于原始TCP)       (WebSocket封装)               (QUIC,HTTP/3底层)       │
│                                                                                 │
│     类比:中国邮政        类比:开通了绿色通道的邮政     类比:货拉拉 + 军方加密    │
│           发一封信           允许对方随时敲门发信              自带多车厢           │
│           必须等回信                                  切换道路不需要换车         │
│                                                                                 │
│   OSI 第4层             OSI 第7层(实为应用层)            OSI 第4层(创新设计)     │
│   传输层原始协议         基于TCP构建的封装协议             基于UDP的传输协议       │
│                                                                                 │
│   核心约束:面向连接      核心价值:全双工                核心突破:多路流独立     │
│           可靠传输              长连接持久化                      0-RTT          │
│           字节流                HTTP兼容握手                    连接迁移         │
│           拥塞控制              帧边界保留                      内置TLS         │
│                                                                                 │
│   设计年代:1980s        设计年代:2011(RFC6455)          设计年代:2021(RFC9000) │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

这张图的用意不是三言两语把三个协议讲完,而是让你在开始深入之前,心中先有一个坐标系。下面会详细拆开每一层。


二、TCP(Transmission Control Protocol)——现代互联网的基石

2.1 它要解决什么问题

IP协议负责把数据包从主机A送到主机B,但路上丢包怎么办?顺序乱了怎么办?发得太快把接收方撑爆了怎么办?三个根本问题催生了TCP:

  1. 丢包怎么办? → 超时重传 + 快速重传

  2. 顺序乱了怎么办? → 序号与确认号机制

  3. 接收方处理不过来怎么办? → 滑动窗口 + 流量控制

  4. 整个网络都堵了怎么办? → 拥塞控制(慢启动、拥塞避免、快恢复)

图:TCP协议头结构(20字节固定头 + 选项)

text

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |          Source Port          |       Destination Port        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                        Sequence Number                        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                    Acknowledgment Number                      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |  Data |           |C|E|U|A|P|R|S|F|                           |
 | Offset| Reserved  |W|C|R|C|S|S|Y|I|        Window             |
 |       |           |R|E|G|K|H|T|N|N|                           |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |           Checksum            |         Urgent Pointer        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                    Options (if any) ...                       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                         Data ...                              |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

关键字段说明:Source/Destination Port(进程标识)、Sequence Number(发送序号)、Acknowledgment Number(确认序号,期望收到的下一个字节)、Data Offset(首部长度,单位4字节)、Window(滑动窗口大小,接收方能接受的字节数)、Checksum(校验和)、六个标志位(URG/ACK/PSH/RST/SYN/FIN)+ 三个现代标志位(NS/CWR/ECE)。

2.2 可靠传输的核心机制——三层保险

(1)确认应答与超时重传

TCP用序号标记每一个字节。A发出序号1001的报文,B收到后回复确认序号2001(表示1001及以前都收到了)。如果A在一定时间内没收到确认,判定丢包并重传。

一个真实示例:A发送数据报序号1001(包含100字节),B回复确认序号1101,A知道对方收到了1001~1100。

问题来了:最新的报文永远没有应答,它的可靠性无法保证,这是TCP的固有特性。

(2)快重传(Fast Retransmit)

不是等超时才重传,而是连续收到三个重复确认立即重传丢失的包。这是TCP演进的关键改进,能把恢复时间从RTO(几百毫秒)压缩到几十毫秒。

举例:A发了1、2、3、4、5。包2丢了,B收到3、4、5时都发ACK=2(期望收到包2)。A收到三次ACK=2,立即重传包2,不等超时。

(3)流量控制——滑动窗口

TCP连接每一方的接收缓冲区大小固定,接收端通告窗口大小,发送端不能超过这个窗口。Windows操作系统中的TCP窗口自动调优机制会自动调整窗口大小。

窗口不是固定的。A收到B的ACK报文,窗口从8192降为4096,A就知道慢下来。网络条件好了,窗口再涨上去。

2.3 三次握手与四次挥手的真正含义

三次握手——建立连接

text

Client                  Server
   |                      |
   |----- SYN=1,SEQ=x --->|  #1: 客户端请求建立连接
   |                      |
   |<--- SYN=1,ACK=1,     |  #2: 服务器确认并回应
   |     SEQ=y,ACK=x+1 ---|
   |                      |
   |----- ACK=1,         |  #3: 客户端确认
   |     SEQ=x+1,ACK=y+1->|
   |                      |

为什么不是两次?因为TCP是双向全双工,双方必须确认对方的接收能力。两次握手会让服务器无法确认客户端收到了自己的SYN+ACK,容易引发SYN洪水攻击——客户端只发第一个SYN就不回应,服务器持续挂起连接,耗尽资源。

四次挥手——断开连接

text

Client                  Server
   |                      |
   |----- FIN=1,SEQ=x --->|  #1: 客户端说"我没数据了"
   |                      |
   |<--- ACK=1,          |  #2: 服务器说"我知道"
   |     SEQ=y,ACK=x+1 ---|
   |                      |
   |<--- FIN=1,          |  #3: 服务器说"我也没了"
   |     SEQ=z,ACK=x+1 ---|
   |                      |
   |----- ACK=1,         |  #4: 客户端确认
   |     SEQ=x+1,ACK=z+1->|
   |                      |

为什么多了一次挥手?因为TCP是全双工:客户端发完FIN表示不发了,但还能收;服务器得把没发完的数据发完才能关。所以ACK和FIN分两步。

重点理解 TIME_WAIT:主动关闭方(一般是客户端)进入TIME_WAIT并等待2MSL(Max Segment Lifetime,通常2分钟)。作用是:

  • 保证最后一个ACK能到达,如果丢了,服务端重传FIN,TIME_WAIT方还能重发ACK

  • 让所有旧报文在网络中消失,避免跟新连接混淆

2.4 TCP状态机——比三次握手更完整的图

TCP有限状态机描述了连接从CLOSED到ESTABLISHED再到TIME_WAIT的全过程。

text

                           +---------+ ---------\      active OPEN
                           |  CLOSED |            \    -----------
                           +---------+<---------\   \   create TCB
                             |     ^              \   \  snd SYN
                   passive OPEN |     |   CLOSE        \   \
                   ------------ |     | ----------       \   \
                    create TCB  |     | delete TCB         \   \
                             V     |                              \
                           +---------+            CLOSE    |    \
                           |  LISTEN |          ---------- |     |
                           +---------+          delete TCB |     |
                    rcvd SYN      |     |         SEND              |
                   -----------    |     |    -------                |
                  | snd SYN,ACK  /       \   snd SYN              /
                  |              V          V                     /
                  |           +---------+                         /
                  |           |         |               rcv SYN      /
                  |           |  SYN    |               -----------
                  |           |  RCVD   | <--------------   snd SYN,ACK
                  |           |         |               
                  |           +---------+               
                  |                  |              
                  |    rcv SYN,ACK   |   snd ACK          
                  |   -----------    V   --------         
                  |      |         +---------+                          
                  |      |         |         |        rcv FIN          |
                  |      |         |         |        ----------       |
                  |      |         |ESTABLISHED| <---    snd ACK       |
                  |      |         |         |                         |
                  |      |         +---------+                         |
                  |      |        rcv FIN /      \   snd FIN /         V
                  |      |        ----------      \ ----------       +---------+
                  |      V         snd ACK          \ CLOSE          |         |
                  |    +---------+                   \ -------       |  CLOSE  |
                  |    |  FIN    | <-------------------- snd FIN     |  WAIT   |
                  |    |  WAIT-1 | -------\                            +---------+
                  |    +---------+        \                         rcv ACK of FIN
                  |       |                 \ snd ACK               -------------- 
                  |       | CLOSE              \                            |
                  |       | -------              \                           V
                  |       V snd FIN                \                       +---------+
                  |     +---------+                  \                    |  LAST   |
                  |     | CLOSING |                    -----------------> |   ACK   |
                  |     +---------+                    rcv ACK of FIN     +---------+
                  |        |                              --------------      |
                  |        | rcv ACK of FIN                 |                  |
                  |        | --------------                 |   rcv ACK of FIN|
                  |        V        \                       V   --------------|
                  |      +---------+  \                  +---------+         |
                  |      |  FIN    |   \        rcv FIN / |  TIME   |         |
                  |      |  WAIT-2 |    ---------------- |  WAIT   |<--------/
                  |      +---------+          snd ACK    +---------+
                  |         |                                 |
                  |         | rcv FIN                         | 2MSL timeout
                  |         | ----------                      | ----------
                  |         V  snd ACK                        V
                  |       +---------+                       +---------+
                  +-----> |  CLOSED | <--------------------- |  CLOSED |
                          +---------+        delete TCB      +---------+

理解这张图,才能真正理解为什么TIME_WAIT会出现、CLOSE_WAIT积压意味着什么。

2.5 拥塞控制——四个算法的演进

流量控制管点对点,拥塞控制管网状全局拥堵。

(1)慢启动

新建连接CWND从1个MSS开始,每收到一个ACK,CWND翻倍。指数增长直到ssthresh(通常65535字节)。

(2)拥塞避免

CWND超过ssthresh后,每收到一个ACK增加(1/CWND)个MSS,每次RTT增加1个MSS,线性增长。

(3)快重传 + 快恢复

收到3个重复ACK时,不进入慢启动,而是将ssthresh设为CWND/2,CWND设为ssthresh+3,然后线性增长。这是TCP Tahoe和TCP Reno的核心差异。

TCP拥塞控制的发展:Tahoe(慢启动+拥塞避免+快重传)、Reno(加入快恢复)、NewReno(改进部分ACK)、CUBIC(Linux默认算法,二次函数增长)、BBR(基于带宽和延迟探测的新型算法)。

2.6 TCP的五个现实案例

场景 具体实现 为什么选择TCP
MySQL主从复制 binlog通过TCP流式传输 每一步都需要确认,绝不能丢包
HTTPS网页加载(HTTP/1.1 & HTTP/2) HTTP协议堆叠在TCP之上 页面要求完整、有序
SFTP文件传输 SSH封装,底层TCP 文件块不能乱序,完整性优先
Kubernetes API Server etcd Raft共识底层是TCP 一致性协议必须先连接再选举
Kafka集群内部Broker通信 Controller与Broker间TCP长连接 元数据同步要求可靠有序

2.7 TCP痛点——为什么需要新协议

  • 握手开销大:TCP 1-RTT + TLS(1-2 RTT),新建连接3个RTT才能发数据

  • 队头阻塞:丢任何一个包,后面全堵住(HTTP/2加重了这个问题)

  • 连接迁移难:IP或端口变了,TCP连接断裂

  • 协议栈在操作系统内核,迭代更新慢


三、WebSocket——让浏览器真正"实时"起来的那个补丁

3.1 它要解决什么问题

2011年之前,想做实时推送给浏览器需要打补丁:轮询、长轮询、Comet(利用HTTP长连接挂起技术)、Flash XMLSocket……全是笨办法。轮询每秒发一次请求,Nginx负载压力大,用户体验差,还费电。

WebSocket不是推翻TCP,而是在TCP上套了一层封装,让浏览器能用JavaScript维持一条双向通道。

3.2 建立连接的过程——HTTP Upgrade

WebSocket复用了HTTP的端口和概念,握手请求长这样:

text

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

服务器返回:

text

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

这一步完成后,TCP连接还是那条连接,但双方开始使用WebSocket帧格式对话,不再是HTTP。这就是"协议升级"的本质。

3.3 WebSocket 帧结构

与TCP的字节流不同,WebSocket保留了"帧"(Frame)边界。每个消息由一个或多个帧组成,有点像UDP的报文边界。

text

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-------+-+-------------+-------------------------------+
 |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
 |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
 |N|V|V|V|       |S|             |   (if payload len==126/127)   |
 | |1|2|3|       |K|             |                               |
 +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - - +
 |     Extended payload length continued, if payload len == 127  |
 + - - - - - - - - - - - - - - - - +-------------------------------+
 |                               |Masking-key, if MASK set to 1  |
 +-------------------------------+-------------------------------+
 | Masking-key (continued)       |          Payload Data         |
 +-------------------------------- - - - - - - - - - - - - - - - - +
 :                     Payload Data continued ...                 :
 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 |                     Payload Data continued ...                 |
 +---------------------------------------------------------------+

关键字段:FIN(消息结束标志)、Opcode(0x1文本/0x2二进制/0x8关闭连接/0x9 Ping/0xA Pong)、MASK(掩码标志,客户端→服务端时必须为1)、Payload len(7位/16位/64位)。

WebSocket与HTTP/2的不同点:WebSocket帧不定义Stream ID,不存在HTTP/2那种复用的概念,但它本身就是全双工的,天然支持双向同时发送。

3.4 WebSocket 在服务端的资源模型

  • 每条连接维护一个文件描述符(epoll中就是一个fd)

  • 内存占用:心跳定时器、会话状态、待发送队列

  • 扩容约束:内存 & 连接数

WebSocket与HTTP最大区别:HTTP请求响应结束就释放连接;WebSocket长期保持,反向推送只需要在服务端保存一个Channel引用,直接写入即可。

3.5 三个真实代码设计场景(带框架)

场景A:使用Spring Boot + STOMP实现WebSocket

java

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic", "/queue");   // 内存中消息代理
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/chat-websocket")
                .setAllowedOrigins("https://your-cdn.com")
                .withSockJS();                            // fallback for old browsers
    }
}

@Controller
public class ChatController {
    @MessageMapping("/chat.sendMessage")
    @SendTo("/topic/public")
    public ChatMessage sendMessage(ChatMessage message) {
        return message;
    }
}

场景B:用Netty底层实现WebSocket服务器

java

public class WebSocketServer {
    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) {
                     ChannelPipeline p = ch.pipeline();
                     p.addLast(new HttpServerCodec());
                     p.addLast(new HttpObjectAggregator(65536));
                     p.addLast(new WebSocketServerProtocolHandler("/websocket"));
                     p.addLast(new TextWebSocketFrameHandler());
                 }
             });
            ChannelFuture f = b.bind(8080).sync();
            f.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

场景C:生产级性能调优参数

yaml

server:
  tomcat:
    websocket:
      buffer-size: 8192               # 消息缓冲区大小
      max-session-idle-timeout: 180000  # 空闲超时(毫秒)
  connection-timeout: 30s
  keep-alive-timeout: 60s

Nginx反向代理WebSocket需要特殊配置:

nginx

location /websocket/ {
    proxy_pass http://backend_ws;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 3600s;   # 长连接超时,别设短了
}

3.6 真实选型的权衡——什么时候用WebSocket

场景 决策结果 核心原因
金融交易行情推送 WebSocket 双向实时,服务端主动推价格变动
在线聊天室 WebSocket 低延迟双向通信
协同文档编辑(如Google Docs) WebSocket + 自定义协议 实时同步+冲突检测
二维码扫码登录 长轮询或Server-Sent Events 单向通知足够,WebSocket过度设计
物联网设备上报 MQTT over TCP 协议更轻量,有QoS分级

3.7 WebSocket的核心痛点

  • TCP队头阻塞问题依然存在

  • 浏览器支持广但服务端资源消耗与连接数线性增长

  • HTTP/3(QUIC)出现后,WebSocket + TCP的叠加暴露了TCP的一些固有限制

  • 7层负载均衡(NGINX/HAProxy)不如4层均衡高效


四、QUIC(Quick UDP Internet Connections)——下一代传输协议

4.1 根本思路:为什么在UDP之上造车

不是不用TCP,而是TCP嵌入操作系统内核太深、进化太慢。Google的思路是:放弃内核TCP,基于UDP重新实现一个带上TCP可靠性的协议。这样QUIC的迭代和定制就不用等Linux内核更新周期,也绕过了网络中间件对TCP的限制。最终QUIC成为HTTP/3的标准传输层。

4.2 QUIC核心特性一:多路流 + 独立队头阻塞消除

TCP的问题:一条连接只有一条字节流,丢一个包全堵住。HTTP/2在TCP上做多路复用,丢包仍然引起队头阻塞。

QUIC的做法:一条QUIC连接包含多个独立的逻辑Stream。HTTP/2的多流在QUIC上真正流独立,丢了Stream A的包只影响A,B可以继续发。

QUIC使用Packet Number(单调递增) 而不是TCP的字节序号,这意味着重传包有新的编号,不会让接收方混淆顺序,也不引入TCP的"重传歧义"问题。

4.3 QUIC核心特性二:0-RTT连接建立

TLS 1.3的设计:首次连接1个RTT完成加密传输;后续连接0个RTT就可以发数据。

首次连接:客户端发送初始包(含TLS 1.3 ClientHello),服务端回复ServerHello+加密配置。密钥协商和传输握手合并为一个阶段。

后续连接:如果客户端之前连接过,缓存了会话票据(PSK),重启连接时可以直接发送加密数据,服务器接收后立即处理。

与HTTPS(TCP 1-RTT + TLS 1-2 RTT)对比:QUIC大部分建连时间0-RTT,极少1-RTT。

4.4 QUIC核心特性三:连接迁移

手机从Wi-Fi切到5G网络时,TCP连接断裂,需要重新握手。

QUIC的身份标识是Connection ID(CID),不是IP+端口。Wi-Fi切到蜂窝网时,新IP发送的数据包带上同一个CID,服务端就知道是同一个连接,继续维持会话。这对于移动场景是革命性的。

4.5 QUIC核心特性四:内置加密

QUIC从一开始就把加密刻在骨头里。所有QUIC数据包都加密,没有明文模式,防止中间人篡改、窃听。内置TLS 1.3握手消除"先TCP连接再TLS握手"的两阶段延迟。

4.6 QUIC数据包和帧结构

QUIC数据包有两种类型:长包头(Long Header,用于连接建立)和短包头(Short Header,用于数据传输)。

QUIC帧格式示例(以Stream帧为例):

text

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                        Stream ID (i)                         |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                        Offset (i)                            |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Length (i)  |   FIN  |                                       |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
  |                                                               |
  |                           Stream Data                         |
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

帧类型包括:Stream帧(数据)、ACK帧(确认)、Crypto帧(加密握手)、Padding帧(占位)、Ping帧(探测)、Connection Close帧(关闭连接)、Reset Stream帧(重置流)。

4.7 性能数据与大规模实践

腾讯云QUIC网关接入HTTP/3业务后,首字节延迟降低约100~200ms,弱网场景下改善尤其明显。当链路丢包率为2%~5%时,HTTP/3比HTTP/2的性能有显著优势,页面加载时间在不同弱网条件下缩短比例从5%到35%不等。

学术研究表明,20%丢包率下,TCP over QUIC仍保持远高于原生TCP的吞吐量。

QUIC有两个"打脸"结论:

  • 在高速网络(数据中心内网、光纤宽带)上,UDP+QUIC+HTTP/3可能比TCP+TLS+HTTP/2慢45.2%,因为UDP在无瓶颈网络需要更多CPU处理每个包

  • 传统TCP优化(窗口缩放、选择性确认)能极大提升吞吐量,而QUIC在这些场景的优势并不明显。

结论:QUIC适合中等到高丢包率、延迟波动的复杂网络(移动网络、无线Wi-Fi、卫星通信、跨国长距离),但不适合无丢包低延迟的理想高速链路。

4.8 QUIC典型应用案例

公司/项目 应用方式 效果
Google(YouTube) 放弃TCP全面切QUIC+HTTP/3 视频缓冲降低,弱网体验提升
Facebook 移动App使用QUIC作为底层传输 长连接保持更好,数据同步更快
携程(Trip.com 移动端API网关支持QUIC 连接迁移提升弱网体验
Cloudflare CDN 全线支持QUIC和HTTP/3 全球网络上的延迟优势
七牛云 直播+点播架构QUIC多路复用 解决高达30%丢包率的弱网场景

五、三协议核心对比表(架构师版)

"不能简单地说谁好谁坏,必须结合场景和业务指标。部署一个10万同时在线的WebSocket网关,跟设计一个高吞吐QUIC+HTTP/3的CDN边缘节点,用的技术完全是两套。"

5.1 核心特性对比

特性维度 TCP WebSocket QUIC
所处层级 传输层(L4) 应用层(封装在TCP上) 传输层(基于UDP)
连接语义 面向连接、可靠字节流 在TCP之上的全双工消息通道 面向连接、可靠、多路流
首部字节 20-60字节 简单帧头(2-14字节) 长包头/短包头(可变)
建立连接最低RTT 1-RTT 1-RTT TCP握手 + 升级 首次1-RTT,续连0-RTT
加密 需额外TLS层(1-2 RTT) 可配合WSS(TLS) 内置TLS 1.3,强制加密
队头阻塞 ❌ 整个连接一个队列,丢包全堵 ❌ 继承了TCP的队头阻塞 ✅ 流级别独立阻塞
多路复用 ❌ 单一字节流 ❌ 单一消息通道 ✅ 多条独立Stream
连接迁移 ❌ 依赖(IP+端口) ❌ 依赖TCP的(IP+端口) ✅ Connection ID

5.2 资源消耗对比

指标 TCP(HTTP/2) WebSocket QUIC(HTTP/3)
每条连接内存占用 约3-15KB 10-30KB(含应用状态) 略高于TCP(需要管理Stream表)
CPU开销(低丢包) 较低 较低 较高(UDP+用户态协议栈)
CPU开销(高丢包) 较高(重传+拥塞控制计算) 较高 中等(流独立可缓解)
NAT/防火墙友好度 最好(全世界允许) 较好(需允许Upgrade) 部分老旧网络可能禁止UDP
服务端水平扩展 每连接一个fd(epoll高效) 每连接一个fd(维护更多状态) 每连接多流+用户态需要更多内存

5.3 丢包率下的性能表现

网络条件 TCP QUIC
0%丢包、低延迟(数据中心内网) 最佳(硬件加速+内核优化) 可能慢40%以上
1%丢包(普通无线网络) 开始出现明显队头阻塞 高于TCP(多流独立)
2-5%丢包(移动弱网、跨境) 吞吐量显著下降 显著优于TCP
10%丢包(弱Wi-Fi、卫星) 拥塞控制使吞吐骤降 保持80%+吞吐
20%丢包(极端弱网) 接近不可用 仍高于TCP的1-2倍

5.4 协议栈成熟度与生态

维度 TCP WebSocket QUIC
标准化年份 1981(RFC 793) 2011(RFC 6455) 2021(RFC 9000)
内核/用户态 操作系统内核 用户态(基于Socket) 用户态(基于UDP)
库和框架支持 所有语言/平台内置 所有主流语言+浏览器 需引入第三方库(支持渐多)
浏览器支持 所有浏览器 所有现代浏览器 HTTP/3需要:Chrome 87+,Firefox 88+,Safari 14+
CDN支持 所有CDN 多数CDN支持 主要CDN已支持(Cloudflare、Akamai等)
调试工具 tcpdump、Wireshark成熟 Wireshark、Chrome DevTools支持 Wireshark(2020年后支持)、qlog格式

六、选型指南与架构决策树

第一步:我的数据丢失能容忍吗?

  • 不能丢(数据库binlog同步、文件上传、金融订单):TCP、WebSocket、QUIC都可以

  • 能丢一点(音视频帧、实时监控画面、游戏状态更新):考虑RAW UDP(丢帧降级),而非QUIC

第二步:对延迟的要求

  • 毫秒级全双工,需要服务端随时主动推送:WebSocket或QUIC

  • 单向请求-响应(REST API):TCP(HTTP)

第三步:网络环境复杂度

  • 移动App、弱网、切换频繁:QUIC

  • 标准数据中心/办公室网络,不需要连接迁移:TCP或WebSocket

第四步:研发维护成本

  • 开发快,生态成熟,调参简单:WebSocket(选熟悉框架)

  • 需要极致性能+连接迁移+0-RTT:QUIC,但学习曲线陡峭

综合决策图

text

                         开始
                           │
                           ▼
                    是否需要服务端主动推送?
                           │
              ┌────────────┴────────────┐
              │ 是                       │ 否
              ▼                          ▼
      是否需要浏览器支持?          HTTP/1.1 或 HTTP/2
              │                     (TCP)即可
    ┌─────────┴─────────┐
    │ 是                │ 否
    ▼                   ▼
WebSocket          是否追求更极致性能、
(浏览器标准)       连接迁移、0-RTT?
                           │
              ┌────────────┴────────────┐
              │ 是                       │ 否
              ▼                          ▼
         QUIC(HTTP/3)              原生TCP长连接
       或 WebTransport                (私有二进制协议)

架构师核心建议

  1. 不要为了新而新:国内很多场景TCP+TLS+HTTP/2足够好,除非弱网、连接迁移是核心卖点

  2. 混合使用:QUIC用于移动端API,WebSocket用于实时推送,TCP用于内网服务间RPC

  3. 做好Fallback:用QUIC时HTTP/3不可用退回到HTTP/2;用WebSocket时准备长轮询降级

  4. 关注维护成本:WebSocket连接数管理难度随并发增大;QUIC故障排查工具链不如TCP成熟


七、专业术语表

术语 全称 简洁解释
RTT Round-Trip Time 往返时间,一个包从发出到收到确认的时间
MSL Maximum Segment Lifetime IP数据包在网络中的最长存活时间(TCP中默认2分钟)
ISN Initial Sequence Number TCP连接建立时随机生成的初始序列号
CWND Congestion Window TCP拥塞窗口,控制一次能发多少数据
RWND Receiver Window 接收窗口,接收方能接受的字节数
SYN Synchronize TCP连接建立的第一步
FIN Finish TCP连接拆除的第一步
ACK Acknowledgment 确认收到数据
RTO Retransmission Timeout TCP超时重传时间间隔
TCB Transmission Control Block 内核维护的TCP连接状态块
MSS Maximum Segment Size TCP报文段最大数据大小(不含头)
HOL Head-of-Line Blocking 队头阻塞
CID Connection ID QUIC连接的唯一标识符
PSK Pre-Shared Key TLS 1.3会话恢复用的预共享密钥
STUN Session Traversal Utilities for NAT NAT会话穿透工具
BBR Bottleneck Bandwidth and RTT Google的拥塞控制算法
QUIC Quick UDP Internet Connections 快速UDP互联网连接
WebTransport Web Transport API Web上的QUIC双向流API

八、核心结论

TCP解决了丢包和顺序问题,但它太老了,内核级迭代难度巨大。

WebSocket在TCP之上给浏览器加了全双工能力。

QUIC是一次根本性的突破:用UDP加用户态协议栈,融合多路流、0-RTT和连接迁移,但代价是在极端高速场景可能不如优化好的TCP。

把这三种协议理解透,可以帮助架构师在实时推送、高速下载、弱网传输等场景做出务实的决策,知道该堆硬件还是该改协议。


参考文献

[1] RFC 793. Transmission Control Protocol. IETF, 1981.

[2] RFC 6455. The WebSocket Protocol. IETF, 2011.

[3] RFC 9000. QUIC: A UDP-Based Multiplexed and Secure Transport. IETF, 2021.

[4] RFC 8446. The Transport Layer Security (TLS) Protocol Version 1.3. IETF, 2018.

[5] I. Swett. QUIC Loss Detection and Congestion Control. IETF, 2021.

[6] Cloud.tencent.com. TCP协议可靠性设计的核心机制与底层逻辑. 2025.

[7] Cloud.tencent.com. 1万字30张图说清TCP协议. 2021.

[8] C. Culnane, M. J. Shepherd. Evaluating Transport Protocols on 5G for Mobile Augmented Reality, 2023.

[9] P. Polese. Implementation and Performance Evaluation of TCP over QUIC Tunnels, 2023.

[10] Cloud.tencent.com. QUIC协议在天翼云CDN全站加速产品中的应用. 2023.

[11] CSDN. 程序员进阶之路:QUIC篇. 2024.

[12] 七牛云. 抛弃TCP握手:深入解析QUIC协议在弱网环境下的0-RTT实现. 2025.

[13] Trip.com. QUIC 高可用及性能提升. 2024.

[14] MDN Web Docs. WebTransport API. 2025.

[15] 张鑫旭. 浅学WebTransport API:下一代Web双向通信技术. 2026.

[16] 掘金. HTTP/3 的多路复用和 QUIC 到底能让页面快多少?聊聊连接迁移和 0-RTT. 2026.

[17] 携程技术. Android开发中通信协议与框架选型. 2025.

[18] CSDN. 8种网络协议工作流程详解. 2025.

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐