本文将介绍如何基于 NestJS 框架,搭建一个模块清晰、职责分明的数据分析平台。整体架构拆分为四大模块:
- 数据库封装模块(
database):封装 ClickHouse、Kafka、RabbitMQ 等中间件连接 - API 服务模块(
api):提供数据查询与分析任务提交接口 - 定时任务模块(
scheduler):定期触发聚合分析任务 - 消费者模块(
consume):处理 Kafka/RabbitMQ 异步数据写入
模块设计详解
1. API 模块
负责对外提供 HTTP 接口,核心功能包括:
- 接收用户数据上报请求
- 提交异步分析任务
- 查询分析结果与任务状态
此模块通常作为网关服务部署,暴露统一接口入口。
2. Database 模块
封装所有数据库/中间件相关连接,统一提供如下服务:
- ClickHouse:高性能列式数据库,用于分析型数据写入与查询
- Kafka:高吞吐消息队列,用于异步任务投递
- RabbitMQ:轻量级消息队列,用于短流程异步任务
- MongoDB:用于存储配置或原始数据
DatabaseModule 设置为全局模块,便于跨模块复用连接池、日志与重试策略。
3. Scheduler 模块
用于执行定时任务,例如:
- 每小时聚合用户活跃度
- 每天清理过期数据、生成快照等任务
基于 @nestjs/schedule 模块实现,结合分布式锁避免多实例冲突。
4. Consumer 模块
后台服务,负责消费 Kafka 或 RabbitMQ 的消息,执行相应操作:
- Kafka 中的数据上报消息解析后写入 ClickHouse
- RabbitMQ 中的任务消息解析后执行计算逻辑
消费者通常为长驻进程,支持水平扩展。
服务配置与运行方式
模块独立入口设计
为保证服务解耦,每个模块配置独立启动入口:
- API 服务:
src/main.ts - 定时任务:
src/main.scheduler.ts - 消费者服务:
src/main.consumer.ts
package.json 配置示例
// package.json
{
"scripts": {
"build": "nest build",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "cross-env NODE_ENV=production node dist/src/main",
"start:scheduler:dev": "nest start --entryFile main.scheduler --watch",
"start:scheduler:prod": "cross-env NODE_ENV=production node dist/src/main.scheduler",
"start:consumer:dev": "nest start --entryFile main.consumer --watch",
"start:consumer:prod": "cross-env NODE_ENV=production node dist/src/main.consumer",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
}
}
启动服务示例
# 启动 API 服务
pnpm start:dev
# 启动定时任务服务
pnpm start:scheduler:dev
# 启动消费者服务
pnpm start:consumer:dev
实践建议
- 定时任务模块和消费者模块 不暴露 HTTP 接口,应部署为常驻进程服务
- 使用 Redis 分布式锁 控制定时任务单点执行,避免并发冲突
- API 和消费者模块可无状态部署,实现 水平扩展
总结
通过模块化架构 + NestJS 框架,我们可以快速构建一个高性能、易维护、可扩展的数据分析平台。结合 Kafka、ClickHouse、RabbitMQ 等组件,实现了数据的高效写入、定时分析、实时处理。