流模块#
核心流模块实现了处理 TCP 和 UDP 连接的基本功能:这包括定义服务器块、流量路由、配置代理、SSL/TLS 支持,以及管理用于流式服务(如数据库、DNS 和其他通过 TCP 和 UDP 操作的协议)的连接。
本节中的其他模块扩展了此功能,使您能够灵活地配置和优化流服务器以满足各种场景和需求。
当 从源代码构建 时,此模块默认不构建;它应通过 默认 — server 设置服务器将接受连接的套接字的 address 和 port。可以只指定 port。地址也可以是主机名,例如: IPv6 地址用方括号指定: UNIX 域套接字用 端口范围用第一个和最后一个端口用连字符分隔: 重要 不同的服务器必须侦听不同的 address:port 组合。 允许指定所有在此端口上接受的连接应在 SSL 模式下工作。 配置用于处理数据报的监听套接字。为了在同一会话中处理来自同一地址和端口的数据包,还应指定 reuseport 参数。 允许指定所有在此端口上接受的连接应使用 PROXY 协议。 listen 指令可以有几个与套接字相关的系统调用的附加参数。 为正在监听的套接字设置关联的路由表,FIB (即 为监听套接字启用 "TCP 快速打开",并限制尚未完成三次握手的连接队列的最大长度 <https://datatracker.ietf.org/doc/html/rfc7413#section-5.1>。 小心 除非服务器能够处理接收相同的 SYN 数据包 <https://datatracker.ietf.org/doc/html/rfc7413#section-6.1> 多次,否则请不要启用此功能。 设置 设置监听套接字的接收缓冲区大小 (即 设置监听套接字的发送缓冲区大小 (即 设置监听套接字的接收过滤器名称 (即 指示在 Linux 上使用延迟 此参数指示对给定的 address:port 组合进行单独的 此参数确定 (通过 此参数指示为每个工作进程创建一个独立的监听套接字 (在 Linux 3.9+ 和 DragonFly BSD 上使用 小心 不当使用此选项可能会带来安全隐患。 如果省略此参数,则将对套接字生效操作系统的设置。 为套接字开启 SO_KEEPALIVE 选项。 为套接字关闭 SO_KEEPALIVE 选项。 某些操作系统支持使用 例如, 将把空闲超时 (TCP_KEEPIDLE) 设置为 30 分钟,将探测间隔 (TCP_KEEPINTVL) 保持为系统默认值,并将探测计数 (TCP_KEEPCNT) 设置为 10 次探测。 指定 preread 缓冲区的大小。 指定 preread 阶段的超时。 指定读取 PROXY 协议头以完成的 timeout。如果在此时间内未传输整个头,则连接将关闭。 默认 — stream, server, upstream 配置用于将上游服务器的名称解析为地址的名称服务器,例如: 地址可以指定为域名或 IP 地址,并可选指定端口。如果未指定端口,则使用端口 53。名称服务器以循环的方式查询。 默认情况下,Angie 使用响应的 TTL 值缓存答案。可选的 valid 参数允许覆盖它: 可选 valid 参数允许覆盖缓存条目的有效性。 默认情况下,Angie 在解析时会查找 IPv4 和 IPv6 地址。 禁用 IPv4 地址的查找。 禁用 IPv6 地址的查找。 可选 参数;允许在指定区域中收集 DNS 服务器请求和响应指标 (/status/resolvers/<zone>)。 小技巧 为防止 DNS 欺骗,建议在适当安全的受信任本地网络中配置 DNS 服务器。 提示 当在 Docker 中运行时,使用其内部 DNS 服务器地址,例如 设置名称解析的超时时间,例如: 设置服务器的配置。 设置虚拟服务器的名称,例如: 第一个名称成为主服务器名称。 服务器名称可以包含星号 ( 这些名称称为通配符名称。 上述两个示例可以合并为一个: 您还可以通过在名称前加上波浪号 ( 正则表达式可以包含捕获
可以在其他指令中使用: 正则表达式中的命名捕获会创建变量
可以在其他指令中使用: 如果指令的参数设置为 在通过名称查找虚拟服务器时,如果名称与多个指定变体匹配(例如同时是通配符名称和正则表达式匹配),将按照以下优先级选择第一个匹配变体: 精确名称 以星号开头的最长通配符名称,例如,
以星号结尾的最长通配符名称,例如 第一个匹配的正则表达式(按出现在配置文件中的顺序) 注意 对于 TLS 连接,
请使用 SSL Preread 模块。 设置服务器名称哈希表的桶大小。默认值取决于处理器缓存行的大小。 设置服务器名称哈希表的最大大小。 分配一个共享内存区域以收集
/status/stream/server_zones/<zone> 的指标。 多个 单值 zone 语法会将其上下文的所有指标聚合到同一个共享内存区域: 替代语法使用以下参数: key 包含变量的字符串,
其值决定了连接在区域中的分组。
所有在替换后产生相同值的连接将被分为一组。
如果替换结果为空,则不更新指标。 zone 共享内存区域的名称。 count (可选) 收集指标的最大分组数。
如果新的 key 值超过此限制,
则将它们归入 zone 下。 默认值为1。 在以下示例中,
所有共享相同 因此,最终的指标在 API 输出中在各个服务器之间分配。 提供配置文件上下文,在其中指定流服务器指令。 启用或禁用 TCP_NODELAY 选项。该选项对客户端和代理服务器连接均启用。 设置变量哈希表的桶大小。设置哈希表的详细信息在单独的 文档 中提供。 设置变量哈希表的最大大小。设置哈希表的详细信息在单独的 文档 中提供。 stream core 模块支持以下变量: Angie 版本 以二进制形式表示的客户端地址,IPv4 地址的值长度始终为 4 字节,IPv6 地址为 16 字节 从客户端接收的字节数 发送到客户端的字节数 连接序列号 主机名 当前时间(以秒为单位,精确到毫秒) 工作进程的 PID 与客户端通信使用的协议: 来自 PROXY 协议头的客户端地址 来自 PROXY 协议头的客户端端口 来自 PROXY 协议头的服务器地址 来自 PROXY 协议头的服务器端口 来自 PROXY 协议头的 TLV。 name 可以是 TLV 类型或其数字值。在后者情况下,值为十六进制并应以 0x 为前缀: $proxy_protocol_tlv_alpn SSL TLV 也可以通过 TLV 类型名称或其数字值访问,两者都以 ssl_ 为前缀: $proxy_protocol_tlv_ssl_version 支持以下 TLV 类型名称: alpn (0x01) - 连接中使用的上层协议 authority (0x02) - 客户端传递的主机名值 unique_id (0x05) - 唯一连接 ID netns (0x30) - 命名空间的名称 ssl (0x20) - 二进制 SSL TLV 结构 支持以下 SSL TLV 类型名称: ssl_version (0x21) - 客户端连接中使用的 SSL 版本 ssl_cn (0x22) - SSL 证书的通用名称 ssl_cipher (0x23) - 使用的密码名称 ssl_sig_alg (0x24) - 用于签署证书的算法 ssl_key_alg (0x25) - 公钥算法 此外,支持以下特殊 SSL TLV 类型名称: ssl_verify - 客户端 SSL 证书验证结果,0 表示客户端提供了证书并成功验证,非零表示其他情况。 必须通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。 客户端地址 客户端端口 接受连接的服务器地址 接受连接的服务器端口 会话持续时间(以秒为单位,精确到毫秒) 会话状态,可以是以下之一: ISO 8601标准格式的本地时间 常见日志格式的本地时间‑‑with‑stream
构建选项 启用。在来自 我们的仓库 的软件包和镜像中,该模块已包含在构建中。配置示例#
worker_processes auto;
error_log /var/log/angie/error.log info;
events {
worker_connections 1024;
}
stream {
upstream backend {
hash $remote_addr consistent;
server backend1.example.com:12345 weight=5;
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns {
server 192.168.0.1:53535;
server dns.example.com:53;
}
server {
listen 12345;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass backend;
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}
指令#
listen#
listen
address[:port] [ssl
] [udp
] [proxy_protocol
] [setfib=
number] [fastopen=
number] [backlog=
number] [rcvbuf=
size] [sndbuf=
size] [accept_filter=
filter] [deferred
] [bind
] [ipv6only=
on
| off
] [reuseport
] [so_keepalive=
on|off|[keepidle]:[keepintvl]:[keepcnt]];listen 127.0.0.1:12345;
listen *:12345;
listen 12345; # 同 *:12345
listen localhost:12345;
listen [::1]:12345;
listen [::]:12345;
unix:
前缀指定:listen unix:/var/run/angie.sock;
listen 127.0.0.1:12345-12399;
listen 12345-12399;
ssl
udp
proxy_protocol
setfib=
numberSO_SETFIB
选项)。此功能目前仅在 FreeBSD 上有效。fastopen=
numberbacklog=
numberlisten()
调用中的 backlog
参数,限制待处理连接队列的最大长度。默认情况下,在 FreeBSD、DragonFly BSD 和 macOS 上,backlog
设置为 -1
,在其他平台上设置为 511。rcvbuf=
sizeSO_RCVBUF
选项)。sndbuf=
sizeSO_SNDBUF
选项)。accept_filter=
filterSO_ACCEPTFILTER
选项),在将传入连接传递给 accept()
之前过滤它们。此功能仅在 FreeBSD 和 NetBSD 5.0+ 上有效。可接受的值为 dataready
和 httpready
。deferred
accept()
(即 TCP_DEFER_ACCEPT
套接字选项)。bind
bind()
调用。实际上,如果有多个 listen 指令具有相同的 port 但不同的地址,并且其中一个 listen
指令为给定端口监听所有地址 (*:port),则 Angie 仅会对 *:port 进行 bind()
。需要注意的是,在这种情况下,将会调用 getsockname()
系统调用以确定接受连接的地址。如果使用了 setfib
、fastopen
、backlog
、rcvbuf
、sndbuf
、accept_filter
、deferred
、ipv6only
、reuseport
或 so_keepalive
参数,则对于给定的 address:port 组合将始终进行单独的 bind()
调用。ipv6only=on
| off
IPV6_V6ONLY
套接字选项) IPv6 套接字在通配地址 [::] 上是否仅接受 IPv6 连接或同时接受 IPv6 和 IPv4 连接。此参数默认开启。它只能在启动时设置一次。reuseport
SO_REUSEPORT
套接字选项,或在 FreeBSD 12+ 上使用 SO_REUSEPORT_LB
),允许内核在工作进程之间分配传入连接。此功能目前仅在 Linux 3.9+、DragonFly BSD 和 FreeBSD 12+ 上有效。so_keepalive=on
| off
| [keepidle]:[keepintvl]:[keepcnt]
配置监听套接字的 "TCP 保持活动" 行为。''
on
off
TCP_KEEPIDLE
、TCP_KEEPINTVL
和 TCP_KEEPCNT
套接字选项在每个套接字的基础上设置 TCP 保持活动参数。在此类系统上(目前,Linux 2.4+、NetBSD 5+ 和 FreeBSD 9.0-STABLE),可以使用 keepidle、keepintvl 和 keepcnt 参数进行配置。可以省略一个或两个参数,在这种情况下,将对相应的套接字选项使用系统默认设置。so_keepalive=30m::10
preread_buffer_size#
preread_timeout#
proxy_protocol_timeout#
resolver#
resolver
address ... [valid=
time] [ipv4=
on
| off
] [ipv6=
on
| off
] [status_zone=
zone];resolver 127.0.0.53 [::1]:5353;
valid
resolver 127.0.0.53 [::1]:5353 valid=30s;
ipv4=off
ipv6=off
status_zone
127.0.0.11
。resolver_timeout#
resolver_timeout 5s;
server#
server_name#
server {
server_name example.com www.example.com;
}
*
)
以替代名称的首部或尾部:server {
server_name example.com *.example.com www.example.*;
}
server {
server_name .example.com;
}
~
) 使用正则表达式:server {
server_name www.example.com ~^www\d+\.example\.com$;
}
server {
server_name ~^(www\.)?(.+)$;
proxy_pass www.$2:12345;
}
server {
server_name ~^(www\.)?(?<domain>.+)$;
proxy_pass www.$domain:12345;
}
$hostname
,则插入机器的主机名。*.example.com
mail.*
server_names_hash_bucket_size#
server_names_hash_max_size#
status_zone#
server
上下文可以共享同一区域进行数据收集。server {
listen 80;
server_name *.example.com;
status_zone single;
# ...
}
$server_addr
值的连接
被分组到 host_zone
中。
对于每个唯一的 $server_addr
跟踪指标,
直到达到10个指标组。
一旦达到此限制,
任何额外的 $server_addr
值将被包含在 server_zone
下:stream {
upstream backend {
server 192.168.0.1:3306;
server 192.168.0.2:3306;
# ...
}
server {
listen 3306;
proxy_pass backend;
status_zone $server_addr zone=server_zone:10;
}
}
stream#
tcp_nodelay#
variables_hash_bucket_size#
variables_hash_max_size#
内置变量#
$angie_version
#$binary_remote_addr
#$bytes_received
#$bytes_sent
#$connection
#$hostname
#$msec
#$pid
#$protocol
#TCP
或 UDP
$proxy_protocol_addr
#
必须通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。$proxy_protocol_port
#
必须通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。$proxy_protocol_server_addr
#
必须通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。$proxy_protocol_server_port
#
必须通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。$proxy_protocol_tlv_<name>
#
$proxy_protocol_tlv_0x01
$proxy_protocol_tlv_ssl_0x21$remote_addr
#$remote_port
#$server_addr
#
计算此变量的值通常需要一次系统调用。为了避免系统调用, listen 指令必须指定地址并使用 bind
参数。$server_port
#$session_time
#$status
#$time_iso8601
#$time_local
#