8.6 KiB
8.6 KiB
Architecture Overview / 架构总览
中文
系统边界
accounts.svc.plus 是一个以 Gin 为 HTTP 入口的 Go 单体服务。它同时承担四类职责:
- 账号与认证:注册、登录、会话、MFA、OAuth、密码重置。
- 账号控制面:管理员权限矩阵、用户管理、Sandbox 假扮、黑名单。
- Agent / Xray 控制:向 agent 提供客户端列表、接收 agent 心跳、按数据库状态生成 Xray 配置。
- 使用量与计费读面:账户流量桶、账本、配额、策略、节点健康和调度决策读取。
主启动链路
cmd/accountsvc/main.go 的 server 路径可以概括为:
- 读取配置并选择运行模式:
server、agent、server-agent。 - 初始化主 store 与管理面 GORM DB,后者负责
admin_settings、homepage video、sandbox binding、tenant / XWorkmate 相关模型。 - 应用 RBAC schema,并确保 root / review / sandbox 用户以及相关体验性账户状态满足当前契约。
- 根据 SMTP 配置决定是否启用真实邮件发送;未配置或是示例域名时自动退回“禁用邮件验证”。
- 在
auth.enable为真时构造auth.TokenService,否则系统仍以 session token 主路径工作。 - 构造
agentserver.Registry,将静态 credential、持久化 agent 状态、sandbox binding 预加载到内存读面。 - 在
xray.sync.enabled为真时启动xrayconfig.PeriodicSyncer,以数据库为源周期性重建 Xray 配置并执行 validate / restart 命令。 - 构造
api.Option列表,把 store、mailer、token service、Stripe、Vault、OAuth provider、metrics provider、agent registry、GORM DB 注入api.RegisterRoutes。 - 启动 Gin HTTP 服务,对外提供
/healthz、/api/auth/*、/api/internal/*、/api/admin/*、/api/agent-server/v1/*与/api/account/*。
运行时主数据流
1. 账号登录与会话
POST /api/auth/login读取store.Store中的用户和密码哈希。- 成功后由
handler.createSession在 session store 中落 token,再由sanitizeUser组装用户返回体。 - 若用户启用 MFA,则先返回 challenge,再由
POST /api/auth/mfa/verify完成会话签发。
2. 配置化管理面
internal/service/admin_settings.go使用 GORM 读写model.AdminSetting。- API 层通过
requireAdminPermission+service.GetAdminSettings/SaveAdminSettings组合出“会话鉴权 + 权限矩阵”的控制面能力。 internal/service/homepage_video_settings.go复用同一套 GORM DB,负责首页视频默认项和域名覆盖项。
3. Xray 配置生成
- Controller 模式下,
internal/xrayconfig.GormClientSource从数据库读取用户并转换为xrayconfig.Client。 xrayconfig.Generator把Definition模板渲染成 JSON,再替换inbounds[0].settings.clients。xrayconfig.PeriodicSyncer周期性执行Generate,可选执行 validate / restart 命令。- Agent 模式下,
internal/agentmode.Client通过/api/agent-server/v1/users获取客户端列表,复用同一套PeriodicSyncer本地生成配置并上报/status。
4. 使用量与计费读取
internal/store.Store暴露分钟桶、账本、配额、账单 profile、策略快照、节点健康、调度决策等读取方法。api/accounting.go将这些事实表组合为/api/account/*与/api/admin/traffic/*读接口。- 这些接口的 source of truth 是 PostgreSQL 事实表,不依赖 Prometheus 聚合。
后台循环与状态持有者
agentserver.Registry在内存中持有 credential digest、agent 身份、最新状态快照和 sandbox agent 集。handler在 API 层持有 session、MFA challenge、邮箱验证码、密码重置 token、OAuth exchange code 等进程内状态。PeriodicSyncer和agentmode.runStatusReporter是主要后台循环;前者负责配置文件收敛,后者负责 agent 健康上报。
当前明确边界
- Session、MFA challenge、邮箱验证码、OAuth exchange code 都是进程内状态,不是横向可共享存储。
- JWT token service 是可选增强,不是当前主控制面的唯一鉴权来源;大部分业务仍围绕 session token 设计。
- GORM 只承载管理面模型,不替代主业务 store。
/api/agent/nodes是 legacy alias,规范路径是/api/agent-server/v1/nodes。
English
System Scope
accounts.svc.plus is a Gin-based Go monolith. It owns four main responsibility areas:
- Identity and authentication: registration, login, sessions, MFA, OAuth, password reset.
- Account control plane: admin permission matrix, user operations, sandbox assume flows, blacklist management.
- Agent / Xray control: serving client lists to agents, receiving agent heartbeats, generating Xray configs from database state.
- Usage and billing read models: traffic buckets, ledger entries, quota state, policy snapshots, node health, and scheduler decisions.
Main Startup Chain
The server path in cmd/accountsvc/main.go is:
- Load config and choose runtime mode:
server,agent, orserver-agent. - Initialize the primary store plus a GORM-backed admin DB used for admin settings, homepage video, sandbox binding, and tenant / XWorkmate models.
- Apply RBAC schema and normalize root / review / sandbox accounts so runtime invariants are satisfied.
- Build the mailer if SMTP is configured; otherwise email verification is disabled automatically.
- Build
auth.TokenServiceonly whenauth.enableis true; the service still keeps session-token flows as the primary path. - Build
agentserver.Registry, hydrate it from configured credentials and persisted agent rows, and preload sandbox bindings. - Start
xrayconfig.PeriodicSyncerwhenxray.sync.enabledis true so Xray configs are regenerated from database state and optionally validated / restarted. - Build the
api.Optionlist and inject store, mailer, token service, Stripe, Vault, OAuth providers, metrics provider, agent registry, and GORM DB intoapi.RegisterRoutes. - Start Gin and expose
/healthz,/api/auth/*,/api/internal/*,/api/admin/*,/api/agent-server/v1/*, and/api/account/*.
Primary Runtime Flows
1. Identity and Session Flow
POST /api/auth/loginreads users and password hashes fromstore.Store.- On success,
handler.createSessionwrites a session token andsanitizeUsershapes the user payload. - If MFA is enabled, login first returns a challenge and
POST /api/auth/mfa/verifycompletes session issuance.
2. Configurable Admin Surface
internal/service/admin_settings.goreads and writesmodel.AdminSettingthrough GORM.- The API layer combines
requireAdminPermissionwithservice.GetAdminSettings/SaveAdminSettingsto enforce session-based access plus permission-matrix rules. internal/service/homepage_video_settings.gouses the same GORM DB for default and per-domain homepage video entries.
3. Xray Config Generation
- In controller mode,
internal/xrayconfig.GormClientSourceloads users from the database and converts them intoxrayconfig.Clientrecords. xrayconfig.Generatorrenders aDefinitiontemplate into JSON and replacesinbounds[0].settings.clients.xrayconfig.PeriodicSyncerrepeatedly callsGenerateand may run validate / restart commands.- In agent mode,
internal/agentmode.Clientfetches/api/agent-server/v1/users, feeds the samePeriodicSyncer, and reports/status.
4. Usage and Billing Reads
internal/store.Storeexposes traffic buckets, ledger, quota, billing profile, policy snapshot, node health, and scheduler decision reads.api/accounting.gocomposes those facts into/api/account/*and/api/admin/traffic/*responses.- The source of truth for those reads is PostgreSQL-backed fact tables, not Prometheus.
Background Loops and State Owners
agentserver.Registryowns credential digests, agent identities, latest status snapshots, and sandbox-agent flags in memory.- API
handlerowns process-local session, MFA challenge, email verification, password reset, and OAuth exchange state. PeriodicSyncerandagentmode.runStatusReporterare the main background loops for config convergence and agent health reporting.
Current Hard Boundaries
- Sessions, MFA challenges, email verification state, and OAuth exchange codes are process-local, not horizontally shared.
- JWT is optional and not the sole authentication source for the current control plane; most business flows are still session-centric.
- GORM is used for admin-side models only and does not replace the primary business store abstraction.
/api/agent/nodesis a legacy alias;/api/agent-server/v1/nodesis the canonical route family.