目录
-
核心代码目录
-
TCP 交互架构
-
UDS(Unix Domain Socket)实现
-
事件驱动机制
-
完整交互流程
一、核心代码目录
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 使用场景
-
SPIRE 身份认证集成 :Istio 通过 UDS 与 SPIRE agent 通信,Envoy 通过 SDS API 从 SPIRE 获取工作负载身份。CSI 驱动将 SPIRE agent 的 UDS 挂载到
/run/secrets/workload-spiffe-uds/socket,Envoy 通过此路径获取 SPIFFE 身份。 -
控制平面通信:xDS 协议可通过 UDS 与控制平面通信。
-
热重启:通过 UDS 传递状态信息。
-
统计和追踪:本地统计信息收集。
四、事件驱动机制
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)包含以下步骤:
- 等待事件 :调用
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 交互和事件驱动机制具有以下特点:
-
清晰的分层架构:接口层 → 实现层 → 事件层
-
基于 libevent:高效的事件驱动,支持大量并发连接
-
完整的 UDS 支持:用于本地进程间通信,尤其在工作负载身份认证(SPIRE)场景中发挥关键作用
-
灵活的过滤器链:支持 L4/L7 过滤器扩展
-
高性能设计:零拷贝、水位控制、可调度回调平衡机制