数据面是真正处理流量的代理组件。它从控制面通过 gRPC xDS 接收配置,运行 HTTP、TCP、UDP 监听器,然后把请求转发到上游服务。
参考配置文件在 dataplane/configs/dataplane/config.yaml。
| 参数 | 类型 | 默认值 | 说明 |
|---|
node_id | string | dp | 数据面实例的唯一标识 |
cluster | string | kind | 所属逻辑集群名 |
node_id 在连到同一个控制面的所有数据面实例中必须唯一。在 Kubernetes 里,Helm chart 自动把这个值设为 Pod 名称。本地开发用 dp 就够了。
cluster 字段把数据面分组到逻辑集群。控制面在跨集群部署时用这个字段把配置路由到正确的数据面组。
| 参数 | 类型 | 默认值 | 说明 |
|---|
control_plane_addr | string | http://127.0.0.1:18080 | 要连接的控制面 gRPC 地址 |
数据面启动时向这个地址打开一条双向 gRPC 流。所有配置推送、健康更新和节点状态报告都走这条连接。生产环境把这个地址指向控制面的 Kubernetes Service。
当控制面开启了 gRPC TLS 之后,把地址改成 https:// 开头。
| 参数 | 类型 | 默认值 | 说明 |
|---|
admin_addr | string | 127.0.0.1:19080 | 数据面 Admin HTTP 服务的监听地址 |
数据面 Admin 服务暴露健康检查、运行时统计和少量管理端点。默认只绑定 localhost,安全考虑。
| 参数 | 类型 | 默认值 | 说明 |
|---|
log.level | string | info,nantian_core::connectors=off | Rust tracing 指令格式的日志过滤 |
log.format | string | json | 输出格式:json 或 text |
log.add_source | bool | false | 日志条目中包含源文件位置 |
log.include_target | bool | false | 包含 tracing target(Rust 模块路径) |
log.include_thread_ids | bool | false | 包含线程 ID |
log.include_thread_names | bool | false | 包含线程名 |
log.non_blocking | bool | true | 使用非阻塞环形缓冲区输出日志 |
log.non_blocking_buffered_lines | int | 65536 | 环形缓冲区容量 |
log.drop_when_full | bool | true | 缓冲区满时丢弃日志 |
level 字段支持 tracing 过滤语法。可以按 Rust 模块设不同级别:info,hyper=warn,tower=debug 表示全局 info 级别,hyper HTTP 库用 warn 级别,tower 中间件用 debug 级别。默认值关掉了 nantian_core::connectors 的冗余输出。
非阻塞日志对高吞吐代理来说很关键。没有非阻塞模式,一个慢速的日志 sink(比如阻塞的磁盘或网络)会拖慢整个代理线程。环形缓冲区吸收突发流量,drop_when_full 保证代理线程不会被日志阻塞。
这些参数控制数据面怎么处理 HTTP 和 TCP 流量:
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.http_capacity.workerThreads | int | 0 | Worker 线程数(0 = CPU 核数) |
runtime_tuning.http_capacity.acceptConcurrency | int | 16 | 并发 TCP accept 操作数 |
runtime_tuning.http_capacity.upstreamKeepalivePoolSize | int | 32768 | 上游连接池中保持的最大空闲连接数 |
runtime_tuning.http_capacity.reusePort | bool/null | null | 开启 SO_REUSEPORT(null = 系统默认) |
workerThreads 为 0 时,运行时按 CPU 核数创建线程。这对 CPU 密集型负载(TLS 拆解、请求头修改、Wasm 过滤器)是最优的。对于 I/O 密集型负载(大部分时间在等上游响应),可以降低这个值让出 CPU 给其他进程。
上游连接池复用和后端服务之间的连接,避免每次请求都走 TCP 握手和 TLS 协商。32768 这个默认值能支持大约这么多并发空闲连接。如果后端服务很多(几百个)或者每个后端并发很高,可以调大这个值。
L4 TCP 代理的缓冲区大小直接影响内存使用和吞吐:
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.tcpProxyBufferBytes | int | 16384 | L4 TCP 代理转发使用的缓冲区大小(字节) |
该缓冲区用于 ntgw-stream 的 L4 TCP 转发。HTTP 代理的响应缓存条目上限由 runtime_tuning.http_cache.maxEntrySizeMb 控制,与此处的 TCP 缓冲区相互独立。
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.downstreamReadTimeoutMs | int | 60000 | 从客户端读取请求的超时(毫秒) |
runtime_tuning.upstream_connection_timeout_ms | int | 5000 | 与上游建立连接的超时(毫秒) |
runtime_tuning.upstream_read_timeout_ms | int | 30000 | 从上游读取响应的超时(毫秒) |
runtime_tuning.upstream_idle_timeout_ms | int | 60000 | 上游 keepalive 连接空闲超时(毫秒) |
upstream_connection_timeout_ms 控制连接后端服务的最大等待时间:若上游在该时间内未接受连接,则放弃该连接。upstream_idle_timeout_ms 控制空闲上游连接在连接池中保留多久,太小会导致频繁重建连接,太大则占用连接池资源。
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_protection.httpGlobalRateLimitRequestsPerSecond | int | 10000 | 全局每秒请求数上限 |
runtime_protection.httpGlobalRateLimitBurst | int | 20000 | 全局突发允许量 |
这是全局限流,作用于所有进入数据面的请求,在路由规则之前生效。更细粒度的按监听器/按路由限流由下方连接保护章节的 runtime_protection.httpListenerRateLimit* 与 httpRouteRateLimit* 参数控制。
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_protection.httpBackendCircuitBreakerMaxRequests | int | 4096 | 单个后端的并发在途请求数上限,超过即触发熔断 |
Nantian 的熔断基于并发在途请求数,而非错误率:当某个后端的并发在途请求达到上限时,新请求快速失败,从而避免拖垮后端。需要按目标做更细粒度熔断时,可通过 BackendLBPolicy 的 circuitBreaker.maxInflightRequests 字段配置。
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.activeHealthCheckEnabled | bool | false | 是否开启主动健康检查 |
runtime_tuning.activeHealthCheckIntervalMs | int | 5000 | 主动健康检查间隔(毫秒) |
runtime_tuning.activeHealthCheckTimeoutMs | int | 1000 | 单次健康检查的超时(毫秒) |
runtime_tuning.activeHealthCheckUnhealthyThreshold | int | 2 | 连续失败多少次标记为不健康 |
数据面可对后端做主动健康检查(默认关闭,通过 activeHealthCheckEnabled 开启)。后端不健康时,流量被路由到其他健康后端;当所有后端都不健康时,数据面返回 503,不把不可用后端暴露给客户端。 | | | |
| 参数 | 类型 | 默认值 | 说明 |
|---|
admin_auth.bearer_token | string | "" | Admin API 静态 Bearer Token |
admin_auth.bearer_token_file | string | "" | 包含 Bearer Token 的文件路径 |
| 用法和控制面的 Admin 认证一样。两个都设空字符串即关闭认证。 | | | |
| 参数 | 类型 | 默认值 | 说明 |
|---|
access_log.enabled | bool | false | 开启按请求访问日志 |
access_log.path | string | stdout | 输出路径,stdout 表示控制台 |
access_log.format | string | (见 config.yaml) | 格式字符串,支持 %VARIABLE% 占位符 |
access_log.mode | string | json | 输出模式:json 或 text |
access_log.sample_rate | float | 0.01 | 日志采样率(1.0 = 全部请求) |
access_log.routeAnnotationPrefix | string | gateway.nantian.dev/access-log- | 按路由覆盖日志配置的 Kubernetes annotation 前缀 |
访问日志记录每个(或抽样)代理请求的详情。格式字符串支持 %METHOD%、%STATUS%、%LATENCY_MS%、%ROUTE_NAME% 等变量。高流量环境下把 sample_rate 调低来控制日志量。 | | | |
routeAnnotationPrefix 允许通过 Kubernetes annotation 按路由覆盖采样率和格式。给某个路由加 gateway.nantian.dev/access-log-sample-rate: "1.0" 就能全量记录该路由的请求。
%RESPONSE_FLAGS% 占位符展开为一个逗号分隔的标志位列表,表明请求为何以特定方式处理。空值或 none 表示请求正常完成。
HTTP 标志位:
| Flag | HTTP 状态 | 说明 |
|---|
none | — | 请求正常完成,无错误 |
NR | 500 | 没有匹配到路由 |
UH | 503 | 没有健康的后端可用 |
CB | 503 | 上游熔断器已打开 |
IB | 500 | BackendRefs 配置无效 |
UF | 500 | 路由引用了不支持的过滤器 |
UT | 504 | 上游连接或响应超时 |
DC | 499 | 客户端在收到响应前断开连接 |
IT | 408 | 请求完成前下游空闲超时 |
UC | 502 | 上游连接意外关闭 |
OL | 503 | 全局过载保护拒绝了请求 |
RL | 429 | 全局限流拒绝了请求 |
RH | 431 | 请求头超过了 maxRequestHeaderBytes 限制 |
RB | 413 | 请求体超过了 maxRequestBodyBytes 限制 |
MA | — | 连接因 httpMaxConnectionAgeMs 被关闭 |
TCP/TLS 流标志位:
| Flag | 说明 |
|---|
NE | 通用网络层错误 |
UE | 上游连接错误 |
DE | 下游连接错误 |
MC | 因连接数达到上限被关闭 |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime.http_listen_addr | string | 0.0.0.0:80 | HTTP 代理监听地址 |
runtime.enable_ipv6 | bool | true | 接受 IPv6 连接 |
runtime.enable_http3 | bool | false | 开启 HTTP/3(QUIC)支持 |
runtime.tls_min_version | string | 1.2 | 入站连接最低 TLS 版本 |
runtime.tls_max_version | string | 1.3 | 入站连接最高 TLS 版本 |
runtime.tlsAssetDir | string | "" | TLS 证书文件目录 |
控制数据面如何连接后端服务:
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.upstream_connection_timeout_ms | int | 5000 | 上游服务连接超时(毫秒) |
runtime_tuning.upstream_read_timeout_ms | int | 30000 | 上游响应的读取超时(毫秒) |
runtime_tuning.upstream_idle_timeout_ms | int | 60000 | 上游 Keep-Alive 连接空闲超时(毫秒) |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.downstreamReadTimeoutMs | int | 60000 | 下游客户端请求的读取超时(毫秒) |
runtime_tuning.httpMaxConnectionAgeMs | int | 0 | 连接最大生命周期(毫秒,0 = 不限制) |
runtime_tuning.httpKeepaliveRequestLimit | int | 0 | 每个 Keep-Alive 连接的最大请求数(0 = 不限制) |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.httpReloadRetryIntervalMs | int | 1000 | HTTP 监听器重载失败时的重试间隔(毫秒) |
runtime_tuning.streamReloadRetryIntervalMs | int | 1000 | Stream 重载失败时的重试间隔(毫秒) |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.tcpProxyBufferBytes | int | 16384 | TCP 代理数据缓冲区大小(字节) |
runtime_tuning.tcpSessionIdleTimeoutMs | int | 0 | TCP 会话空闲超时(毫秒,0 = 不超时) |
runtime_tuning.tcpMaxConnectionAgeMs | int | 0 | TCP 连接最大生命周期(毫秒,0 = 不限制) |
重试预算防止重试风暴压垮后端:
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.retryBudgetEnabled | bool | true | 开启重试预算控制 |
runtime_tuning.retryBudgetRatioPercent | int | 20 | 重试与成功请求的最大比例(%) |
runtime_tuning.retryBudgetBurst | int | 16 | 超过预算限额的最大突发值 |
重试预算确保重试不会加剧后端故障。当重试次数与成功请求的比例超过 retryBudgetRatioPercent 时,数据面停止重试,直到比例恢复。retryBudgetBurst 允许在稳态比例之上有短暂的突发。 | | | |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.streamUpstreamPoolSize | int | 128 | 上游池中保持的最大空闲流连接数 |
runtime_tuning.streamUpstreamPoolIdleTimeoutMs | int | 30000 | 流上游连接的空闲超时(毫秒) |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.work_stealing | bool | true | 启用 Tokio 跨工作线程的工作窃取 |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.http_cache.enabled | bool | false | 启用 HTTP 响应缓存 |
runtime_tuning.http_cache.maxSizeMb | int | 256 | 最大缓存大小(MB) |
runtime_tuning.http_cache.defaultTtlSeconds | int | 60 | 默认缓存 TTL(秒) |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.graceful_drain_period_ms | int | 0 | 优雅关闭排空时间(毫秒,0 = 不排空) |
数据面收到 SIGTERM(Pod 终结)后,停止接受新连接,在此时间内排空现有连接。设为 0 则立即关闭代理。Kubernetes 部署常见值为 30000(30 秒)。 | | | |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.activeHealthCheckEnabled | bool | false | 开启对上游的主动健康检查 |
runtime_tuning.activeHealthCheckIntervalMs | int | 5000 | 健康检查探测间隔(毫秒) |
runtime_tuning.activeHealthCheckTimeoutMs | int | 1000 | 单次探测超时(毫秒) |
runtime_tuning.activeHealthCheckUnhealthyThreshold | int | 2 | 连续失败多少次标记为不健康 |
| 主动健康检查定期向后端发送请求,在生产流量之外验证后端存活性。它和被动健康检查(从真实请求中检测故障)互补,能发现那些没在接收流量的后端的问题。 | | | |
TCP Keepalive 探测在操作系统层面检测死连接:
下游 TCP Keepalive:
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.downstreamTcpKeepalive.enabled | bool | false | 开启下游连接 TCP Keepalive |
runtime_tuning.downstreamTcpKeepalive.idleMs | int | 60000 | 发送探测前的空闲时间(毫秒) |
runtime_tuning.downstreamTcpKeepalive.intervalMs | int | 15000 | 探测间隔(毫秒) |
runtime_tuning.downstreamTcpKeepalive.probeCount | int | 4 | 判定死亡前的探测次数 |
runtime_tuning.downstreamTcpKeepalive.userTimeoutMs | int | 0 | 用户超时覆盖(毫秒,0 = 系统默认) |
上游 TCP Keepalive 使用 runtime_tuning.upstream_tcp_keepalive 下相同的字段,默认 enabled: true。 | | | |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.downstream_tcp_fastopen | bool | null | 下游启用 TCP Fast Open(null = 自动检测) |
runtime_tuning.downstream_dscp | int | null | 下游连接 DSCP 标记(null = 禁用) |
runtime_tuning.upstream_tcp_recv_buf | int | 0 | 上游 TCP 接收缓冲区大小(字节,0 = 系统默认) |
runtime_tuning.upstream_tcp_fast_open | bool | true | 上游启用 TCP Fast Open |
runtime_tuning.upstream_dscp | int | null | 上游连接 DSCP 标记(null = 禁用) |
TCP Fast Open 通过在初始 TCP 握手期间发送数据来减少连接延迟。DSCP(区分服务代码点)标记可在网络层面实现 QoS 优先级。
保护限制防止异常客户端或后端导致资源耗尽:
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_protection.httpGlobalInflightLimit | int | 16384 | 所有监听器并发请求数上限 |
runtime_protection.httpListenerInflightLimit | int | 8192 | 每个监听器并发请求数上限 |
runtime_protection.httpRouteInflightLimit | int | 4096 | 每个路由并发请求数上限 |
runtime_protection.httpBackendCircuitBreakerMaxRequests | int | 4096 | 单个后端并发请求熔断阈值 |
runtime_protection.httpMaxRequestBodyBytes | int | 10485760 | 请求体最大大小(字节,0 = 不限制) |
runtime_protection.httpMaxRequestHeaderBytes | int | 65536 | 请求头最大大小(字节,0 = 不限制) |
全局、按监听器、按路由的限流:
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_protection.httpGlobalRateLimitRequestsPerSecond | int | 10000 | 全局请求速率限制(0 = 不限制) |
runtime_protection.httpGlobalRateLimitBurst | int | 20000 | 全局突发允许量 |
runtime_protection.httpListenerRateLimitRequestsPerSecond | int | 5000 | 每个监听器请求速率限制 |
runtime_protection.httpListenerRateLimitBurst | int | 10000 | 每个监听器突发允许量 |
runtime_protection.httpRouteRateLimitRequestsPerSecond | int | 2000 | 每个路由请求速率限制 |
runtime_protection.httpRouteRateLimitBurst | int | 4000 | 每个路由突发允许量 |
限流采用令牌桶算法。Burst 决定桶的深度:100 的速率配 50 的突发,第一个瞬间允许 150 个请求,之后稳定在每秒 100 个。 | | | |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_protection.tcpGlobalConnectionLimit | int | 32768 | 最大并发 TCP 连接数 |
runtime_protection.tcpListenerConnectionLimit | int | 8192 | 每个监听器最大 TCP 连接数 |
runtime_protection.udpGlobalDatagramLimit | int | 100000 | 最大并发 UDP 数据报数 |
runtime_protection.udpListenerDatagramLimit | int | 50000 | 每个监听器最大 UDP 数据报数 |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.requestMirrorMaxConcurrency | int | 1024 | 最大并发镜像请求数 |
| 请求镜像将生产流量复制一份发送到次要后端,用于测试或金丝雀分析。这个限制控制飞行中的镜像请求数,防止镜像消耗过多资源。 | | | |
| 参数 | 类型 | 默认值 | 说明 |
|---|
session_persistence.secret_key | string | "" | 会话 Cookie 加密密钥 |
session_persistence.secret_key_file | string | "" | 包含密钥的文件路径 |
会话保持(粘性会话)需要密钥来加密会话 Cookie。二选一配置 secret_key 或 secret_key_file。生产环境建议用文件方式,密钥从 Kubernetes Secret 挂载。 | | | |
| 参数 | 类型 | 默认值 | 说明 |
|---|
runtime_tuning.udpResponseIdleTimeoutMs | int | 500 | UDP 响应会话空闲超时(毫秒) |
xDS 连接控制面的传输参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|
xdsTransport.connect_timeout_ms | int | 5000 | 建立 xDS 连接的超时时间(毫秒) |
xdsTransport.keepalive_interval_ms | int | 10000 | xDS keepalive ping 间隔(毫秒) |
xdsTransport.keepaliveTimeoutMs | int | 5000 | xDS keepalive ping 响应超时(毫秒) |
xdsTransport.initialReconnectBackoffMs | int | 2000 | xDS 重连初始退避时间(毫秒) |
xdsTransport.maxReconnectBackoffMs | int | 30000 | xDS 重连最大退避时间(毫秒) |
xdsTransport.applyTimeoutMs | int | 3000 | 应用接收到的配置快照的超时时间(毫秒) |
xdsTransport.applyPollIntervalMs | int | 100 | 等待快照应用时的轮询间隔(毫秒) |
xdsTransport.staleStreamTimeoutMs | int | 30000 | 将陈旧 xDS 流视为失败的时间(毫秒) |
xdsTransport.snapshotFreshnessTimeoutMs | int | 90000 | 将当前快照视为过期的时间(毫秒) |
连接断开时,数据面使用指数退避重连,从 initialReconnectBackoffMs 开始,每次翻倍,最多到 maxReconnectBackoffMs。applyTimeoutMs 和 applyPollIntervalMs 控制快照应用过程。
| 参数 | 类型 | 默认值 | 说明 |
|---|
experimental.enableExperimentalGateway | bool | false | 开启实验性 Gateway API 功能 |
experimental.enableAiGateway | bool | false | 开启 AI 网关模块 |
| 必须和控制面的功能开关保持一致。只在一侧开启会导致行为不一致。 | | | |