4 vCPU · 7.6 GiB · 单根卷
ARCHITECTURE / 01
全局架构总图
把逻辑边界、生产部署、身份、资源、数据、实时服务、日志、发布和恢复放在同一个架构入口。目标态与运行真值并列展示,避免把规划误认为上线能力。
ARCHITECTURE DOSSIERS
八份可执行的专项架构档案
总图负责全局方向;专项档案负责真正开发。每份都下钻到组件 owner、运行状态、关键时序、接口 guard、数据恢复、故障收敛与 QA 发布门禁。
AUTH身份与访问控制
OTP、JWT、应用会话、设备身份与权限边界
MEDIA资源、包与媒体交付
上传隔离、校验、晋级、下载票据与端侧验证
CONTENT可信内容与公共知识
来源注册、采集、证据、社区共审与公共发布
REALTIME实时通信与端侧状态
HTTP 会话、WebSocket、消息持久化、Push 与媒体发送
ORDER预约与本地服务交易
发现、发布店铺、容量、预约状态与商家运营
QUANT行情、策略与量化研究
版本化行情、冻结策略、确定性运行、信号与端上展示
OPS日志、可观测与恢复
Nginx、systemd、Docker、Loki、Grafana、备份与故障演练
DELIVERY多团队交付与 QA 架构
任务包、契约、UI CI、发布证据、灰度与回滚
DEPLOYED REALITY
生产请求实际经过四层运行栈
所有公共域名、业务服务、数据库、日志和仓库目前汇聚到同一台 EC2。下面是 SSH、Nginx、systemd、Docker 与健康接口共同核实出的部署路径。
5 个宿主机业务服务,共用一台 EC2
数据库、Gitea、日志、备份与采集数据同盘
Auth 有生产风险;资源控制面尚未部署
EDGE
DNS · TLS · Nginx
9 个公共域名汇聚到同一公网 IP,由 Nginx 按 host/path 分流。reits / wwwbbsapiauthorderopenapiworkergitealogHOST SERVICES
systemd 业务服务
Go/Node 服务直接运行在宿主机;内部端口由 Nginx 反向代理。reits-auth :8095developer-api :8090miniapp-gateway :8081order :3210data-sources :8080CONTAINERS
Docker 产品与平台
IM、官网、BBS、Gitea 和日志栈共用一个 Docker daemon 与根卷。im-core :18080portal :3003NodeBB :4567Gitea :3002Grafana :3300Loki :3100AlloySTATE
本机数据库与数据卷
业务状态、仓库、日志和采集文件仍以本机 EBS/Docker volumes 为主。MariaDBPostgreSQLRedisMongoDBIM Postgres/Redis/NATS/MinIOLocal packagesXFS / Docker volumesCONTROL PLANES
六个产品与平台控制面
每个框都同时给出稳定责任链和当前生产真值。状态不是宣传口径,而是代码与运行环境对照后的结论。
身份与授权
reits-auth :8095 已运行;生产预览旁路开启,版本落后主干。
资源与包交付
代码契约存在;生产仍是 OpenAPI local storage,无 service / bucket / CDN。
可信内容
采集数据、内容快照和 BBS/官网链路已运行,但控制面与公共面边界偏重。
实时通信
IM Core 容器运行;共享单 EC2,媒体控制面未统一。
预约与开放能力
预约与网关已生产运行;order auth 仍非强制、billing 为 mock。
行情与量化
行情、回测和端上模拟已有代码;quant-platform 仍是规划仓。
TRUST BOUNDARIES
六个信任区,不把公网、应用和状态画成同一层
每次跨区都必须回答:谁认证、什么 scope、哪份数据、怎样审计、失败后如何收敛。下方同时给出现行控制和缺口。
Public Internet
Web / iOS / Miniapp clientsSearch & crawlerThird-party source sitesCONTROLTLS、公开限流、无隐式信任
GAP公开 API 的一致限流证据仍不足
AUTH + CONTRACT + TELEMETRY ↓Edge
Nginx :443Host + path routingSecurity groupCONTROL单一入口、端口过滤、基础 header
GAPNginx 与单 EC2 同一故障域
AUTH + CONTRACT + TELEMETRY ↓Application
systemd web servicesDocker business servicesNodeBB / Gateway / AuthCONTROL应用会话、scope、服务健康
GAPAuth 预览旁路与 order 弱认证属于 P0
AUTH + CONTRACT + TELEMETRY ↓Stateful Services
PostgreSQLMongoDB / Redis / NATSLocal package & content filesCONTROL服务内网、业务 owner、备份 timer
GAP状态、日志与备份共用单根卷
AUTH + CONTRACT + TELEMETRY ↓Secrets & Recovery
Environment secretsGitea backupDB dump / package backupCONTROL宿主机权限、备份清单
GAP没有统一 KMS、异地副本与恢复演练证据
AUTH + CONTRACT + TELEMETRY ↓Operations
SSH operatorsGitea deploy hooksGrafana / CI evidenceCONTROL人工权限、审计页面、发布记录
GAP发布主体、审批和回滚证据尚未统一
reits.techsystemd / Next.jspublic + operations gatecontent snapshotsBBS · data-sources · MCPbbs.reits.techDocker / NodeBBNodeBB sessionMongoDB + Redisdata-sources · portal bridgeauth route :8095systemd / GoOTP → JWT subject/scopesauth PostgreSQLim-core verification · consumersapi.reits.techDocker / Godevice + token + MFAPostgreSQL + Redis + NATSpush · media adapter · mobile clientsorder.reits.techsystemd / web + APIconsumer token / merchant sessionbooking PostgreSQLAuth · notifications · OpenSDKopenapi.reits.techDocker / gateway + portalreits-auth app sessionPostgreSQL + local packageshost clients · package storagetarget onlyNOT DEPLOYEDsigned upload/download tickettarget S3 quarantineOpen Platform · iOSinternal GrafanaDocker / Alloy + Loki + Grafanaoperatorlocal Loki chunksNginx · Docker · systemd journalsCRITICAL SEQUENCES
六条关键时序把 UI、服务、状态和门禁串起来
架构图只画组件还不够;真正容易出错的是跨边界的步骤、事务点和降级路径。
邮箱 OTP 登录
- 1
Client 请求验证码
- 2
reits-auth 发起 OTP
- 3
im-core verification 校验
- 4
签发 subject + scopes
- 5
业务服务建立 app session
可信内容发布
- 1
Source registry 授权
- 2
Fetch / Parse / Store
- 3
文档与素材固化
- 4
BBS 候选人工/策略门
- 5
Portal snapshot + citation
资源包发布
- 1
Portal 选择 ZIP
- 2
上传 quarantine
- 3
checksum + scan
- 4
版本签名/promote
- 5
Gateway ticket → Host 校验
预约提交
- 1
打开 publish hash
- 2
选择服务与可用时段
- 3
提交客户信息
- 4
容量冲突事务校验
- 5
状态 token / 商家队列 / 通知
实时消息
- 1
HTTP 建立会话
- 2
WebSocket 订阅
- 3
本地 optimistic message
- 4
服务端持久化 + event
- 5
receipt / push / durable replay
确定性回测
- 1
选择冻结策略版本
- 2
绑定 data_asof 行情
- 3
提交参数与 seed
- 4
backtest 生成不可变 run
- 5
iOS 展示指标/信号/风险
EDGE + STATE
域名路由和状态存储必须成对看
路由说明请求落到哪里;状态表说明失败后真正要恢复什么。reits-media 以缺失态呈现,不再用 S3/CDN 目标图掩盖现状。
/ · /snapshots · /api/operationsreits-info-portal:3003Dockerhealthy/NodeBB:4567Dockerhealthy/healthz · /readyz · /websock · defaultim-core:18080Dockerhealthy/api/*public-booking-platform:3210systemdhealthy/openapi/*miniapp-gateway:8081systemdhealthy/v1/* · /api/*reits-auth:8095systemdrisk/public-booking-platform:3210systemdhealthy/api/* · /openapi/* · /packages/*developer-api · gateway · local disk:8090 / 8081systemdrisk/data-sources:8080systemdhealthy/Gitea:3002Dockerhealthy/Grafana:3300Dockerprotected/v1/*reits-media:—not deployedmissingHost MariaDB
Auth / OpenAPIjx_reits_auth · jx_im_developer · jx_im_openapi · wukong
Backup · daily dump → local + S3Host PostgreSQL
GiteaGitea metadata
Backup · missing from current backup scriptHost Redis
Auth / OpenAPIsession/challenge support
Backup · not declareddata-sources data
Content Datacrawler state, files and local data
Backup · local backup directoryGitea Docker volume
Developer Platformrepositories, LFS and Gitea /data
Backup · daily tar → local + S3BBS volumes
Communitytopics/users/uploads + Redis
Backup · not proven in EC2 backup flowIM volumes
RealtimeIM state, Redis, NATS, object data
Backup · not proven in EC2 backup flowOpenAPI local packages
Developer Platformpackage files under /opt/miniapp-open-platform/storage
Backup · local-only runtime modeDATA OWNERSHIP
每类状态只有一个真值 owner,并绑定恢复目标
RPO/RTO 标注为目标,不冒充已实现 SLA;Evidence 栏说明目前能拿出的恢复证据。
reits-authPostgreSQL≤24h target≤4h target备份覆盖需独立验证
im-corePostgreSQL + Redis/NATS≤15m target≤2h targetdurable replay 有代码;跨机恢复未演练
public-bookingPostgreSQL≤1h target≤2h target本机备份;恢复包未统一
data-sourcesPostgreSQL + local files≤24h target≤8h target后台有备份恢复面;需自动演练
reits-bbsMongoDB + Redis≤24h target≤4h targetNodeBB 状态与自定义审计需成组恢复
miniapp-open-platformPostgreSQL + local files≤1h target≤4h targetreits-media 未部署,checksum 不是异地备份
GiteaPostgreSQL + repositoriestimer snapshotmanual有本机备份;缺离机恢复验证
Platform OpsLoki + journalsbest effortN/A4 天本机链路;缺异地保留与统一告警
FAILURE DOMAINS
从单点故障看爆炸半径、检测和收敛
当前生产最需要解决的不是再画更多理想服务,而是把单 EC2、单卷、Auth 和本地包存储的爆炸半径降下来。
EC2 instance
- IMPACT
- 全部公共域名与内部服务同时不可用
- DETECTION
- external health + SSH
- CONTAINMENT
- 无跨机隔离
- NEXT CONTROL
- 拆 Edge/State,建立替换实例与恢复 runbook
Root EBS volume
- IMPACT
- 数据库、Gitea、包、日志和备份同损
- DETECTION
- disk / fs / backup checks
- CONTAINMENT
- 同盘备份不能覆盖卷故障
- NEXT CONTROL
- 独立数据卷 + 异地对象存储 + restore drill
Nginx / certificate
- IMPACT
- 所有公共 host 入口中断
- DETECTION
- TLS / route smoke
- CONTAINMENT
- 应用可能健康但不可达
- NEXT CONTROL
- 配置测试、证书预警、可回滚 edge bundle
Auth / session
- IMPACT
- Open Platform、Booking 与部分客户端无法安全登录
- DETECTION
- OTP + scope synthetic
- CONTAINMENT
- 公共只读面应继续可用
- NEXT CONTROL
- 关闭旁路、强制 audience/scope、建立降级矩阵
Mongo / Redis / NATS
- IMPACT
- 社区或 IM 的实时/缓存/队列能力降级
- DETECTION
- dependency health + replay lag
- CONTAINMENT
- 按领域分级降级
- NEXT CONTROL
- 为无缓存、无队列、重连分别定义 SLO
Local package storage
- IMPACT
- 新包发布与客户端包下载受阻
- DETECTION
- checksum / ticket smoke
- CONTAINMENT
- 已缓存包可继续运行
- NEXT CONTROL
- 部署 reits-media,隔离 quarantine 与 immutable assets
OBSERVABILITY + RECOVERY
从日志进入发布证据和恢复能力
可观测不是 Grafana 一个框;恢复也不是备份定时器一个框。这里把采集、存储、查看、部署证据和备份范围放进同一条责任链。
BBS / Data / Portal
~1 minute- SourceGitea main
- Executorsystemd timers
- TargetDocker / systemd
- Evidencecurrent-sha files
Order
~5 minutes- SourceGitea main
- Executorreits-order-auto-deploy
- Targetsystemd :3210
- Evidencerelease SHA + health
OpenAPI
~1 hour- SourceGitea main
- Executorreits-openapi-autodeploy
- Targettwo systemd services
- Evidencebuild SHA + health
Auth
manual- SourceGitea main
- Executormanual deploy
- Targetsystemd :8095
- Evidenceproduction is behind current main
EC2 backup
daily 03:00 UTC- SourceMariaDB + Gitea /data
- Executorec2-backup.timer
- Targetlocal + S3
- Evidencegzip integrity only
生产 Auth 仍启用预览旁路
AUTH_EXPOSE_DEV_CODE、AUTH_ALLOW_PREVIEW、AUTH_PREVIEW_OVERRIDE 在 auth.reits.tech 生产进程中均为开启状态;必须先建立零停机回退方案,再关闭并验证所有客户端。
资源服务器只存在于代码,不存在于生产
没有 reits-media service、Nginx vhost、REITs S3 bucket 或 assets.reits.tech DNS;OpenAPI health 明确报告 storageBackend=local。
当前备份无法完整恢复 Gitea
备份包含 MariaDB 和 Gitea /data tar,但 Gitea 实际使用的宿主机 PostgreSQL 约 3.9 GiB 未被 dump;BBS 与 IM 数据卷也未进入这条备份链,脚本还包含应迁移到受管密钥存储的硬编码凭据。
单 EC2 是全生态共同故障域
Edge、Auth、IM、官网、BBS、Order、OpenAPI、数据库、日志和 Gitea 共用一个实例、一块根卷与一个 Docker daemon。
日志可查询,但没有异地副本
Alloy → Loki → Grafana 链路健康且 Grafana 有访问保护;日志仅存本机,CloudWatch log group 为 0,实例或根卷故障会同时丢失服务和诊断证据。
生产版本真值不统一
多数服务有 SHA 证据,但 Auth 仍运行 d95cab5,落后于当前 main;Order/OpenAPI 的 build SHA 来自健康接口,部署状态文件格式不一致。
磁盘与备份增长需要预算
根卷使用 54%;Docker 50 GiB、本地备份 26 GiB、采集数据 19 GiB。当前尚未形成统一容量阈值、保留策略和告警。
DEPENDENCY CONTRACTS
项目依赖不是一根线,而是一份契约
依赖表只表达稳定输入输出;部署拓扑和实现细节由各仓维护。每份契约还要进入 QA 追踪链。
END-TO-END
端到端链路
每条链路都从可审计输入开始,以明确用户价值和发布证据结束。
可信内容主链
- 官方披露/API
- data-sources 采集与合规
- BBS 机器人动态与共审
- 官网编辑/质量门禁
- 全球/国家/资产聚合
即时通讯主链
- Matrix X / Quant iOS
- im-core HTTP/WS
- PostgreSQL/Redis
- Push/Realtime replay
- 设备端状态收敛
预约交易主链
- 发现/店铺
- 预约与自助管理
- 商户审核/排班
- 订单/支付/通知
- 归因与发布证据
小程序发布主链
- 开发者应用
- reits-media 直传
- ZIP 完整性验证
- 版本发布/Gateway
- iOS 验 hash 后运行
端上模拟主链
- trading-data-source
- 冻结策略
- deterministic backtest
- quant-platform 目标服务
- Quant iOS / miniapp
协作治理主链
- 知识库决策
- 机器清单
- 任务包/Owner
- 代码与契约
- CI 证据
- 门户自动更新
ARCHITECTURE RULES
六条不可绕过的架构规则
边界
项目通过版本化契约协作,不跨仓引用业务源码。
真值
运行状态归业务数据库;架构状态归 machine manifest;决策归 ADR。
安全
认证、发布、上传、支付和人工写入门默认 fail-closed。
数据
所有公开内容保留来源、时间、授权/合规状态和不可变 hash。
发布
公共体验、内部运营和后台任务使用独立 owner 与爆炸半径。
演进
先保持外部契约,再拆巨型文件与内部领域边界。