Envoy 底层 TCP 交互、UDS 和事件驱动技术文档

目录

  1. 核心代码目录

  2. TCP 交互架构

  3. UDS(Unix Domain Socket)实现

  4. 事件驱动机制

  5. 完整交互流程


一、核心代码目录

1.1 网络层(TCP/UDS)

bash 复制代码
source/common/network/├── connection_impl.h/cc              # 连接实现(核心!)├── connection_impl_base.h/cc         # 连接基类├── socket_impl.h/cc                  # Socket 实现├── listen_socket_impl.h/cc           # 监听 Socket 实现├── tcp_listener_impl.h/cc            # TCP 监听器实现├── udp_listener_impl.h/cc            # UDP 监听器实现├── io_socket_handle_impl.h/cc        # IO 句柄实现├── filter_manager_impl.h/cc          # 过滤器管理器├── base_listener_impl.h/cc           # 监听器基类├── connection_balancer_impl.h/cc     # 连接均衡器├── raw_buffer_socket.h/cc            # 原始缓冲区 Socket├── socket_option_impl.h/cc           # Socket 选项实现├── transport_socket_options_impl.h/cc # 传输 Socket 选项├── dns_resolver/                     # DNS 解析器├── matching/                         # 匹配器└── utility.h/cc                      # 工具函数

1.2 事件驱动层

bash 复制代码
source/common/event/├── dispatcher_impl.h/cc              # 事件分发器(核心!)├── libevent.h/cc                     # libevent 封装├── libevent_scheduler.h/cc           # libevent 调度器├── file_event_impl.h/cc              # 文件事件实现├── timer_impl.h/cc                   # 定时器实现├── schedulable_cb_impl.h/cc          # 可调度回调实现├── event_impl_base.h/cc              # 事件基类├── scaled_range_timer_manager_impl.h/cc # 范围定时器管理器├── real_time_system.h/cc             # 实时系统├── deferred_task.h                   # 延迟任务├── posix/│   ├── signal_impl.h/cc              # 信号处理(POSIX)│   └── ...└── win32/                            # Windows 平台实现

1.3 抽象接口层

bash 复制代码
envoy/network/├── connection.h                      # 连接接口├── listener.h                        # 监听器接口├── socket.h                          # Socket 接口├── transport_socket.h                # 传输 Socket 接口├── filter.h                          # 过滤器接口├── io_handle.h                       # IO 句柄接口└── ...
envoy/event/├── dispatcher.h                      # 分发器接口├── file_event.h                      # 文件事件接口├── timer.h                           # 定时器接口├── libevent.h                        # libevent 接口└── ...

二、TCP 交互架构

2.1 核心类层次

cpp 复制代码
Network::Connection (接口)    ↑    |ConnectionImplBase (基类)    ↑    |ConnectionImpl (实现)    ↑    ├── ServerConnectionImpl (服务端连接)    └── ClientConnectionImpl (客户端连接)

2.2 关键类说明

文件 功能
ConnectionImpl connection_impl.h/cc 连接核心实现,管理读写缓冲区、过滤器链
ServerConnectionImpl connection_impl.h/cc 服务端连接,处理已接受的连接
ClientConnectionImpl connection_impl.h/cc 客户端连接,主动发起连接
TcpListenSocket listen_socket_impl.h TCP 监听 Socket
UdsListenSocket listen_socket_impl.h Unix Domain Socket 监听器
DispatcherImpl event/dispatcher_impl.h/cc 事件分发器,基于 libevent
LibeventScheduler event/libevent_scheduler.h/cc libevent 调度器封装

2.3 连接状态机

perl 复制代码
┌─────────────┐│   Closed    │└──────┬──────┘       │ connect() / accept()       ▼┌─────────────┐│ Connecting  │└──────┬──────┘       │ onConnected()       ▼┌─────────────┐│   Open      │└──────┬──────┘       │ close()       ▼┌─────────────┐│  Closing    │└──────┬──────┘       │       ▼┌─────────────┐│   Closed    │└─────────────┘

三、UDS(Unix Domain Socket)实现

3.1 UDS 相关类

