
zlooks.cn 架构:以 Hile 为核心的可发现微服务与插件化 Web 平台
基于当前代码,梳理 zlooks.cn 的 Hile 微服务、Gateway、RSC/MCP 插件、领域服务、数据存储与事件架构。
文章说明
本文基于 zlooks.cn 当前代码与包级架构约束整理,重点说明系统如何组织服务、请求、页面、管理能力和持久化状态。
一、整体定位:一个可组合的平台,而不是单体博客
zlooks.cn 当前是一个由 pnpm workspaces、Lerna、Nx、TypeScript 和 Hile 共同构成的 monorepo。代码按能力拆分为多个可独立构建、安装和运行的包,例如 Gateway、Blog、User、Password Auth、Images、Events、Global Config、Sitemap 和 Videos。
这种拆分并不是简单的目录分组。每个 *-server 都是一个内部 Hile Micro 服务,拥有自己的生命周期、领域模型、持久化边界和服务契约;*-shared、*-schema 和 contract 包则保存稳定的身份、DTO、Schema 与 typed client。系统通过 Registry 进行服务发现,通过统一的 Gateway 对外提供 Web、RSC、静态资源和 MCP 能力。
因此,zlooks.cn 的核心架构可以概括为:
浏览器 / MCP 客户端
│
▼
唯一公网 Gateway
┌───────┼────────┐
▼ ▼ ▼
RSC Host Browser MCP Gateway
API │
│ ▼
└─── Hile Registry ───┐
│
┌──────────────┬─────────┼──────────────┐
▼ ▼ ▼ ▼
Blog Service User Service Event Service Images...
│ │ │ │
└──────── PostgreSQL / Redis / 文件存储 ┘
二、唯一公网入口:Gateway 只负责接入与投影
@zlooks.cn/gateway-server 是系统唯一对外监听的服务。其他服务不创建独立的公网 HTTP、Next.js、RSC、MCP 或管理接口,而是通过内部 Hile Micro 网络提供能力。
Gateway 的职责主要有四类:
- 公共 Web Host:承载首页、Next.js 文档协议、RSC Flight、静态资源和 Server Functions。
- 通用 RSC Host:通过
/:pluginId/*path将动态发现的 RSC 插件投影到同一个公网 Origin。 - 通用 Browser API Controller:通过
/-/{namespace}/{...paths}将浏览器请求转发到服务自己声明的 HTTP-over-Micro 消息。 - 统一 MCP Gateway:发现内部 MCP Provider,并在同一个公网监听器上提供官方 MCP HTTP 传输。
Gateway 不知道 Blog、User 或 Images 的业务路由清单,也不通过硬编码的插件 ID、服务地址或能力别名来工作。它只理解通用的发现协议、传输边界、认证、限流、取消传播和生命周期。
这使得新增业务能力时,通常只需新增一个遵循约定的内部服务并发布 Registry announcement,而无需修改 Gateway 的业务分支。
三、Hile Micro:Model、Micro、Web/MCP 的三层边界
项目最重要的代码约束之一,是保持如下依赖方向:
Model → Micro Message → Web Controller / MCP Tool / RSC
1. Model:表达业务行为
Model 使用 @hile/model 定义一个结构化的领域命令、查询、策略或状态转换。例如 Blog 的发布文章、审核评论、读取公开文章,User 的创建会话、更新资料,Images 的上传与删除,都应该由领域 Model 表达。
Model 不应该知道 HTTP method、URL、Cookie、MCP 对象、状态码或传输帧。这样同一个业务行为可以被 Web、MCP、RSC 或其他服务复用。
2. Micro Message:稳定的应用用例边界
Hile Micro Message 负责验证稳定 DTO,加载一个或多个 Model,并完成跨 Model 的用例编排。简单行为可以调用一个 Model;涉及用户身份、公开投影或跨领域调用的行为,则由 Message 负责组合。
Micro 是服务对内提供能力的正式边界。其他服务、Browser API 适配器和 MCP Provider 都通过 typed Micro client 调用,而不是直接读取对方的 Store、Runtime 或 Model。
3. Web/MCP:协议适配器
Browser Controller、HTTP-over-Micro Message、MCP Tool 和 Resource 都是协议适配层。它们负责解析协议输入、传递 Context 和 cancellation、投影响应及映射错误,但不应重新实现业务规则。
这套边界让同一个 Blog 发布流程可以被管理端 MCP 使用,也可以被其他内部服务调用,同时避免出现一套 MCP 逻辑、一套 HTTP 逻辑和一套内部逻辑互相漂移。
四、RSC 插件:页面能力通过 Registry 动态组合
zlooks.cn 没有把所有页面都写进 Gateway 的 Next.js 路由。Gateway 只保留首页和一个通用的动态路由:
/:pluginId/*path
User 服务发布 user.account RSC 插件,Blog Theme 服务发布 blog 插件,其他能力也可以按相同机制独立部署。每个插件携带自己的不可变构建产物、路由和组件,由 Hile RSC discovery 发现后交给 Gateway Host 渲染。
插件边界带来几个重要效果:
- User 的
/account、/login、/register不需要 Gateway 添加专用页面。 - Blog 的主题可以独立构建和切换,不需要把主题代码编译进 Gateway。
- 滚动发布时,Gateway 通过
{ pluginId, buildId }精确选择活动构建,避免新旧产物混用。 - 插件拥有自己的 Client Boundary 和 UI Provider;跨 RSC 构建边界不能假设 React Context 自动共享。
- 公共 Shell、站点身份和当前用户投影由 Gateway 生成受限上下文,Opaque session 则通过独立参数传递,不能进入 Flight 输出或客户端状态。
当前部署采用可信内部网络的 trusted-internal 发现模式。内部服务间不依赖额外的发布者密钥,但公网 MCP 仍由 Gateway 的 Bearer Token、Origin 和 Scope 策略保护。
五、Browser API:通用转发,业务路由归属服务
浏览器交互请求使用统一的 Gateway Controller 前缀:
/-/{namespace}/{...paths}
Gateway 只负责把 namespace 和剩余路径转交给 Hile Micro 服务。服务必须显式定义 defineHttpOverMicroMessage(),才能成为浏览器 API;普通 Micro 操作不会自动暴露到公网。
Blog 例如拥有分类、标签、文章、评论、搜索和点赞等 HTTP-over-Micro 消息,但这些路径和状态语义仍归 Blog 所有。User 则拥有认证、账户和会话操作。Gateway 不解析业务字段,也不维护 Browser Provider 目录。
浏览器 JSON API 统一使用:
{ "code": 0, "data": {} }
或:
{ "code": 1001, "error": "面向用户的有限错误信息" }
Cookie 由 Gateway 统一写入并施加 HttpOnly、Secure、SameSite 等安全属性;业务服务只返回声明式的 cookie effect。认证凭据通过有界的 Hile Context 传播,不能混入业务 DTO,也不能把完整 Context 写入日志。
六、业务服务:按领域拥有数据和规则
Blog Service
Blog 服务拥有分类、文章、页面、标签、评论、友情链接和点赞等领域数据。TypeORM/PostgreSQL 是持久化真源,Redis 只承担视图去重、主题选择和发现协调等辅助职责。
Blog 的管理能力全部通过 MCP Provider 暴露。单记录读取使用 MCP Resource,写入使用 Tool,多步骤的发布、评论审核和主题切换则使用 Prompt 提供可发现的工作流模板。Prompt 本身不执行写入,真正的校验和状态变更仍由 Tool 与 Micro 边界负责。
文章发布前会执行确定性的 Markdown 审查,例如标题层级、内容限制和分类标签问题。阻断项会停止发布,警告项不会阻止保存。Blog 主题不是 Blog Gateway 页面,而是通过独立的 RSC Theme 服务发现和激活。
User 与 Password Auth
User 服务是用户、身份、会话和认证扩展的控制面。密码登录只是一个可独立部署的认证扩展,User 通过可信的扩展发现目录调用它,而不是把密码协议写死在用户服务中。
用户数据和会话持久化在 PostgreSQL,短期认证事务、限流和幂等重放使用 Redis。数据库只保存会话 Token 的 SHA-256 摘要;浏览器拿到的真正 Token 只通过内部调用返回,再由 Gateway 写入 HttpOnly Cookie。
User 同时发布 user.account RSC 插件,负责账户、登录和注册页面。Gateway 不拥有这些页面的专用路由。
Images 与 Videos
Images 服务负责图片元数据、原图文件、安全读取和 MCP 管理能力。PostgreSQL 保存元数据,原图存放在机器本地的受控目录,Gateway 只通过通用 public-asset 协议转发公开读取。
Videos 是独立的上传、配对、认证、播放和 RSC 插件服务。它说明平台不仅支持博客内容,也可以承载拥有独立存储、浏览器交互和插件页面的业务能力。
Global Config 与 Sitemap
Global Config 使用 PostgreSQL 保存版本化站点资料,通过 expectedRevision 实现乐观并发控制,再把验证后的只读快照发布到 Registry。Gateway 订阅站点展示和站点 Profile 快照,避免在每个请求中 RPC 查询配置。
Sitemap 服务聚合各领域 Provider 的站点地图数据。Gateway 只读取聚合结果并提供 /sitemap.xml,不会在请求路径上重新发现和调用所有业务服务。
七、事件中心:把领域提交与异步投递分开
Blog、User、Images 等服务在自己的数据库事务中构造确定性的领域事件,并在事务提交后通过 @zlooks.cn/event-client 发布。它们不各自创建 Outbox、Inbox、重试调度器或 Redis Stream。
event-server 是全平台唯一的事件中心,负责:
- 持久化事件信封;
- 保存订阅关系和投递记录;
- 为消费者租约和续租;
- ACK、失败重试和 dead-letter;
- 支持多副本消费者和延迟创建订阅后的有限历史回填。
事件投递是 at-least-once,而不是 exactly-once。事件 ID 是幂等键,消费者必须按事件 ID 设计可重复执行的副作用。领域数据库提交与事件中心接收是两个提交边界,因此对于业务关键流程,还需要依靠确定性事件 ID、重试或对账处理 crash gap。
八、配置、存储与生命周期
运行时配置通过 Hile Registry 订阅。除最小的 Micro 启动边界外,业务代码不直接读取 process.env。PostgreSQL 和 Redis 作为顶层 Registry topic,由各服务组合自己的领域配置。
每个服务通常都有一个最小 .boot.ts 作为启动组合根,其余逻辑位于可复用的 .service.ts、Model、Message 和 Store 中。启动顺序一般是:
- 解析 Registry 地址并启动内部 Micro Application;
- 订阅并校验服务配置;
- 初始化 PostgreSQL、Redis 或文件存储;
- 加载 Micro contract 和业务消息;
- 启动 RSC、MCP、Sitemap 或 public-asset 等发现发布;
- Gateway 在依赖的运行时就绪后启动唯一公网 Host。
关闭时反向释放:先停止公网 Host,等待请求和流结束,再关闭 RSC/MCP 发现、订阅、数据库和 Micro listener。服务的正确性不能依赖进程本地 Map 或单实例粘性路由。
九、这套架构的主要收益与代价
收益
- 扩展不依赖 Gateway 改码:新服务通过 Registry 发布即可接入通用 Host、MCP 和 Browser API 边界。
- 业务规则可复用:Model 和 Micro 是 Web、MCP、RSC、服务间调用共享的正式入口。
- 部署边界清晰:每个领域拥有自己的数据、事件和生命周期。
- 滚动升级更安全:RSC 通过不可变 buildId,配置通过 revision,事件通过 eventId,分别处理版本和幂等问题。
- 管理自动化友好:MCP Provider、Resource 和 Prompt 让管理操作既可发现,又保留人工确认边界。
代价
- 运行组件较多:Registry、Gateway、多个 Micro、PostgreSQL、Redis 和可选服务共同构成部署单元。
- 调试需要跨边界追踪:一个页面请求可能经过 Gateway、RSC Host、User/Blog Micro 和数据库。
- 契约维护成本高:shared/schema/contract 必须保持单一真源,不能在适配层重复定义。
- 分布式一致性更复杂:服务提交和事件发布不是一个事务,消费者必须面对重复、延迟、重排和 dead-letter。
结语
zlooks.cn 的架构重点不是“把博客拆成很多服务”,而是建立一套可发现、可组合、可替换的服务平台:Gateway 统一公网边界,Hile Micro 统一应用调用,RSC 统一页面插件,MCP 统一管理能力,Registry 统一发现,PostgreSQL/Redis 分别承担持久化与协调,Event Server 统一处理异步投递。
在这套设计下,博客只是当前最完整的领域实现。用户认证、主题、图片、视频、站点配置和搜索引擎提交都可以遵循同一套边界独立演进,同时仍然共享统一的 Web、RSC、MCP 和生命周期基础设施。

参与讨论
评论