Nginx 在 64 位平台上存储 TCP 连接的状态有多大?

How big is it for Nginx to store the state of a TCP connection on a 64-bit platform?

阅读 Nginx 的 limit_conn_zone and limit_req_zone 文档后,我感到困惑。尽管他们都使用 $binary_remote_addr 变量来存储密钥,但他们描述了不同大小的 space 占用。请问这是文档错误吗?在 64 位平台上存储一个 TCP 连接状态需要多少 space?

来自limit_conn_zone中的描述。

Note that instead of $remote_addr, the $binary_remote_addr variable is used here. The $remote_addr variable’s size can vary from 7 to 15 bytes. The stored state occupies either 32 or 64 bytes of memory on 32-bit platforms and always 64 bytes on 64-bit platforms. The $binary_remote_addr variable’s size is always 4 bytes for IPv4 addresses or 16 bytes for IPv6 addresses. The stored state always occupies 32 or 64 bytes on 32-bit platforms and 64 bytes on 64-bit platforms.

来自limit_req_zone中的描述。

Note that instead of $remote_addr, the $binary_remote_addr variable is used here. The $binary_remote_addr variable’s size is always 4 bytes for IPv4 addresses or 16 bytes for IPv6 addresses. The stored state always occupies 64 bytes on 32-bit platforms and 128 bytes on 64-bit platforms.

这两个指令都在共享内存中定义了一个区域,其中包含从键到某些状态的映射。您将密钥的大小误认为是状态的大小。此外,他们不必使用 $binary_remote_addr 变量作为键。实际上,您是通过指令的第一个参数 (key) 来决定将哪个变量用作键的人。

我所说的映射是指一个 function/data 结构,给定一个键 return 一个与该键关联的值。相同的键将始终 return 相同的值。这类似于Dictionary(抽象数据类型),可以使用HashTable(数据结构)来实现。我不是 100% 确定 NGINX 实现会专门使用这些类型,但这是可能的。阅读它们可能会帮助您更好地理解该主题。不管它是如何实现的,NGINX 将这种映射称为“区域”。

在这两个指令中,您都定义了一个区域,并且能够指定要用作键的变量。这将决定哪些 requests/connections 被分组为相同的值,哪些不是。以$binary_remote_addr为例。在这种情况下,共享远程地址的所有 requests/connections 将在区域中分组为一个值。

最后,对于存储的状态 - 这是与键关联的值。你可以把内存的抽象布局想象成:

[key1] ---> { some state stored in the zone, associated with key1 }
[key2] ---> { some other state, associated with key2 }
etc.

现在,重要的是虽然它们使用相同的键来索引数据,但这些指令中的每一个都在区域中存储不同的信息。两者的定义都以:

开头

Sets parameters for a shared memory zone that will keep states for various keys.

因为这是区域的通用定义。他们的区别在于以“特别”开头的句子:

In particular, the state stores the current number of excessive requests.

对于limit_req_zone

In particular, the state includes the current number of connections.

对于 limit_conn_zone

每个指令创建的区域将在与键关联的状态中存储不同的信息。在一种情况下,它是过多请求的数量,而在另一种情况下,它是连接数。既然信息不同,自然大小也就不同。因此,每个指令将“存储状态”的大小描述为不同的值。他们可以(但不一定必须,由您决定)使用与密钥相同的变量,例如 $binary_remote_addr。在这种情况下,键的大小将相同,但它们与每个区域中与这些键关联的状态大小无关。