流模块#
核心流模块实现了处理 TCP 和 UDP 连接的基本功能:包括定义服务器块、流量路由、配置代理、SSL/TLS 支持,以及管理流式服务(如数据库、DNS 和其他基于 TCP 和 UDP 运行的协议)的连接。
本节中的其他模块扩展了此功能,允许您灵活地配置和优化流服务器以适应各种场景和需求。
当 从源代码构建 时,该模块默认不会被构建;必须通过
构建选项 --with-stream 启用它。
在来自 我们的软件仓库 的包和镜像中,该模块已包含在 构建中。
相关指南
连接处理:会话阶段;按地址和 SNI 选择服务器。
Console Light Web 面板:status_zone 填充 TCP/UDP Zones 选项卡。
配置示例#
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;
}
}
指令#
error_log_user_tag#
Added in version 1.12.0.
为服务器处理的每个会话的 error_log 记录附加一个标签。value 可以包含变量,因此标签可以因会话而异;值为空的标签不会被附加。可以多次指定该指令以添加多个标签。当且仅当当前级别上没有定义 error_log_user_tag 指令时,这些指令才会从上一配置级别继承。
标签仅在使用 format=json 的 error_log 目标中以 tags 列表的形式出现;filter=tag: 在任何格式下都可以匹配它们。
listen#
| |
默认值 | — |
server |
设置服务器将接受连接的套接字的 address 和 port。可以只指定 port,这样 Angie 将监听所有可用的 IPv4(以及 IPv6,如果已启用)接口。地址也可以是主机名,例如:
listen 127.0.0.1:12345;
listen *:12345;
listen 12345; # 与 *:12345 相同
listen localhost:12345;
IPv6 地址用方括号指定:
listen [::1]:12345;
listen [::]:12345;
端口范围通过用连字符分隔的第一个和最后一个端口来指定:
listen 127.0.0.1:12345-12399;
listen 12345-12399;
UNIX 域套接字使用 unix: 前缀指定:
listen unix:/var/run/angie.sock;
| 使该服务器成为给定 address:port 对的默认服务器:它处理服务器名称与该对上其他任何服务器都不匹配的连接。 如果没有任何 |
| 允许指定在此端口上接受的所有连接应在 SSL 模式下工作。 |
| 配置监听套接字以处理数据报。为了在同一会话中处理来自相同地址和端口的数据包,还应指定 reuseport 参数。 此参数与 |
| 允许指定在此端口上接受的所有连接应使用 PROXY 协议。 客户端必须在 proxy_protocol_timeout 指定的时间内发送完整的标头,否则 Angie 会关闭连接。 标头中传递的值会填充 $proxy_protocol_addr 系列变量, 并可通过 RealIP 模块替换客户端地址。 |
listen 指令可以有几个与套接字相关的系统调用特定的附加参数。
| 为监听套接字设置关联的路由表 FIB( |
| 为监听套接字启用"TCP Fast Open",并 限制 尚未完成三次握手的连接队列的最大长度。 警告 除非服务器能够处理多次接收 相同的带数据的 SYN 数据包,否则不要启用此功能。 |
| 设置 |
| 设置监听套接字的接收缓冲区大小( |
| 设置监听套接字的发送缓冲区大小( |
| 设置监听套接字的接受过滤器名称( |
| 指示在 Linux 上使用延迟 |
| 为给定的 address:port 对单独调用 |
| 此参数(通过 |
| 此参数指示为每个工作进程创建单独的监听套接字(在 Linux 3.9+ 和 DragonFly BSD 上使用 警告 不当使用此选项可能会带来安全隐患。 |
| 启用通过 多路径 TCP(MPTCP)协议接受连接,从 5.6 版本开始在 Linux 内核中支持。 |
so_keepalive=on | off | [keepidle]:[keepintvl]:[keepcnt]
配置监听套接字的"TCP keepalive"行为。
| 如果省略此参数,则套接字将使用操作系统的设置 |
| 为套接字开启 SO_KEEPALIVE 选项 |
| 为套接字关闭 SO_KEEPALIVE 选项 |
某些操作系统支持使用 TCP_KEEPIDLE、TCP_KEEPINTVL 和
TCP_KEEPCNT 套接字选项在每个套接字的基础上设置 TCP keepalive 参数。在这
些系统上(目前包括 Linux、NetBSD、DragonFly、FreeBSD 和 macOS),可以使用
keepidle、keepintvl 和 keepcnt 参数进行配置。可以省略一个或两个参数,在这
种情况下,相应套接字选项的系统默认设置将生效。在 macOS 上,keepidle 参数设置的是
TCP_KEEPALIVE 套接字选项,而不是 TCP_KEEPIDLE。
例如,
so_keepalive=30m::10
将空闲超时(TCP_KEEPIDLE)设置为 30 分钟,将探测间隔(TCP_KEEPINTVL)保留为系统默认值,并将探测次数(TCP_KEEPCNT)设置为 10 次探测。
preread_buffer_size#
指定 预读 缓冲区的大小。
preread_timeout#
指定 预读 阶段的超时时间。
proxy_protocol_timeout#
指定读取 PROXY 协议头完成的超时时间。如果在此时间内未传输完整个头部,则连接将被关闭。
resolver#
| |
默认值 |
|
stream, server, upstream |
配置用于将上游服务器名称解析为地址的域名服务器,例如:
resolver 127.0.0.53 [::1]:5353;
地址可以指定为域名或 IP 地址,并可选端口。如果未指定端口,则使用端口 53。域名服务器以轮询方式查询。
除 resolver off; 形式外,必须至少指定一个 DNS 服务器地址或 conf 参数。
备注
建议使用本地可信解析器,例如 127.0.0.53 (systemd-resolved),而非
公共解析器(如 8.8.8.8)。公共解析器会将 DNS 查询暴露给第三方,
并增加缓存投毒攻击的风险。
备注
该指令值会被嵌套块继承, 并可在其中根据需要覆盖。 在单个块内,该指令只能指定一次; 重复指定属于配置错误。
启用域名解析,用于通过变量引用或使用 resolve 参数配置的上游服务器,以及 OCSP stapling。
除了显式的服务器地址外,该指令还识别以下参数:
| 显式禁用域名解析 |
| 从指定文件读取 DNS 服务器地址,如果未指定文件,
则从 |
该文件可以包含 nameserver 行,其格式与系统解析器使用的格式相同:
nameserver 127.0.1.4
nameserver 127.0.1.5
从文件读取的地址会添加到指令中显式指定的任何地址中,然后所有这些地址一起以轮询方式查询。如果文件不存在、无法读取或未列出任何地址,且未显式配置任何地址,则 Angie 回退到默认服务器 127.0.0.1:53。
运行期间,当文件发生变化时,Angie 会重新读取该文件,并更新 DNS 服务器集合。
默认情况下,Angie 会在 DNS 响应中 TTL 值的有效期内缓存每个答案。可选的 valid 参数可覆盖此行为:
| 可选 参数允许覆盖响应缓存的有效期 |
resolver 127.0.0.53 [::1]:5353 valid=30s;
默认情况下,Angie 在解析时会同时查找 IPv4 和 IPv6 地址。
| 禁用 IPv4 地址查找 |
| 禁用 IPv6 地址查找 |
| 可选 参数; 在指定区域中启用 DNS 服务器请求和响应指标的收集 (/status/resolvers/<zone>) |
小技巧
为防止 DNS 欺骗,建议在适当安全的可信本地网络中使用 DNS 服务器。
小技巧
在 Docker 中运行时,使用相应的内部 DNS 服务器地址,例如 127.0.0.11。
resolver_timeout#
设置名称解析的超时时间,例如:
resolver_timeout 5s;
server#
设置服务器的配置。
server_name#
设置虚拟服务器的名称。
警告
在 stream 模块中, server_name 指令基于服务器名称指示
(SNI),仅适用于 TLS 连接。要使用它,
必须在相应的 server 块中配置 Stream SSL 模块以终止 TLS,
或启用 Stream SSL Preread 模块。
配置示例:
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/angie/cert.pem;
ssl_certificate_key /etc/angie/key.pem;
}
第一个名称成为主服务器名称。
服务器名称可以包含星号 (*)
来替换名称的第一部分或最后一部分:
server {
server_name example.com *.example.com www.example.*;
}
这些名称称为通配符名称。
您还可以在服务器名称中使用正则表达式,方法是在名称前加上
波浪号 (~):
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#
分配共享内存区域以收集 /status/stream/server_zones/<zone> 的指标。
多个 server 上下文可以共享同一区域进行数据收集。
共用同一区域的所有 status_zone 指令
必须使用相同的语法;使用替代语法时,
凡是给出 count 之处,其值也必须相同;
否则,由于共享内存区域的大小冲突,配置将无法加载。
单值 zone 语法将当前上下文的所有指标聚合 在一个共享内存区域中:
server {
listen 80;
server_name *.example.com;
status_zone single;
# ...
}
替代语法允许指定以下参数:
key | 包含变量的字符串, 其值决定区域中连接的分组。 所有在替换后产生相同值的连接 会被分组在一起。 如果替换产生空值,则不更新指标。 |
zone | 共享内存区域的名称。 |
count | 用于收集指标的单独组的最大数量。 如果新的 key 值超过此限制, 它们将被分组到 zone 下。 必须指定,除非另一条 |
在以下示例中,
server_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;
}
}
生成的指标在 API 输出中按各个服务器拆分。
备注
仅在设置了 status_zone 时才会收集这些指标。如未设置,对应的
server 将不会出现在 /status/stream/server_zones/<zone>、
「TCP/UDP Zones」小部件
及 Prometheus 输出中,且不会输出任何警告信息。
stream#
提供配置文件上下文,在其中指定流服务器指令。
tcp_nodelay#
启用或禁用 TCP_NODELAY 选项的使用。该选项对客户端连接和到代理服务器的连接都启用。
time_format#
Added in version 1.12.0.
定义一个 $variable 来保存当前本地时间,使用自定义 format 字符串渲染,该字符串由类似 strftime 的说明符以及表示毫秒的 %L 组成。当 $time_local 和 $time_iso8601 无法满足需求时(例如因为它们不提供亚秒级精度),该指令很有用:
time_format $time_ms "%Y-%m-%dT%H:%M:%S.%L%Z";
log_format tf '$time_ms $remote_addr $status';
使用上述格式时,变量 $time_ms 会展开为类似 2024-01-15T14:34:56.789+03:00 的值。
重新定义内置变量(例如 $time_local),或针对同一名称重复使用 time_format,都会使配置加载失败,并报出类似 "the duplicate "..." variable" 的错误。
format 字符串接受以下说明符,这些说明符在与 $time_local 相同的本地时区中求值:
| 4 位数年份 |
| 2 位数年份 |
| 月份, |
| 一个月中的第几天, |
| 一个月中的第几天,空格填充, |
| 小时, |
| 小时, |
| 分钟, |
| 秒, |
| 毫秒, |
| 大写 |
| 小写 |
| 缩写的星期名称, |
| 完整的星期名称, |
| 缩写的月份名称, |
| 完整的月份名称, |
| 时区偏移, |
| 时区偏移,ISO 8601 风格, |
| 换行符 |
| 制表符 |
| 字面量 |
备注
无法识别的说明符会原样复制到输出中,包括前导的 %;位于 format 字符串最末尾的单独 % 会被丢弃。
variables_hash_bucket_size#
设置变量哈希表的桶大小。设置哈希表的详细信息在单独的 文档 中提供。
variables_hash_max_size#
设置变量哈希表的最大大小。设置哈希表的详细信息在单独的 文档 中提供。
内置变量#
核心 stream 模块支持以下内置变量: Angie 版本 二进制形式的客户端地址,IPv4 地址的值长度始终为 4 字节,IPv6 地址为 16 字节 从客户端接收的字节数 发送到客户端的字节数 连接序列号 主机名 当前时间(秒),精度为毫秒 nginx 版本 工作进程的 PID 用于与客户端通信的协议: 来自 PROXY 协议头的客户端地址。
必须先通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。 来自 PROXY 协议头的客户端端口。
必须先通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。 来自 PROXY 协议头的服务器地址。
必须先通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。 来自 PROXY 协议头的服务器端口。
必须先通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。 从 PROXY 协议头获取的 TLV。name 可以是 TLV 类型名称或其数值。在后一种情况下,该值以十六进制指定,并且必须以 0x 开头: SSL TLV 也可以通过 TLV 类型名称和其数值来访问,两者都必须以 支持以下 TLV 类型名称: 支持以下 SSL TLV 类型名称: 还支持以下特殊 SSL TLV 类型名称: 必须先通过在 listen 指令中设置 proxy_protocol 参数来启用 PROXY 协议。 客户端地址 客户端端口 接受连接的服务器地址。
计算此变量的值通常需要一次系统调用。为了避免系统调用, listen 指令必须指定地址并使用 接受连接的服务器端口 会话持续时间,以秒为单位,精度为毫秒 会话状态,可以是以下之一: ISO 8601 标准格式的本地时间 通用日志格式的本地时间$angie_version#$binary_remote_addr#$bytes_received#$bytes_sent#$connection#$hostname#$msec#$nginx_version#$pid#$protocol#TCP 或 UDP$proxy_protocol_addr#$proxy_protocol_port#$proxy_protocol_server_addr#$proxy_protocol_server_port#$proxy_protocol_tlv_<name>#$proxy_protocol_tlv_alpn
$proxy_protocol_tlv_0x01
ssl_ 开头:$proxy_protocol_tlv_ssl_version
$proxy_protocol_tlv_ssl_0x21
alpn (0x01) - 连接上使用的上层协议authority (0x02) - 客户端传递的主机名值unique_id (0x05) - 唯一连接标识符netns (0x30) - 命名空间名称ssl (0x20) - 二进制格式的 SSL TLV 结构ssl_version (0x21) - 客户端连接中使用的 SSL 版本ssl_cn (0x22) - 证书通用名称ssl_cipher (0x23) - 使用的密码套件名称ssl_sig_alg (0x24) - 用于签署证书的算法ssl_key_alg (0x25) - 公钥算法ssl_verify - 客户端证书验证结果:如果客户端提供了证书并且验证成功则为 0,否则为非零值$remote_addr#$remote_port#$server_addr#bind 参数。$server_port#$session_time#$status#$time_iso8601#$time_local#