跳到主要内容

网络层设计

概述

本文档描述了 Garnet 服务器的网络层是如何设计的,以及它用于执行网络操作以与客户端通信的各种类。

初始化时,GarnetServer 实例化 GarnetServerTcp 对象以处理传入的网络连接。其 Start 方法在 GarnetServer 启动时调用,绑定到配置中指定的 IP 地址和端口(请参阅配置页面),并开始接受来自客户端的新连接。它还将 AcceptEventArg_Completed 注册为接收新连接时要调用的回调函数。

当接受新连接时调用的 AcceptEventArg_Completed 方法通过创建新的 ServerTcpNetworkHandler 对象并使用 HandleNewConnection 方法将其添加到 activeHandlers 字典中来处理新连接。

网络处理器

ServerTcpNetworkHandler 执行以下步骤来接收和处理传入数据。

  • 实例化时,分配网络缓冲区内存以接收数据。
  • 网络缓冲区是使用由 LimitedFixedBufferPool 类管理的内存池分配的。有关详细信息,请参阅LimitedFixedBufferPool
  • 分配的网络缓冲区配置为直接从网络接收数据。
  • 它(通过基类 TcpNetworkHandlerBase)将 RecvEventArg_Completed 注册为从套接字接收数据的回调方法。
  • 此外,根据是否启用 TLS 加密,使用 SslStream.AuthenticateAsServerAsync 方法执行客户端服务器身份验证来验证 SSL 连接。

基类 NetworkHandler 提供处理网络通信的功能,包括通过网络连接发送和接收数据。该类的主要部分

  • 类的构造函数初始化各种字段和属性,包括服务器钩子、网络发送器、网络缓冲区池、TLS 相关字段和日志记录器。它还根据是否启用 TLS 设置网络和传输接收缓冲区。
  • StartStartAsync 方法用于启动网络处理器,包括如果启用 TLS 的身份验证阶段。这些方法采用可选参数,例如 TLS 选项和远程端点名称。它们内部调用 AuthenticateAsServerAsync 或 AuthenticateAsClientAsync 方法来执行身份验证。
  • AuthenticateAsServerAsyncAuthenticateAsClientAsync 方法处理 TLS 连接的身份验证过程。它们使用 sslStream 对象执行身份验证并建立安全连接。这些方法还处理读取身份验证后剩余的任何额外字节。
  • 当从网络接收到数据时,会调用 OnNetworkReceive 方法。此方法负责处理接收到的数据。它首先检查 TLS 读取器的状态,并对网络和传输接收缓冲区执行必要的转换。然后,它调用 Process 方法来处理接收到的数据。
  • Process 方法负责处理接收到的数据。它检查传输接收缓冲区中是否有数据以及是否有可用的消息消费者。如果有,它会尝试通过调用 TryProcessRequest 方法来处理请求。消息消费者负责根据线协议检索会话提供程序 - ASCII 是当前唯一支持的格式。会话提供程序在 Garnet 服务器初始化时已注册。然后使用检索到的会话提供程序创建新的会话对象(如果尚不存在)。为了处理消息,GarnetProvider 类被注册为会话提供程序,并用于创建 RespServerSession 类的对象以处理 RESP 消息。
  • 该类还执行其他操作,例如缓冲区管理、缓冲区移动、记录安全信息和释放资源。

GarnetTcpNetworkSender

GarnetTcpNetworkSender 类是一个 TCP 网络发送器,它继承自 NetworkSenderBase 类。它负责通过 TCP 连接发送网络数据以响应消息给客户端。这作为 ServerTcpNetworkHandler 对象的创建的一部分被实例化。

  • 它使用以前创建用于接受连接的套接字将响应发送回客户端。
  • 该类使用 GarnetSaeaBuffer 对象堆栈来管理可重用的发送缓冲区。这些缓冲区是使用类型为LimitedFixedBufferPool 的 networkPool 字段创建的。这些缓冲区用于存储要通过网络发送的数据。
  • 该类使用节流来限制并发发送的数量。它有一个 throttleCount 字段来跟踪正在进行的发送数量,以及一个 throttle 信号量来控制并发发送的最大数量。

使用 LimitedFixedBufferPool 的网络内存池

LimitedFixedBufferPool 类是一个内存池实现,它提供不同大小的内存段池。它旨在高效地管理内存分配和释放,以提高在需要频繁内存分配和释放操作的场景中的性能。它通过使用并发队列数组来实现这一点。每个并发队列代表特定大小范围的内存段。该类提供从池中分配和释放内存段的方法。

  • LimitedFixedBufferPool 类被设计为线程安全的,可以在多线程场景中使用。
  • 该池内部使用并发队列来管理内存段,确保高效的分配和释放操作。
  • 该池支持大小为二的幂且大于或等于最小分配大小的内存段。
  • LimitedFixedBufferPool 类是可处置的,不再需要时应将其处置以释放已分配的内存段。

Get 方法从池中为请求的大小分配一个内存段。它返回一个表示已分配内存段的 PoolEntry 对象。

Return 方法将内存段返回到池中以供重用。

PoolEntry 类

LimitedFixedBufferPool 类内部使用 PoolEntry 类来表示内存段。PoolEntry 类提供重用和管理已分配内存段的方法。