跳到主要内容

命令行参数 & 配置文件(静态配置)

Aidy Gateway 的配置包括「静态配置」与「PG 运行时配置」。其中,静态配置指的是在启动时读取并使用的配置,通过命令行或配置文件指定、不会热更新,用于指定程序的监听地址、管理端口、PG 连接信息以及静态插件配置(如 Log/Guard)等;而路由、租户、消费者、上游等运行时配置则统一来自 PostgreSQL。

本文档介绍的是静态配置。

静态配置来源于命令行参数与配置文件。可通过 -c--config 指定配置文件,配置文件格式为 TOML。当同一配置在命令行与配置文件中同时指定时,命令行参数优先生效。

命令行参数

  • -c, --config: 启动配置文件(TOML)(必须显式指定)
  • -l, --listen: 网关监听地址(默认 :12580
  • --root-redirect-url: gateway 入口收到 GET / 时返回 302 跳转到的绝对 URL(可选;未配置时保持当前行为)
  • --data-dir: 已废弃的兼容参数,当前为 NO-OP,无实际效果
  • --shutdown-max-wait: 进程退出时等待仍在处理中的 HTTP 请求的最长时间(Go time.Duration,默认 1m
  • --management-listen: Management API 监听地址(默认 :12581
  • --config-source: 运行时配置来源,当前仅支持 pg
  • --config-pg-ro: 运行时只读 PostgreSQL 连接串(必填)
  • --config-pg-rw: 预留的读写 PostgreSQL 连接串(可选)
  • --rate-limit-redis: 限速存储使用的 Redis 地址(可选,未配置时限速相关能力不可用)
  • --rate-limit-headers-mode: 限速响应头返回策略(always | on-limit | never,默认 on-limit
  • --enable-dashboard: 是否启用 Dashboard(默认 false)
  • --enable-log: 启用请求日志插件(默认 false)
  • --log-unknown-routes: 记录未知路由日志(默认 false)
  • --log-unauthenticated-routes: 记录未授权路由日志(默认 false)
  • --log-hide-sensitive-data: 是否隐藏日志中的敏感信息(默认 true)
  • --log-remote-addr-source: 远程地址来源(connecting_ip | header | xff,默认 connecting_ip
  • --log-remote-addr-header: 当 log-remote-addr-source=header 时,取哪个 Header 的值
  • --log-remote-addr-xff: 当 log-remote-addr-source=xff 时,取第几个 IP(正数从左、负数从右)
  • --log-store-full-body-in-pg: 是否把完整请求/响应 body 额外写入 PostgreSQL request_logs.raw(默认 false)
  • --log-destination: 日志目的地(http | kafka | none
  • --log-output-format: 日志目的地输出编码(json | binary,默认 json
  • --log-http-method: HTTP 上报方法(例如 POST
  • --log-http-url: HTTP 上报地址
  • --log-http-basic-username: HTTP 基本认证用户名
  • --log-http-basic-password: HTTP 基本认证密码
  • --log-kafka-brokers: Kafka broker 列表(逗号分隔)
  • --log-kafka-topic: Kafka 目标 topic
  • --log-kafka-tls-enable: Kafka 是否启用 TLS
  • --log-kafka-tls-ca: Kafka TLS CA 证书路径
  • --log-kafka-tls-cert: Kafka TLS 客户端证书路径
  • --log-kafka-tls-key: Kafka TLS 客户端私钥路径
  • --log-kafka-tls-insecure-skip-verify: Kafka TLS 跳过证书校验
  • --enable-guard: 启用 Guard 插件(默认 false)
  • --guard-check-service-url: Guard 检测服务地址
  • --guard-timeout-ms: Guard 超时时间(毫秒)
  • --enable-semantic-cache: 启用语义缓存插件(默认 false)
  • --semantic-cache-embedding-service-url: 语义缓存 embedding 服务地址
  • --semantic-cache-embedding-model: 语义缓存 embedding 模型名
  • --semantic-cache-embedding-api-key: 语义缓存 embedding API key
  • --semantic-cache-embedding-dimensions: 语义缓存 embedding 向量维度
  • --semantic-cache-embedding-timeout-ms: 语义缓存 embedding 超时(毫秒)
  • --semantic-cache-redis: 语义缓存 Redis 地址
  • --enable-prompt-compressor: 启用语义压缩插件(默认 false)
  • --prompt-compressor-service-url: 语义压缩服务地址
  • --prompt-compressor-timeout-ms: 语义压缩服务超时(毫秒)
  • --upstream-max-idle-conns-per-host: 上游 HTTP Transport 的默认 MaxIdleConnsPerHost(默认 512

说明:当前 V2 运行时只支持 PostgreSQL,不再支持 fileredis-v1redis-v2 等旧动态配置源。

本地初始化 PG 运行时数据,建议结合以下文档一起看:

配置文件

listen = ":12580"
# root_redirect_url = "https://example.com"
shutdown_max_wait = "1m"

[rate-limit]
redis = "redis://localhost:6379/1"
headers_mode = "on-limit"

[upstream]
max_idle_conns_per_host = 512

[upstream.ssrf_protection]
enabled = true
allow_private_network = false
domain_list_mode = "blacklist"
domain_list = []
ip_list_mode = "blacklist"
ip_list = []
allowed_ports = [] # 空数组表示允许全部端口;也支持 "80" 或 "8000-8999"

[dynamic-config]
source = "pg"
pg_ro = "postgres://postgres:postgres@localhost:5432/aidy?sslmode=disable"
pg_rw = "postgres://postgres:postgres@localhost:5432/aidy?sslmode=disable" # 必填,management ConnectRPC API 使用

[management-server]
listen = ":12581"
[management-server.dashboard]
enable = true
[plugins.log]
enable = true
log_unknown_routes = true
log_unauthenticated_routes = true
hide_sensitive_data = true # 默认 true;如需在日志中显示密钥可设为 false
store_full_body_in_pg = true # 默认 false;开启后会把完整 body 写入 request_logs.raw
destination = "http" # or kafka or none
output_format = "json" # or binary;默认 json
[plugins.log.http]
method = "POST"
url = "http://127.0.0.1:19091/ingest/request-logs"
[plugins.log.remote_addr]
source = "connecting_ip" # or header or xff
header = "X-Real-IP" # 当 source=header 时取哪个 Header 的值
xff = 1 # 当 source=xff 时取第几个 IP

#[plugins.log.kafka]
#brokers = ["127.0.0.1:9092", "127.0.0.1:9093"]
#topic = "aidy-logs"
# [plugins.log.kafka.tls]
# enable = false
# # ca_file_path = "/path/to/ca.pem"
# # cert_file_path = "/path/to/client.pem"
# # key_file_path = "/path/to/client.key"
# # insecure_skip_verify = false

[plugins.guard]
enable = true
check_service_url = "http://localhost:8999/check"
timeout_ms = 30000
verbose_log = false # 是否开启 Guard 详细日志(默认 false)

[plugins.semantic_cache]
enable = false
embedding_service_url = "http://103.44.80.148:9013/v1/embeddings"
embedding_model = "bge-m3:latest"
embedding_dimensions = 1024
embedding_timeout_ms = 5000
redis = "redis://127.0.0.1:6379/0"
verbose_log = false

[plugins.prompt_compressor]
enable = false
service_url = "http://10.0.181.199:8089"
timeout_ms = 10000
verbose_log = false

root_redirect_url 只影响 gateway 监听端口上的 GET /,配置后该请求返回 302Location 为配置的绝对 URL。其它请求路径和方法仍按现有路由解析/未知路由逻辑处理;Management API 监听端口不受影响。

未提供 [rate-limit] 配置时,程序会在启动日志中打印警告:未配置 Redis,限速功能不可用

headers_mode 支持 always / on-limit / never,分别表示始终返回限速头、仅在返回 429 时返回、或完全不返回;未配置时默认 on-limit

如需在本地接收 plugins.log.destination = http 的 protojson 请求日志,可使用 ck-ingest-server ,默认监听 127.0.0.1:19091,接收路径为 /ingest/request-logs

环境变量替换

配置文件中所有字符串值都支持 bash 风格的环境变量替换:

  • $VAR${VAR} 两种语法均可
  • 支持在一个值里多次出现以及与字面字符串拼接,例如 "redis://$HOST:${PORT}/1"
  • 替换发生在解析与校验之前,因此 []string 的每个元素、shutdown_max_wait 这类会进一步转换的字符串字段也都会先做替换
  • 引用了未设置的环境变量时启动会失败,并一次性列出所有缺失的变量名,便于一次部署就把环境补齐
  • 已设置但为空的变量(export FOO=)视为合法值,展开为空字符串,不会计入缺失

举个用环境变量复用同一份 Redis 连接信息的例子(同一个实例,不同的 db):

[rate-limit]
redis = "${REDIS_URL}/1"

[plugins.guard]
enable = true
check_service_url = "http://127.0.0.1:8999"
redis = "${REDIS_URL}/2"

[plugins.semantic_cache]
enable = true
embedding_service_url = "http://127.0.0.1:9013/v1/embeddings"
embedding_model = "bge-m3:latest"
redis = "${REDIS_URL}/0"

启动前 export REDIS_URL=redis://:pwd@redis-master:6379 即可,三处引用都从同一个变量取值。

当前未实现 ${VAR:-default} 默认值语法,也没有 $$ 字面转义。如果密码本身就包含 $ 后跟字母数字的子串(例如 p@$$word),建议把整个密码或整条连接串放到环境变量里整体注入,避免被误识别为变量引用。

Log 输出格式

当前 log 插件有两类输出:

  • PostgreSQL:写入 request_logs 摘要,裁剪发生在入库阶段
  • plugins.log.destination:发送统一的完整事件流

其中:

  • destination = http 时,默认发送 logging.v1.Event 的 proto json 数组
  • destination = kafka 时,默认发送 proto json,消息类型为 logging.v1.Event
  • destination = none 时,不广播事件,只写 PostgreSQL

可通过 plugins.log.output_format 显式覆盖日志目的地输出编码:

  • output_format = "json":HTTP 发送 Event proto json 数组;Kafka 每条 message 发送一个 Event proto json 对象
  • output_format = "binary":HTTP 每次请求发送一个 Event protobuf binary;Kafka 每条 message 发送一个 Event protobuf binary

plugins.log.store_full_body_in_pg 可选控制是否把完整 RequestLog 的 protojson 额外写入 PostgreSQL request_logs.raw。默认 false

shutdown_max_wait

shutdown_max_wait 用于控制 Aidy Gateway 在收到退出信号后,最多等待多长时间让仍在处理中的 HTTP 请求完成。默认值为 1m

收到退出信号后,Aidy 会先把 /ready 切到 503,再等待 readiness_drain_delay,之后才开始执行这个 HTTP draining 等待。超过这个时间后,HTTP server 会停止继续等待并退出优雅关闭阶段。

该字段只影响 HTTP 请求 draining,不影响其他关闭动作。例如:

  • Kafka 日志 flush / destination close
  • PG 连接池、日志 destination 等后台资源的关闭

该字段支持 Go time.Duration 格式,例如:

  • 30s
  • 1m
  • 5m

也可以通过命令行参数 --shutdown-max-wait 覆盖配置文件中的值。

如果使用 systemd、Kubernetes 或其他进程管理器,请确保它们的停止超时配置能够覆盖整个退出过程,而不仅仅是 shutdown_max_wait;因为 HTTP 请求等待结束后,其他关闭动作仍可能继续执行。

readiness_drain_delay

readiness_drain_delay 用于控制收到退出信号后、开始关闭 gateway listener 前的等待时间。默认值为 10s

这个等待窗口让 Kubernetes 有时间观察到 /ready 返回 503,并从 Service endpoints 中摘除当前 Pod,减少新请求继续打到正在退出的实例。

该字段支持 Go time.Duration 格式,例如:

  • 0s
  • 5s
  • 10s

在 Kubernetes 中,terminationGracePeriodSeconds 应至少覆盖:

readiness_drain_delay + shutdown_max_wait + 额外关闭缓冲

Helm chart 默认 readinessDrainDelay=10sshutdownMaxWait=5mterminationGracePeriodSeconds=330