跳转到主要内容

gRPC 服务

本页覆盖以下模板,并逐项对照当前运行时代码:

  • lynx-grpc/conf/example_config.yml
  • lynx-grpc/conf/example_client_config.yml
  • lynx-grpc/conf/example_complete_config.yml
  • lynx-grpc/conf/example_polaris_config.yml

Runtime 事实

能力Go module配置前缀Runtime 插件名
gRPC 服务端github.com/go-lynx/lynx-grpclynx.grpc.servicegrpc.service
gRPC 客户端github.com/go-lynx/lynx-grpclynx.grpc.clientgrpc.client

配置前先知道

  • lynx.grpc.servicelynx.grpc.client 是两套独立能力,可以只开服务端、只开客户端,或同时启用。
  • 服务端如果省略 stream / message size,不会回到 protobuf 注释里的“零值语义”,而是启动时补上更安全的运行时默认值:1000 个并发 stream、10 MiB 的收发消息上限。
  • lynx.grpc.service 还会从同一前缀读取一些仅 YAML 暴露的扩展键,例如 graceful_shutdown_timeoutrate_limitmax_inflight_unarycircuit_breaker
  • 客户端优先使用 subscribe_servicesservices 只是兼容历史配置。
  • example_client_config.yml 末尾还给出了一段顶层 subscriptions.grpc[*] 示例。真实 bootstrap 配置里,它属于 lynx.subscriptions.grpc[*],而不是 lynx.grpc.client
  • 当前客户端代码真正生效的开关里,tracing_enabled 是 live 的,但 metrics_enabledlogging_enabledhealth_check_enabledhealth_check_intervalmax_message_sizecompression_enabledcompression_type 目前还只有模板 / proto 面定义,没有对应运行时效果。
  • subscribe_services[*] 里的 tls_enabletls_auth_type 现在不会可靠继承客户端全局 TLS 默认值;你不写,就会落成 false / 0

lynx.grpc.service

字段作用何时生效默认值 / 交互关系常见误配
network选择监听传输类型。一直生效。默认 tcp选了 unix 却仍填写 TCP 地址。
addr设置监听地址。一直生效。默认 :9090只绑回环地址却期待跨主机访问。
tls_enable打开 gRPC 服务端 TLS。只有证书来源已就绪时。默认 false;通常要配合可工作的 TLS Manager证书还没准备好就先开 TLS。
tls_auth_type选择客户端证书校验策略。tls_enable: true默认 0;合法值 0..4TLS 没开,却配置了 mTLS 策略。
timeout设置 Kratos gRPC 请求超时。一直生效。默认 10s有长耗时 RPC 却没同步调大。
max_concurrent_streams限制每个连接的 HTTP/2 并发 stream 数。服务端启动时。省略或写 0 时,运行时仍会补成安全默认值 1000只看 proto 注释,以为 0 在实际运行里等于不限流。
max_recv_msg_size限制入站消息大小,单位字节。服务端启动时。省略或写 0 时,运行时补成 10 MiB仍按上游 gRPC 默认约 4 MiB 去理解。
max_send_msg_size限制出站消息大小,单位字节。服务端启动时。省略或写 0 时,运行时补成 10 MiB大响应 / 流式场景没同步调大。

额外的 lynx.grpc.service YAML 键

example_config.yml 里还有一些不在 service.proto 内,但运行时仍通过 ServerOptionslynx.grpc.service 前缀读取的键。