nginx 复制代码
UdsListenSocket (listen_socket_impl.h)    ↑    |ListenSocketImpl (基类)    ↑    |SocketImpl (基类)

3.2 UDS 核心代码

ruby 复制代码
// source/common/network/listen_socket_impl.h
class UdsListenSocket : public ListenSocketImpl {public:  UdsListenSocket(const Address::InstanceConstSharedPtr& address);  UdsListenSocket(IoHandlePtr&& io_handle, const Address::InstanceConstSharedPtr& address);  Socket::Type socketType() const override { return Socket::Type::Stream; }};

3.3 UDS 特性

特性 说明
地址族 AF_UNIX
类型 SOCK_STREAM(流式)
用途 本地进程间通信
性能 比 TCP 更快(无网络栈开销)
安全性 基于文件系统权限

3.4 UDS 使用场景

  1. SPIRE 身份认证集成 :Istio 通过 UDS 与 SPIRE agent 通信,Envoy 通过 SDS API 从 SPIRE 获取工作负载身份。CSI 驱动将 SPIRE agent 的 UDS 挂载到 /run/secrets/workload-spiffe-uds/socket,Envoy 通过此路径获取 SPIFFE 身份。

  2. 控制平面通信:xDS 协议可通过 UDS 与控制平面通信。

  3. 热重启:通过 UDS 传递状态信息。

  4. 统计和追踪:本地统计信息收集。

四、事件驱动机制

4.1 事件驱动架构

Envoy 的事件驱动核心基于 libevent,通过单线程事件循环高效处理海量连接

go 复制代码
┌─────────────────────────────────────────────────────────┐│                    DispatcherImpl                        ││  (事件分发器,基于 libevent)                              │└────────────────┬────────────────────────────────────────┘                 │    ┌────────────┼────────────┐    │            │            │    ▼            ▼            ▼┌─────────┐ ┌─────────┐ ┌─────────┐│FileEvent│ │  Timer  │ │ Signal  ││ (IO事件)│ │ (定时器) │ │ (信号)  │└────┬────┘ └────┬────┘ └────┬────┘     │           │           │     └───────────┼───────────┘                 │                 ▼         ┌──────────────┐         │  libevent    │         │  (事件循环)   │         └──────────────┘

4.2 核心事件类型

事件类型 说明 触发条件 封装类
FileEvent 文件描述符事件 Socket 可读/可写/错误 FileEventImpl
Timer 定时器事件 定时器到期(连接超时、闲置超时等) TimerImpl
Signal 信号事件 收到系统信号 SignalImpl
SchedulableCallback 可调度回调 跨线程任务投递、延迟调度、重试等 SchedulableCallbackImpl

4.3 事件循环(Event Loop)

Dispatcher 线程的每一次事件循环(event loop iteration)包含以下步骤:

  1. 等待事件 :调用 epoll_wait(或 kqueue)等待以下事件:
  • 线程间 post callback 消息(TLS 数据更新,如 Cluster/Stats)

  • Timer timeout 事件

  • File/socket/inotify 事件

  • 内部 active event(程序显式调用函数触发)

  • 处理事件:按优先级处理就绪事件。

  • 执行回调:调用注册的回调函数。

4.4 libevent 封装层次

cpp 复制代码
libevent::event_base    ↑    └── LibeventScheduler (封装 event_base)            ↑            └── DispatcherImpl                    ↑                    └── WorkerImpl → ThreadImplPosix
libevent::event    ↑    └── ImplBase (基类)            ├── TimerImpl          (定时器)            ├── SchedulableCallbackImpl (可调度回调)            └── FileEventImpl      (文件/Socket 事件)

SchedulableCallbackImpl 的设计目的是在高负载时平衡事件处理的响应时间和吞吐量,避免单次 event loop 处理过久影响其他事件的响应时效。

4.5 事件分发器核心方法

