8.6 KiB
目标后台持续连接
所有目标协议支持(2026-09-23)
原因:原设置只允许四种单节点数据库预认证会话或 SSH/K8s 出口隧道,其余已支持的目标协议不能开启后台检查。
结果与范围:全部现有目标协议均可配置 connectionOptions.persistent。单节点 MySQL、MongoDB、PostgreSQL、Redis 仍使用独占交接的预认证备用会话;SSH/K8s 出口仍保持共享隧道。无共享隧道且不能安全交接会话的 SQL Server、RabbitMQ、HTTP(S)、SSH/SFTP、TCP 与数据库集群使用 probe 模式:网关运行期间每 15 秒以目标协议的现有连接测试独立探测,完成后关闭临时连接;不复用业务会话、不保持这些协议的长连接,也不计入复用次数。对不能安全保持会话的协议,保活含义仅为持续探测,不保证客户端免建连。SSH/K8s 出口保持原有隧道模式,集群不缓存可变节点的会话。
兼容性与迁移:管理界面新建目标时,全部现有目标协议默认写入 persistent: true;已有目标继续使用已保存值,缺少字段或显式为 false 的旧配置不会自动开启,无数据迁移。探测额外产生周期性连接和认证请求,明确的认证、权限或身份拒绝继续暂停重试,避免锁号。连接测试本身仍使用临时资源;后台探测不影响客户端原有路由或事务。模型与网关包测试、全部 16 个前端领域测试文件、前端类型检查及串行 go vet -p=1 ./... 通过;其中 6 项持续连接组件测试和 8 项连接草稿测试逐一检查全部 11 种类型的模式及默认值,并验证旧目标不继承新建默认值。完整 Go 测试仍有 6 项 Windows 文件权限/SQLite 快照环境失败,Vite 构建受 esbuild spawn EPERM 限制;Playwright 成功发现测试但未运行浏览器。网关测试使用 fixture,不代表真实目标的在线验证。
行为与用途(2026-09-22)
目标编辑器的“高级”页提供“后台持续连接”开关,对应 connectionOptions.persistent。全部 11 种目标类型的新建草稿默认 true;编辑已有目标时严格使用后端保存值,旧配置缺少字段时仍显示关闭。保存和测试共用的目标 payload 保留此布尔值。
- 单节点 MySQL、MongoDB、PostgreSQL、Redis 支持预认证备用池,按网关绑定及账号权限范围隔离。仅交接尚未服务客户端的连接;客户端用过的会话不回收,避免事务、游标和订阅状态串用。
- 任意协议使用 SSH 或 K8s 出口时可保持持续隧道,但仍遵守原有协议及固定资源规则:K8s 固定资源仍要求单节点,不因 persistent 放宽集群校验。SSH 集群只保持隧道,不建立预认证备用池。其他协议的直连或 SOCKS5 方式仅周期性探测,不保持或复用业务连接。
- 不支持时禁用尚未开启的开关并解释原因。切换协议或出口后已有
true不会被悄悄清除;保存校验报错,允许用户显式关闭。 - 仅在引用目标的网关运行期间预建、心跳和重连;网关停止释放后台资源。备用连接及 SSH 隧道每 15 秒心跳,K8s 沿用 SPDY 5 秒心跳,网络或未知失败后 1–30 秒指数退避。
- 明确认证、权限或身份拒绝时进入
rejected并暂停后台重试,避免重复密码登录锁号。检查凭据、权限或主机指纹,修正目标配置并保存后,运行网关按新配置重建后台资源。拒绝分类由后端安全类型化证据提供,前端不解析错误字符串,不将未知错误推断为密码错误。 - K8s 可在隧道上为多个客户端建立独立流,无需维护 Pod IP;断线后重新按资源解析 Pod。
- 运行中保存目标或网关配置后,新连接和后台预热使用新快照;已有客户端连接及已租用隧道继续使用原快照直至结束,旧配置不再补充新的后台资源。
状态展示与安全边界
网关运行面板展示 runtime.persistentTargets,只读取:
{targetId, accountId, mode, state, ready, leases, reconnects}。
mode 为 session(预认证备用池)、tunnel(持续隧道)或 probe(后台探测)。state 闭集为 connecting、ready、retrying、rejected、expired、stopped,未知值统一显示“未知状态”,不回显原值。rejected 显示“已拒绝,暂停重试”及固定恢复提示,不显示原始拒绝原因。ready 独立表示当前可用性。
leases 显示为“累计成功复用次数”,指备用会话独占交接或隧道新流,不是当前连接数;reconnects 为重连次数。界面不读取或展示原始错误、密码或其他未约定字段。
持续连接标签、模式说明和默认行为说明使用项目现有中文、英文、日文字典。后端生命周期由后端实现提供;组件测试不证明真实目标、认证、心跳或隧道连接成功。
使用方法
- 新建目标时「目标服务 → 配置目标 → 高级」中的「后台持续连接」默认开启,可按需关闭后保存;编辑旧目标时沿用已保存状态。引用网关正在运行时无需先停止。
- 启动网关。即使没有客户端接入,也会开始预建后台资源;没有运行网关的目标不会主动连接。
- 在网关列表展开该行,查看「目标后台持续连接」的状态、复用和重连计数。首次建立或心跳检查期间可能短暂显示不可用;前台连接仍按原配置建立,不降级直连。
- 明确认证/权限/身份拒绝会暂停后台重试;核对并保存目标配置后按新快照重试。不能通过开启持续连接绕过 SSH 指纹校验。
实现与生命周期边界
internal/gateway/persistent.go管理每个运行网关的后台任务、独占会话交接和隧道引用计数。每个绑定/权限范围最多保留一个空闲预认证会话,借出后补充;实际客户端连接仍受网关原有数量与来源限制,后台备用连接额外占用上游资源。SessionPreparer仅由四个单节点数据库 Handler 实现。心跳时会话先从可借位置取走,交接前再做一次有界 Ping。失败则关闭后新建,不重放业务查询。MySQL/PG 的不同初始数据库不借默认库备用连接;MongoDB 预认证 hello 不借用已认证连接,认证及心跳遵循目标 authSource,空值才默认 admin。internal/outbound/persistent.go与kubernetes.go提供独立流的共享隧道。每个 SSH 流有独立超时及半关闭;单个流结束不关闭底层共享连接。运行中配置更新停止旧池预热并按新快照建立资源,已有隧道租赁继续;停止网关才强制关闭全部隧道资源。- 共享 Dial 遵守
connectTimeoutSeconds和调用方更短的期限,期限不成为已建立会话的总时限。退役与尚未取得引用的 Dial 竞争时,只对明确尚未开始通道建立的退役拒绝按旧配置独立拨号;其他错误不自动重试应用数据。 - 明确连接测试使用新的临时连接,不触发后台预热,诊断阶段仍反映本次真实建连。runtime 提供的函数引用不持久化、不进入配置响应。
ConfigurableTable保留 expand 结构列,避免列设置过滤掉运行详情入口;普通数据列的显隐、顺序和宽度规则不变。
验证
- Go 1.25.0 全量测试与 vet 通过。四协议 fixture 覆盖无客户端预认证、借前 Ping、身份/数据库隔离、取消、超时、自定义 Mongo authSource 和安全拒绝分类。
- 网关集成测试使用 loopback RESP fixture:启动后无客户端已有认证连接,第一个客户端复用它,后台补充后第二个客户端获得不同的新备用会话,停服释放全部连接。纯控制器测试覆盖独占、过期、不跨配置借用、断线重连、暂停拒绝、切换保留租赁和取消建连。
- SSH/K8s fixture 验证多流复用同一次握手/upgrade、deadline 隔离、半关闭、EOF、幂等清理和重新解析 Pod。相关生命周期用例重复 20 次通过。
node --test web/tests/persistent-target.test.mjs6/6 通过。Vite/类型构建通过;新程序的persistent-target.spec.ts与列设置等工作区用例合计 6/6 通过。真实 API 保存/回读与界面重开已验证;状态渲染使用模拟 runtime,不代表真实远端状态验收。- Linux/amd64、Darwin/amd64 的 gateway/outbound 测试程序交叉编译通过,未在相应系统运行。当前环境 CGO 禁用,不能运行 race detector,不宣称 race 检查通过。
完整浏览器回归及日志见 testing.md。所有连接验证为本地 fixture,不涉及真实目标数据;未部署或提交。