字段作用何时生效默认值 / 交互关系常见误配
graceful_shutdown_timeout设置服务端停机等待时间。停机阶段。默认 30s把它和请求超时混为一谈。
enable_tracing打开 gRPC tracing 拦截器。启动时。默认 true关掉它后还期待服务端继续产出 gRPC span。
enable_request_logging打开 unary / stream 请求日志。启动时。默认 true关掉它后还在找带 trace-id 的请求日志。
enable_metrics打开 unary / stream 指标拦截器。启动时。默认 true关掉后还期待服务端 gRPC 指标继续出现。
rate_limit.enabled打开进程内服务端限流器。启动时。默认 false;不显式开启就不会生效。误以为示例里有这个块就已经启用。
rate_limit.rate_per_second设置稳态 unary RPC 吞吐。rate_limit.enabled: true除零值保护外没有额外默认值。只填了速率,却没把 enabled 打开。
rate_limit.burst设置限流突发容量。rate_limit.enabled: true<= 0 时回退到 rate_per_second + 10 却误判实际 burst。
max_inflight_unary限制并发执行中的 unary RPC 数。仅值 > 0默认 0 表示不限制。以为它也能限制 streaming RPC。
circuit_breaker.enabled打开服务端熔断器。启动时。默认 false误以为和 HTTP 插件一样默认就开。
circuit_breaker.failure_threshold熔断打开前的失败次数门槛。仅熔断启用时。省略或非法时默认 5把它当成失败率而不是失败次数。
circuit_breaker.recovery_timeout熔断从 open 进入 half-open 前的等待时长。仅熔断启用时。默认 30s把它当成单次请求超时。
circuit_breaker.success_threshold熔断恢复关闭前需要的成功探测次数。仅熔断启用时。默认 3设太高导致 half-open 持续过久。
circuit_breaker.timeout熔断保护请求时使用的超时。仅熔断启用时。默认 10s误以为它会替代 lynx.grpc.service.timeout
circuit_breaker.max_concurrent_requests熔断参与时允许的并发请求数。仅熔断启用时。默认 10配得低于常规流量,制造出额外节流。

lynx.grpc.client

字段作用何时生效默认值 / 交互关系常见误配
default_timeout出站 RPC 的默认超时。服务项没覆写 timeout 时。默认 10s忘了它也影响 required: true 服务的启动探活等待。
default_keep_alive客户端连接 keepalive 周期。建连时。默认 30s设太小导致重连抖动频繁。
max_retries可重试 unary RPC 的默认重试次数。重试拦截器中。默认 3;服务项里 0 或更小会回退到这个全局值。配得很高,却忘了重试会放大时延。
retry_backoff重试退避基础间隔。重试拦截器中。默认 1s配得太大,让短暂故障看起来像卡死。
max_connections每个服务在连接池里的最大连接数。开启连接池或创建池化连接时。默认 10把它理解成“最多跟踪多少个服务”。
tls_enable全局兜底客户端连接是否启用 TLS。createConnection() 和历史路径里。默认 false全局打开后,以为 subscribe_services[*] 会自动继承。
tls_auth_type全局兜底客户端 TLS 认证模式。全局 TLS 路径中。默认 0TLS 没开还期待它起作用。
connection_pooling是否启用多连接池。客户端初始化时。默认 false打开后却把 pool_sizemax_connections 按错误维度去调。
pool_size连接池最多跟踪多少个服务项。connection_pooling: true<= 0 时回退到 10把它当成“每个服务保留多少连接”。
idle_timeout池化连接空闲淘汰时间。connection_pooling: true缺失或 <= 0 时回退到 5m配到一分钟以下导致频繁重连。
health_check_enabled预期中的客户端健康检查开关。启动时会解析。目前模板 / proto 有,代码未使用。以为打开后就会自动做 gRPC health probe。
health_check_interval预期中的客户端健康检查频率。启动时会解析。当前未使用。调了它却看不到任何运行时变化。
metrics_enabled预期中的客户端指标开关。启动时会解析。当前客户端无论此值如何都会挂指标拦截器。设成 false 后还惊讶指标没停。
tracing_enabled是否向出站 metadata 注入 trace 上下文。构建客户端拦截器时。默认 false启用了 lynx-tracer 却忘了这里,结果链路不串。
logging_enabled预期中的客户端日志开关。启动时会解析。当前客户端无论此值如何都会挂日志拦截器。设成 false 后还期待客户端静默。
max_message_size预期中的客户端消息大小覆盖。启动时会解析。当前 dial 选项未使用。把它当成真实生效的保护上限。
compression_enabled预期中的压缩开关。启动时会解析。当前未接线。以为打开后链路会自动启用 gzip。
compression_type预期中的压缩算法。启动时会解析。当前未接线。配成 gzip 后发现线上仍是明文未压缩流量。
subscribe_services推荐使用的按服务配置 / 发现配置列表。GetConnection(serviceName) 优先走这里。默认空。新服务仍只写进已废弃的 services
services已废弃的旧静态服务列表。只有 subscribe_services 没命中时才兜底。仍兼容,但启动会告警。把 discovery-first 的新服务继续写在这里。

lynx.grpc.client.subscribe_services[*]

字段作用何时生效默认值 / 交互关系常见误配
name作为 discovery 服务名和 GetConnection(name) 的查找键。一直生效。必填。同一个服务名写了两次,校验会直接拒绝。
endpoint静态地址覆盖。仅没有 discovery 实例时。一旦 discovery 存在,当前代码会忽略它,不会做“在线 fallback”。以为 Polaris 在场时它还能兜底。
timeout单服务超时覆盖。该服务被选中时。回退到 default_timeout慢上游没调大,且 required: true 导致启动失败。
tls_enable单服务 TLS 开关。该订阅项被选中时。当前不会继承全局值;不写就等于 false全局开了 TLS,却忘了在每个服务项上重复声明。
tls_auth_type单服务 TLS 认证模式。仅该服务项 tls_enable: true当前不会可靠继承全局值;不写就等于 0误以为全局 mTLS 策略会自动下沉。
max_retries单服务重试次数覆盖。重试拦截器中。0 会回退到全局重试次数。0 误解成“完全不重试”。
required启动时上游不可达就直接失败。仅启动探活阶段。默认 false把可选依赖标成必需,拖死整个服务启动。
metadata负载均衡筛选和路由提示的附加元数据。仅所选负载均衡器会用到时。可选 map。把它当成每次 RPC 自动发送的请求 metadata。
load_balancer选择服务选址策略。仅 discovery 可用时。当前校验器接受 round_robinrandomweighted_round_robin静态 endpoint 场景下配置它,却期待真的生效。
circuit_breaker_enabled是否打开该上游的客户端熔断。仅此服务。默认 false以为客户端有一个全局共享熔断器。
circuit_breaker_threshold单服务熔断失败次数门槛。circuit_breaker_enabled: true过高会触发校验告警。配得过高,导致熔断几乎永远不触发。

已废弃的 lynx.grpc.client.services[*]

字段作用何时生效默认值 / 交互关系常见误配
name历史服务键。一直生效。必填。继续复用现代 discovery 服务名,却没迁移到 subscribe_services
endpoint静态上游地址。一直生效。历史列表里必填。留空后还期待 discovery 自动补齐。
timeout历史单服务超时。历史项被选中时。省略时回退到全局客户端超时。以为它能影响 subscribe_services
tls_enable历史单服务 TLS 开关。历史项被选中时。默认 false应用里没有证书提供者却打开了 TLS。
tls_auth_type历史单服务 TLS 模式。仅历史 TLS 打开时。默认 0TLS 关闭状态下还期待它改变行为。
max_retries历史单服务重试次数。历史项被选中时。0 时回退到全局配置。把它当成现代 discovery 服务的覆盖项。

example_client_config.yml 里的顶层 lynx.subscriptions.grpc[*]

example_client_config.yml 结尾还有第二段示例块:subscriptions.grpc[*]。这组键不属于 lynx.grpc.client,而是属于 Lynx bootstrap 订阅配置;真实运行时路径应写成 lynx.subscriptions.grpc[*]

这组键由 lynx/subscribe 里的 core subscription loader 消费,适合描述“启动阶段要建立并复用的 gRPC 订阅连接”。它和 lynx.grpc.client.subscribe_services[*] 是两套不同的配置面,不应混写成同一语义。

