TCP SO_REUSEPORT 套接字分片与零停机热重启深度实战

TCP SO_REUSEPORT 套接字分片与零停机热重启深度实战


一、为什么需要 SO_REUSEPORT

在 Linux 高并发网络编程中,经典的 C10K/C100K 问题催生了大量解决方案:单线程 epoll、线程池 accept、SO_REUSEPORT 等。其中 SO_REUSEPORT 从 Linux 3.9(2013 年)引入之后,逐渐成为生产环境中的首选方案。

1.1 Accept 惊群:被误解多年的"问题"

早期 Linux 版本中,多个进程/线程阻塞在同一个 listen socket 上调用 accept(),当新连接到来时,内核会唤醒所有等待者——但只有一个能成功获取连接。这就是所谓的"accept 惊群"(thundering herd)。

然而很多人不知道的是,Linux 2.6 之后 accept 惊群问题基本已经被内核修复了。内核使用等待队列的 exclusive 模式,保证每次只唤醒一个等待者。真正的性能瓶颈不在于惊群,而在于:

  • 单点 accept 的串行化:所有线程共享同一个 accept queue,必须互斥访问
  • 负载不均衡:内核唤醒策略可能导致某些线程过载,某些线程空闲
  • 缓存局部性差:连接在不同 CPU 核间频繁跳转

1.2 SO_REUSEPORT 的核心思路

SO_REUSEPORT 的本质是:允许多个 socket 绑定到同一个 IP:PORT 组合,内核在 TCP 连接建立阶段直接将连接分发给对应的 listen socket。

这意味着:

  • 每个工作进程/线程拥有独立的 listen socket
  • accept 操作不再需要跨进程/线程同步
  • TCP 三次握手的 CPU 开销天然分布在多个核上
  • 配合 CPU affinity,可以实现最佳缓存局部性

二、内核实现深度剖析

2.1 数据结构:reuseport_array

在内核中,绑定在同一端口上的所有 SO_REUSEPORT socket 通过一个共享的 struct sock_reuseport 关联。关键数据结构定义在 net/core/sock_reuseport.c:


struct sock_reuseport {
    struct rcu_head     rcu;
    u16         max_socks;        /* 组内最大 socket 数 */
    u16         num_socks;        /* 当前 socket 数 */
    /* 用于 BPF 的匹配程序 */
    struct bpf_prog __rcu   *prog;
    /* socket 成员数组 */
    struct sock     *socks[0];    /* 变长数组 */
};

当应用程序对 N 个 socket 设置 SO_REUSEPORT 时,它们共享同一个 sock_reuseport 实例,内核通过 socks 数组管理这些 socket 的引用。

2.2 连接分发算法

新 TCP 连接进入时,内核在 inet_lookup_listener() 中调用 reuseport_select_sock() 来确定接收该连接的 listen socket:


TCP SYN 到达
    ↓
inet_csk_route_req()    →  确定目标路由
    ↓
inet_lookup_listener()  →  端口查找
    ↓
reuseport_select_sock() →  选择目标 socket
    ↓
inet_csk_reqsk_queue_add() → 添加到该 socket 的半连接队列
    ↓
完成三次握手后进入该 socket 的 accept queue

关键代码路径(简化版):


static struct sock *reuseport_select_sock(struct sock *sk, u32 hash, struct sk_buff *skb)
{
    struct sock_reuseport *reuse;
    struct bpf_prog *prog;
    struct sock *sk2 = NULL;
    u16 socks;

    rcu_read_lock();
    reuse = rcu_dereference(sk-                        
                    
点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部