ruby 复制代码
// source/common/event/dispatcher_impl.h
class DispatcherImpl : public Dispatcher {public:  // 创建文件事件(Socket 可读/可写)  FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb,                                FileTriggerType trigger, uint32_t events);
  // 创建定时器  TimerPtr createTimer(TimerCb cb);
  // 创建监听器  Network::ListenerPtr createListener(Network::SocketSharedPtr&& socket,                                      Network::TcpListenerCallbacks& cb, ...);
  // 创建服务端连接  Network::ServerConnectionPtr createServerConnection(      Network::ConnectionSocketPtr&& socket,      Network::TransportSocketPtr&& transport_socket, ...);
  // 创建客户端连接  Network::ClientConnectionPtr createClientConnection(      Network::Address::InstanceConstSharedPtr address, ...);
  // 运行事件循环  void run(RunType type);};

五、完整交互流程

5.1 服务端 TCP 连接建立流程

css 复制代码
┌─────────────────────────────────────────────────────────────────────────────┐│                          服务端 TCP 连接建立流程                              │└─────────────────────────────────────────────────────────────────────────────┘
1. 创建监听 Socket   ┌─────────────────────────────────────────────────────────────────┐   │ TcpListenSocket(address, options, bind_to_port)                │   │   ├── socket(AF_INET/AF_INET6, SOCK_STREAM, 0)                 │   │   ├── setsockopt(SO_REUSEADDR)                                  │   │   ├── bind(address)                                             │   │   └── listen(backlog)                                           │   └─────────────────────────────────────────────────────────────────┘
2. 创建监听器   ┌─────────────────────────────────────────────────────────────────┐   │ dispatcher->createListener(socket, callbacks, ...)             │   │   ├── 创建 FileEvent (监听 socket 可读事件)                     │   │   └── 注册回调: onAccept()                                      │   └─────────────────────────────────────────────────────────────────┘
3. 事件循环等待   ┌─────────────────────────────────────────────────────────────────┐   │ dispatcher->run(RunType::Block)                                │   │   └── event_base_loop(base_, EVLOOP_NONBLOCK)                   │   └─────────────────────────────────────────────────────────────────┘
4. 新连接到达   ┌─────────────────────────────────────────────────────────────────┐   │ libevent 检测到监听 socket 可读                                 │   │   └── 触发 FileEvent 回调: onAccept()                           │   └─────────────────────────────────────────────────────────────────┘
5. 接受连接   ┌─────────────────────────────────────────────────────────────────┐   │ onAccept()                                                      │   │   ├── new_fd = accept(listen_fd, &addr, &addrlen)              │   │   ├── AcceptedSocketImpl(new_fd, local_addr, remote_addr)       │   │   └── dispatcher->createServerConnection(socket, ...)           │   └─────────────────────────────────────────────────────────────────┘
6. 创建服务端连接   ┌─────────────────────────────────────────────────────────────────┐   │ ServerConnectionImpl(dispatcher, socket, transport_socket, ...) │   │   ├── 创建读写缓冲区 (read_buffer_, write_buffer_)              │   │   ├── 创建 FileEvent (连接 socket 可读/可写事件)                │   │   ├── 注册回调: onFileEvent()                                   │   │   └── 初始化过滤器链                                            │   └─────────────────────────────────────────────────────────────────┘
7. 连接就绪   ┌─────────────────────────────────────────────────────────────────┐   │ raiseEvent(ConnectionEvent::Connected)                          │   │   └── 通知过滤器链连接已建立                                    │   └─────────────────────────────────────────────────────────────────┘

5.2 数据读写流程

css 复制代码
┌─────────────────────────────────────────────────────────────────────────────┐│                              数据读写流程                                    │└─────────────────────────────────────────────────────────────────────────────┘
读数据流程:
1. Socket 可读   ┌─────────────────────────────────────────────────────────────────┐   │ libevent 检测到连接 socket 可读                                 │   │   └── 触发 FileEvent 回调: onFileEvent(events=READ)             │   └─────────────────────────────────────────────────────────────────┘
2. 读取数据   ┌─────────────────────────────────────────────────────────────────┐   │ onReadReady()                                                   │   │   ├── transport_socket_->doRead(read_buffer_)                   │   │   │   └── recv(fd, buffer, size, 0)                            │   │   └── 更新统计信息                                              │   └─────────────────────────────────────────────────────────────────┘
3. 过滤器处理   ┌─────────────────────────────────────────────────────────────────┐   │ filter_manager_->onRead()                                      │   │   └── 遍历读过滤器链,每个过滤器处理数据                         │   └─────────────────────────────────────────────────────────────────┘
写数据流程:
1. 写入数据   ┌─────────────────────────────────────────────────────────────────┐   │ connection->write(buffer, end_stream)                          │   │   ├── write_buffer_->move(buffer)                              │   │   └── enableWriteEvent()                                        │   └─────────────────────────────────────────────────────────────────┘
2. Socket 可写   ┌─────────────────────────────────────────────────────────────────┐   │ libevent 检测到连接 socket 可写                                 │   │   └── 触发 FileEvent 回调: onFileEvent(events=WRITE)            │   └─────────────────────────────────────────────────────────────────┘
3. 发送数据   ┌─────────────────────────────────────────────────────────────────┐   │ onWriteReady()                                                  │   │   ├── transport_socket_->doWrite(write_buffer_)                 │   │   │   └── send(fd, buffer, size, 0)                            │   │   └── 更新统计信息                                              │   └─────────────────────────────────────────────────────────────────┘

5.3 UDS 连接建立流程

perl 复制代码
┌─────────────────────────────────────────────────────────────────────────────┐│                          UDS 连接建立流程                                    │└─────────────────────────────────────────────────────────────────────────────┘
1. 创建 UDS 监听 Socket   ┌─────────────────────────────────────────────────────────────────┐   │ UdsListenSocket(address)                                       │   │   ├── socket(AF_UNIX, SOCK_STREAM, 0)                          │   │   ├── bind(unix_address)                                        │   │   └── listen(backlog)                                           │   └─────────────────────────────────────────────────────────────────┘
2. 创建 UDS 监听器   ┌─────────────────────────────────────────────────────────────────┐   │ dispatcher->createListener(uds_socket, callbacks, ...)         │   │   └── 流程与 TCP 相同                                           │   └─────────────────────────────────────────────────────────────────┘
3. 接受 UDS 连接   ┌─────────────────────────────────────────────────────────────────┐   │ onAccept()                                                      │   │   ├── new_fd = accept(uds_fd, &unix_addr, &addrlen)            │   │   ├── 获取对端凭证 (SO_PEERCRED)                                │   │   └── 创建 ServerConnectionImpl                                  │   └─────────────────────────────────────────────────────────────────┘
4. 后续流程与 TCP 相同

5.4 事件驱动完整流程

css 复制代码
┌─────────────────────────────────────────────────────────────────────────────┐│                        事件驱动完整流程                                      │└─────────────────────────────────────────────────────────────────────────────┘
1. 初始化   ┌─────────────────────────────────────────────────────────────────┐   │ DispatcherImpl(name, api, time_system)                         │   │   ├── event_base_new()                                          │   │   ├── 创建 LibeventScheduler                                    │   │   └── 初始化定时器、文件事件管理器                              │   └─────────────────────────────────────────────────────────────────┘
2. 注册事件   ┌─────────────────────────────────────────────────────────────────┐   │ createFileEvent(fd, callback, trigger, events)                  │   │   ├── event_new(base_, fd, events, callback)                    │   │   └── event_add(event, timeout)                                 │   └─────────────────────────────────────────────────────────────────┘
3. 运行事件循环   ┌─────────────────────────────────────────────────────────────────┐   │ dispatcher->run(RunType::Block)                                │   │   └── event_base_loop(base_, flags)                             │   │       ├── 等待事件 (epoll_wait/kqueue)                          │   │       ├── 处理就绪事件                                          │   │       └── 执行回调函数                                          │   └─────────────────────────────────────────────────────────────────┘
4. 事件处理   ┌─────────────────────────────────────────────────────────────────┐   │ libevent 回调                                                   │   │   ├── FileEvent: onFileEvent(events)                            │   │   │   ├── READ: onReadReady()                                  │   │   │   ├── WRITE: onWriteReady()                                │   │   │   └── ERROR: close()                                       │   │   ├── Timer: onTimer()                                         │   │   └── Signal: onSignal()                                       │   └─────────────────────────────────────────────────────────────────┘
5. 清理   ┌─────────────────────────────────────────────────────────────────┐   │ ~DispatcherImpl()                                              │   │   ├── event_base_free(base_)                                   │   │   └── 清理所有事件                                              │   └─────────────────────────────────────────────────────────────────┘

六、关键数据结构

6.1 ConnectionImpl 核心成员

cpp 复制代码
class ConnectionImpl : public ConnectionImplBase {private:  TransportSocketPtr transport_socket_;      // 传输 Socket(TLS/原始)  ConnectionSocketPtr socket_;               // Socket 句柄  StreamInfo::StreamInfo& stream_info_;      // 流信息  FilterManagerImpl filter_manager_;         // 过滤器管理器  Buffer::InstancePtr write_buffer_;         // 写缓冲区  Buffer::InstancePtr read_buffer_;          // 读缓冲区  uint32_t read_buffer_limit_;               // 读缓冲区限制  bool connecting_;                          // 连接中标志  uint32_t read_disable_count_;              // 读禁用计数  bool write_buffer_above_high_watermark_;   // 写缓冲区高水位标志  bool enable_half_close_;                   // 半关闭标志  bool read_end_stream_;                     // 读结束标志  bool write_end_stream_;                    // 写结束标志};

6.2 DispatcherImpl 核心成员

cpp 复制代码
class DispatcherImpl : public Dispatcher {private:  LibeventScheduler base_scheduler_;         // libevent 调度器  SchedulerPtr scheduler_;                   // 调度器  std::vector<DeferredDeletablePtr> to_delete_1_; // 延迟删除列表 1  std::vector<DeferredDeletablePtr> to_delete_2_; // 延迟删除列表 2  std::list<std::function<void()>> post_callbacks_; // 跨线程回调  absl::InlinedVector<const ScopeTrackedObject*, 10> tracked_object_stack_; // 追踪对象栈  MonotonicTime approximate_monotonic_time_; // 近似单调时间  WatchdogRegistrationPtr watchdog_registration_; // 看门狗注册};

七、性能优化

7.1 零拷贝优化

