Listener 连接建立细节#
事件驱动和连接的建立的过程和关系:
Envoy worker 线程挂起在
epoll_wait()
方法中。线程被移出 kernel 的 runnable queue。线程睡眠。client 建立连接,server 内核完成3次握手,触发 listen socket 事件。
操作系统把 Envoy worker 线程被移入 kernel 的 runnable queue。Envoy worker 线程被唤醒,变成 runnable。操作系统发现可用 cpu 资源,把 runnable 的 envoy worker 线程调度上 cpu。(注意,runnable 和 调度上 cpu 不是一次完成的)
Envoy 分析事件列表,按事件列表的 fd 调度到不同的 FileEventImpl 类的回调函数(实现见:
FileEventImpl::assignEvents
)FileEventImpl 类的回调函数调用实际的业务回调函数,进行 syscall
accept
,完成 socket 连接。得到新 socket 的 FD:$new_socket_fd
。业务回调函数把 调用
epoll_ctl
把$new_socket_fd
加到 epoll 监听中。回到步骤 1 。
TCP 连接建立步骤#
先看看代码,了解大概的连接建立过程和相关的实现:
图:Listener TCP 连接建立流程#
步骤是:
epoll 收到连接请求,完成3次握手。最好回调到 TcpListenerImpl::onSocketEvent()。
最终 syscall
accept()
获得新 socket 的 FD。调用 ActiveTcpListener::onAccept()
创建新连接专用的
ListenerFilterChain
创建新连接专用的
ActiveTcpSocket
,发起ListenerFilterChain
流程执行
ListenerFilterChain
流程:如:TlsInspector::Filter 注册监听新 socket 的事件,以便在后续新 socket 发生事件时,读 socket,抽取出 TLS SNI/ALPN。
当
ListenerFilterChain
中所有的ListenerFilter
在新的事件和事件周期中完成其所有的数据交换和抽取的任务,本 fd 的控制权交到一环节。
调用 核心函数
ActiveTcpListener::newConnection()
调用 findFilterChain() 基于之前
ListenerFilter
抽取到的数据,和各network filter chain 配置
的 match 条件,找到最匹配的network filter chain 配置
。创建
ServerConnection
(ConnectionImpl的子类) 对象注册 socket 事件回调到
Network::ConnectionImpl::onFileEvent(uint32_t events)
中。即以后的 socket 事件将由这个ServerConnection
处理。
用之前找到的
network filter chain 配置
对象,创建transportSocket
。用之前找到的
network filter chain 配置
对象,创建运行期的NetworkFilterChain
。
求证过程#
如果有兴趣研究实现细节,建议看看我 Blog 的文章: