流模块#
核心流模块实现了处理 TCP 和 UDP 连接的基本功能:包括定义服务器块、流量路由、配置代理、SSL/TLS 支持,以及管理流式服务(如数据库、DNS 和其他基于 TCP 和 UDP 运行的协议)的连接。
本节中的其他模块扩展了此功能,允许您灵活地配置和优化流服务器以适应各种场景和需求。
当 从源代码构建 时,
此模块默认不会被构建;
应使用
默认值 — server 设置服务器将接受连接的套接字的 address 和 port。可以只指定 port,这样 Angie 将监听所有可用的 IPv4(以及 IPv6,如果已启用)接口。地址也可以是主机名,例如: IPv6 地址用方括号指定: UNIX 域套接字使用 端口范围通过用连字符分隔的第一个和最后一个端口来指定: 备注 不同的服务器必须监听不同的 address:port 对。 允许指定在此端口上接受的所有连接应在 SSL 模式下工作。 配置监听套接字以处理数据报。为了在同一会话中处理来自相同地址和端口的数据包,还应指定 reuseport 参数。 允许指定在此端口上接受的所有连接应使用 PROXY 协议。 为监听套接字设置关联的路由表 FIB( 为监听套接字启用"TCP Fast Open",并 限制 尚未完成三次握手的连接队列的最大长度。 警告 除非服务器能够处理多次接收 相同的带数据的 SYN 数据包,否则不要启用此功能。 设置 设置监听套接字的接收缓冲区大小( 设置监听套接字的发送缓冲区大小( 设置监听套接字的接受过滤器名称( 指示在 Linux 上使用延迟 此参数指示为给定的 address:port 对进行单独的 此参数(通过 此参数指示为每个工作进程创建单独的监听套接字(在 Linux 3.9+ 和 DragonFly BSD 上使用 警告 不当使用此选项可能会带来安全隐患。 启用通过 多路径 TCP
<https://en.wikipedia.org/wiki/Multipath_TCP>`__(MPTCP)协议接受连接,从 5.6 版本开始在 Linux 内核中支持。
此参数与 :samp:`udp 不兼容。 配置监听套接字的"TCP keepalive"行为。 如果省略此参数,则套接字将使用操作系统的设置 为套接字开启 SO_KEEPALIVE 选项 为套接字关闭 SO_KEEPALIVE 选项 某些操作系统支持使用 例如, 将空闲超时(TCP_KEEPIDLE)设置为 30 分钟,将探测间隔(TCP_KEEPINTVL)保留为系统默认值,并将探测次数(TCP_KEEPCNT)设置为 10 次探测。 指定 预读 缓冲区的大小。 指定 预读 阶段的超时时间。 指定读取 PROXY 协议头完成的超时时间。如果在此时间内未传输完整个头部,则连接将被关闭。 默认值 — stream, server, upstream 配置用于将上游服务器名称解析为地址的域名服务器,例如: 地址可以指定为域名或 IP 地址,并可选端口。如果未指定端口,则使用端口 53。域名服务器以轮询方式查询。 备注 该指令值会被嵌套块继承,
并可在其中根据需要覆盖。
在单个块内,该指令只能指定一次。
如果重复指定,则最后的定义生效。 默认情况下,Angie 使用响应的 TTL 值缓存答案。如果
未指定 可选 参数允许覆盖响应缓存的有效期 默认情况下,Angie 在解析时会同时查找 IPv4 和 IPv6 地址。 禁用 IPv4 地址查找 禁用 IPv6 地址查找 可选 参数;
在指定区域中启用 DNS 服务器请求和响应指标的收集
(/status/resolvers/<zone>) 小技巧 为防止 DNS 欺骗,建议在适当安全的可信本地网络中使用 DNS 服务器。 小技巧 在 Docker 中运行时,使用相应的内部 DNS 服务器地址,例如 设置名称解析的超时时间,例如: 设置服务器的配置。 设置虚拟服务器的名称。 警告 在 配置示例: 第一个名称成为主服务器名称。 服务器名称可以包含星号 ( 这些名称称为通配符名称。 您还可以在服务器名称中使用正则表达式,方法是在名称前加上
波浪号 ( 正则表达式可以包含捕获,可在其他指令中使用: 正则表达式中的命名捕获会创建变量,
可在其他指令中使用: 如果指令的参数设置为 按名称搜索虚拟服务器时,如果名称匹配多个
指定的变体(例如,通配符名称和正则表达式
都匹配),将按以下优先级顺序选择第一个匹配的变体: 精确名称 以星号开头的最长通配符名称,例如
以星号结尾的最长通配符名称,例如 第一个匹配的正则表达式(按配置文件中出现的顺序) 设置服务器名称哈希表的桶大小。默认值取决于
处理器缓存行的大小。 设置服务器名称哈希表的最大大小。 分配共享内存区域以收集
/status/stream/server_zones/<zone> 的指标。 多个 单值 zone 语法将当前上下文的所有指标聚合
在一个共享内存区域中: 替代语法允许指定以下参数: key 包含变量的字符串,
其值决定区域中连接的分组。
所有在替换后产生相同值的连接
会被分组在一起。
如果替换产生空值,则不更新指标。 zone 共享内存区域的名称。 count (可选) 用于收集指标的单独组的最大数量。
如果新的 key 值超过此限制,
它们将被分组到 zone 下。 默认值为 1。 在以下示例中,
所有具有相同 生成的指标在 API 输出中按各个服务器拆分。 提供配置文件上下文,在其中指定流服务器指令。 启用或禁用 TCP_NODELAY 选项的使用。该选项对客户端连接和到代理服务器的连接都启用。 设置变量哈希表的桶大小。设置哈希表的详细信息在单独的 文档 中提供。 设置变量哈希表的最大大小。设置哈希表的详细信息在单独的 文档 中提供。 核心 stream 模块支持以下内置变量: Angie 版本 二进制形式的客户端地址,IPv4 地址的值长度始终为 4 字节,IPv6 地址为 16 字节 从客户端接收的字节数 发送到客户端的字节数 连接序列号 主机名 当前时间(秒),精度为毫秒 工作进程的 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 协议。 客户端地址 客户端端口 接受连接的服务器地址。
计算此变量的值通常需要一次系统调用。为了避免系统调用,:ref:s_listen 指令必须指定地址并使用 接受连接的服务器端口 会话持续时间,以秒为单位,精确到毫秒 会话状态,可以是以下之一: 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;
ssludpproxy_protocollisten 指令可以有几个与套接字相关的系统调用特定的附加参数。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。deferredaccept() (TCP_DEFER_ACCEPT 套接字选项)。bindbind() 调用。事实上,如果有多个具有相同 port 但不同地址的 listen 指令,并且其中一个 listen 指令监听给定端口的所有地址(*:port),Angie 将只 bind() 到 *:port。应该注意的是,在这种情况下将进行 getsockname() 系统调用以确定接受连接的地址。如果使用了 setfib、fastopen、backlog、rcvbuf、sndbuf、accept_filter、deferred、ipv6only、reuseport 或 so_keepalive 参数,则对于给定的 address:port 对将始终进行单独的 bind() 调用。ipv6only=on | offIPV6_V6ONLY 套接字选项)确定监听通配符地址 [::] 的 IPv6 套接字是仅接受 IPv6 连接还是同时接受 IPv6 和 IPv4 连接。此参数默认开启。它只能在启动时设置一次。reuseportSO_REUSEPORT 套接字选项,或在 FreeBSD 12+ 上使用 SO_REUSEPORT_LB),允许内核在工作进程之间分配传入连接。目前仅在 Linux 3.9+、DragonFly BSD 和 FreeBSD 12+ 上有效。multipathso_keepalive=on | off | [keepidle]:[keepintvl]:[keepcnt]''onoffTCP_KEEPIDLE、TCP_KEEPINTVL 和 TCP_KEEPCNT 套接字选项在每个套接字的基础上设置 TCP keepalive 参数。在这些系统上(目前包括 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;
resolver 指令且不执行动态 DNS 查询
(例如,在 代理 中使用固定名称而不使用
变量时),则不需要指定解析器:名称将在启动时
使用系统解析器进行解析。可选的 valid 参数允许
覆盖此行为:validresolver 127.0.0.53 [::1]:5353 valid=30s;
ipv4=offipv6=offstatus_zone127.0.0.11。resolver_timeout#
resolver_timeout 5s;
server#
server_name#
stream 模块中,:samp:server_name 指令基于服务器名称指示
(SNI),仅适用于 TLS 连接。要使用它,
必须在相应的 server 块中 配置 TLS 终止 或 启用 TLS
预读。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.commail.*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#$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#