  • 使用 Buffer::Instance 管理数据,避免不必要的拷贝

  • 过滤器链直接操作缓冲区引用

7.2 事件驱动优势

  • 单线程事件循环,避免锁竞争

  • libevent 使用 epoll/kqueue,高效处理大量连接

  • 边缘触发(Edge-Triggered)模式,减少系统调用

  • SchedulableCallbackImpl 机制平衡响应时间和吞吐量

7.3 缓冲区管理

  • 水位机制(高水位/低水位)控制背压

  • 读缓冲区限制防止内存溢出

  • 写缓冲区限制防止发送过快


八、总结

Envoy 的底层 TCP/UDS 交互和事件驱动机制具有以下特点:

  1. 清晰的分层架构:接口层 → 实现层 → 事件层

  2. 基于 libevent:高效的事件驱动,支持大量并发连接

  3. 完整的 UDS 支持:用于本地进程间通信,尤其在工作负载身份认证(SPIRE)场景中发挥关键作用

  4. 灵活的过滤器链:支持 L4/L7 过滤器扩展

  5. 高性能设计:零拷贝、水位控制、可调度回调平衡机制

相关推荐
wifi chicken4 小时前
wifi漫游(Roaming)802.11kvr 全协议梳理
网络·wifi·内核开发·wifi 漫游
MAXrxc4 小时前
VRRP初体验
网络
qq_260241234 小时前
将盾CDN:移动网络环境下的安全接入技术
网络·安全
试试勇气5 小时前
C++实现json-rpc框架
网络协议·rpc·json
咖喱o5 小时前
策略路由
网络
Deitymoon5 小时前
linux——TCP服务器获取客户端IP地址
linux·服务器·tcp/ip
CDN3605 小时前
高防服务器磁盘 / CPU 爆满?攻击引流与资源扩容实战
运维·服务器·网络协议
white-persist5 小时前
【vulhub spring CVE-2018-1270】CVE-2018-1270 Spring Messaging 远程命令执行漏洞 完整复现详细分析解释
java·服务器·网络·数据库·后端·python·spring
听到微笑5 小时前
MCP传输协议演进:从SSE到Streamable HTTP
网络·网络协议·http