字段作用何时生效默认值 / 交互关系常见误配
service指定 discovery 中的上游服务名,同时也作为订阅连接的 key。一直生效。必填;开启 TLS 时,它还会被用作证书校验里的 ServerName把这里写成 host:port,而不是服务发现注册名。
tls为该订阅连接打开 TLS。lynx.subscriptions.grpc[*] 订阅路径。默认 false;为 true 时,core loader 会先开 TLS,再按 ca_name / ca_group 取 CA,或回退到应用默认 Root CA provider。开了 TLS,却没有任何 CA 来源或默认 Root CA。
required把该订阅标记为启动期硬依赖。启动建连阶段。默认 false;失败时不再只是告警跳过,而是直接返回错误。把可选上游标成必需,导致服务起不来。
ca_name指定该订阅 TLS 路径使用的根 CA 配置名 / 载荷名。tls: true 且需要从配置 / 控制面拉取 CA 时。留空表示改用应用默认 Root CA provider。tls 没开就填它,或应用路径里没有 config provider 却硬填。
ca_group指定该 CA 配置所在的分组。tls: trueca_name 已设置。在 core loader 里,留空会回退到 ca_name分组填错,结果拉到了错误的 CA。

example_polaris_config.yml:服务发现前提

example_polaris_config.yml 里的 lynx.polaris 配置不属于 lynx-grpc 本身,而是 Polaris 控制面插件的配置。但它依然会改变 gRPC 客户端行为,因为 discovery 一旦可用,grpc.client 的选址逻辑就会切换。

字段对 gRPC 使用者的作用默认值 / 交互关系常见误配
lynx.polaris.namespace选择客户端实际去解析的服务发现命名空间。省略时 Polaris 默认 default命名空间写错,最后误判成 gRPC discovery 失效。
lynx.polaris.server_addresses指向一个或多个 Polaris 服务发现端点。远程发现实践里基本必填。服务网络里根本连不到 Polaris。
lynx.polaris.enable_retry打开 Polaris 侧重试。有助于发现端短暂故障恢复。关掉 gRPC 重试后,忘了 Polaris 还有自己的重试语义。
lynx.polaris.max_retry_times限制 Polaris 重试次数。Polaris 自身会校验范围。设太大,让发现失败耗时过长。
lynx.polaris.retry_intervalPolaris 重试间隔。max_retry_times 配合使用。间隔配太大,让服务发现看上去像“卡住”。
lynx.polaris.health_check_interval控制 Polaris 侧健康检查 / 刷新频率。会影响发现状态变化被感知的速度。误以为它能替代客户端自己的每次 RPC 健康检查。

完整 YAML 示例

lynx:
polaris:
namespace: "default" # example_polaris_config.yml 里的服务发现命名空间
server_addresses:
- "127.0.0.1:8091" # 一个或多个 Polaris 服务端地址
enable_retry: true # Polaris 侧重试开关
max_retry_times: 3 # Polaris 重试次数上限
retry_interval: "2s" # Polaris 重试间隔
health_check_interval: "5s" # Polaris 刷新 / 健康检查频率

grpc:
service:
network: "tcp" # 监听传输类型;默认 tcp
addr: ":9090" # 服务端监听地址;默认 :9090
tls_enable: false # 只有 lynx.tls 已加载证书后才应打开
tls_auth_type: 0 # 0..4;仅 tls_enable=true 时有意义
timeout: "10s" # 请求超时
max_concurrent_streams: 1000 # 省略或 0 时会落到安全默认值
max_recv_msg_size: 10485760 # 10 MiB 入站消息上限
max_send_msg_size: 10485760 # 10 MiB 出站消息上限
graceful_shutdown_timeout: "30s" # 仅 YAML 暴露的服务端选项;默认 30s
enable_tracing: true # 服务端 tracing 拦截器开关
enable_request_logging: true # 服务端请求日志拦截器开关
enable_metrics: true # 服务端指标拦截器开关
rate_limit:
enabled: false # 进程内 unary 限流器
rate_per_second: 100 # 稳态 unary 吞吐
burst: 200 # 突发容量;<=0 会回退到 rate_per_second+1
max_inflight_unary: 0 # 0 表示不限制并发 unary RPC
circuit_breaker:
enabled: false # 服务端熔断开关
failure_threshold: 5 # 失败次数门槛
recovery_timeout: "30s" # open 到 half-open 的等待时长
success_threshold: 3 # 关闭熔断前需要的成功探测次数
timeout: "10s" # 熔断保护请求时的超时
max_concurrent_requests: 10 # 熔断参与时的并发请求上限

