3-3 优化微服务代码:提炼HealthModule到共享模块
提炼动机
HealthController 和 HealthModule 在每个微服务中都需要使用,属于典型的横切关注点。将其提炼到 proto-pkg 共享模块中:
| 提炼前 | 提炼后 |
|---|---|
| 每个微服务独立实现 HealthController | proto-pkg 统一提供 |
| 代码重复 | 一次实现,处处复用 |
| 修改需要同步多个项目 | 修改一处即可 |
提炼步骤
1. 在 proto-pkg 中创建 Health 目录
proto-pkg/src/
├── index.js # 入口文件
├── utils.js # 工具函数
├── nest/
│ └── user.ts # ts-proto 生成
└── health/ # 新增
├── health.controller.ts
└── health.module.ts
text
2. 复制 HealthController 和 HealthModule
从 user 微服务中将以下文件复制到 proto-pkg/src/health/:
health.controller.ts-- 实现通用的 gRPC 健康检查响应health.module.ts-- 注册 HealthController
3. 安装依赖
proto-pkg 中需要 @nestjs/common 依赖:
cd packages/proto-pkg
pnpm add @nestjs/common
bash
4. 在入口文件中导出
在 src/index.ts 中添加 HealthModule 导出:
// src/index.ts
export { loadProto, loadSync } from './utils';
export { HealthModule } from './health/health.module';
export { promiseifySomeMethods } from './utils/grpc-utils';
typescript
5. 构建验证
pnpm build
bash
检查 dist/ 目录中是否包含 HealthModule 的输出。
在微服务中使用共享 HealthModule
替换引用
// 替换前:引用本地模块
import { HealthModule } from './health/health.module';
// 替换后:引用共享包
import { HealthModule } from '@remote/proto-pkg';
typescript
删除本地 health 目录
确认共享模块正常工作后,删除微服务中的本地 src/health/ 目录。
验证流程
- 启动微服务
- 使用 grpcurl 测试健康检查接口
- 确认正常响应
同步提炼 grpc-utils
除了 HealthModule,Gateway 中使用的 promiseifySomeMethods 等工具函数也可以提炼到 proto-pkg:
proto-pkg/src/
├── utils/
│ ├── index.ts # 统一导出
│ ├── grpc-utils.ts # gRPC 工具函数(原 promiseifySomeMethods)
│ └── proto-utils.ts # proto 相关工具(原 utils 中的 loadProto 等)
└── health/
├── health.controller.ts
└── health.module.ts
text
入口文件更新
// src/index.ts
export { loadProto, loadSync } from './utils/proto-utils';
export { HealthModule } from './health/health.module';
export { promiseifySomeMethods } from './utils/grpc-utils';
typescript
提炼后的项目引用方式
// 在微服务中
import { HealthModule, loadProto } from '@remote/proto-pkg';
// 在 Gateway 中
import { promiseifySomeMethods, loadProto } from '@remote/proto-pkg';
typescript
提炼收益
| 维度 | 收益 |
|---|---|
| 代码复用 | HealthModule 和工具函数一次实现,多处使用 |
| 维护成本 | 修改只在 proto-pkg 中进行,自动同步到所有微服务 |
| 版本一致 | 通过 workspace 依赖确保所有项目使用同一版本 |
| 开发效率 | 新增微服务时直接引用共享模块,无需重复编写 |
参考资源
- NestJS Modules - 模块系统
- pnpm Workspaces - Monorepo 管理
- tsup Build - TypeScript 打包工具
↑