client:
default_timeout: "10s" # 全局兜底 RPC 超时
default_keep_alive: "30s" # 连接 keepalive 周期
max_retries: 3 # 默认 unary 重试次数
retry_backoff: "1s" # 重试退避基础间隔
max_connections: 10 # 连接池模式下每个服务的最大连接数
tls_enable: false # 全局兜底 TLS 开关;subscribe_services 不会可靠继承它
tls_auth_type: 0 # 全局兜底 TLS 认证模式
connection_pooling: true # 启用多连接池
pool_size: 10 # 连接池最多跟踪多少个服务
idle_timeout: "60s" # 池化连接空闲淘汰时间
health_check_enabled: true # 模板字段;当前客户端代码不会消费
health_check_interval: "30s" # 模板字段;当前客户端代码不会消费
metrics_enabled: true # 模板字段;当前客户端代码不会消费
tracing_enabled: true # live 的出站 trace 上下文注入开关
logging_enabled: true # 模板字段;当前客户端代码不会消费
max_message_size: 4194304 # 模板字段;当前客户端代码不会消费
compression_enabled: false # 模板字段;当前客户端代码不会消费
compression_type: "gzip" # 模板字段;当前客户端代码不会消费
subscribe_services:
- name: "user-service" # GetConnection("user-service") 的查找键
endpoint: "127.0.0.1:9091" # discovery 不可用时的静态兜底地址
timeout: "5s" # 单服务超时覆盖
tls_enable: true # 单服务 TLS 开关
tls_auth_type: 2 # 单服务 TLS 认证模式
max_retries: 5 # 单服务重试次数覆盖
required: true # 依赖不可用时直接让启动失败
metadata:
version: "v1.0" # 可选负载均衡 / 路由元数据
region: "us-west" # 额外路由提示
load_balancer: "round_robin" # 仅 discovery 场景生效的选址策略
circuit_breaker_enabled: true # 单服务客户端熔断
circuit_breaker_threshold: 5 # 单服务熔断失败次数门槛
services:
- name: "legacy-service" # 已废弃的静态服务列表
endpoint: "legacy.internal:9094" # legacy 模式必填的静态地址
timeout: "10s" # 单服务超时覆盖
tls_enable: false # legacy 单服务 TLS 开关
tls_auth_type: 0 # legacy 单服务 TLS 认证模式
max_retries: 3 # legacy 单服务重试次数覆盖

subscriptions:
grpc:
- service: "user-service" # bootstrap 订阅连接使用的服务名
tls: false # 是否为这条 bootstrap 订阅连接打开 TLS
required: true # 建连失败时是否直接让启动失败
ca_name: "" # tls=true 时可选的 CA 配置名
ca_group: "" # 可选 CA 分组;留空回退到 ca_name

最小可用 YAML 示例

服务端和客户端本来就是两套独立能力,所以最小可复制配置可以只启服务端,也可以只给客户端一个直接上游。下面这个例子把两者都保留了,但不依赖 Polaris:

lynx:
grpc:
service:
addr: ":9090" # 足够启动 gRPC 服务端;network 默认 tcp
client:
subscribe_services:
- name: "user-service" # GetConnection("user-service") 的连接键
endpoint: "127.0.0.1:9091" # 没有 discovery 插件时可直接连这个上游

只有在你需要“启动期共享订阅连接”时,才再补 subscriptions.grpc[*]

实用规则

  • 服务端 TLS 和客户端 TLS 要分开配,它们不会自动联动。
  • 现在如果某个上游需要 TLS,请在 subscribe_services[*] 里把相关 TLS 字段重复写清楚。
  • required: true 只留给那些“启动没它就没法继续”的硬依赖。
  • metrics_enabledlogging_enabledhealth_check_*max_message_sizecompression_* 目前更应该视为前瞻模板字段,而不是已经生效的客户端开关。