1. 项目概述
这个基于Node.js和Express框架的文学交流平台,是我去年为一个读书会开发的核心项目。它解决了传统文学社群常见的几个痛点:作品展示形式单一、互动方式有限、用户粘性不足。平台上线后三个月内,注册用户突破5000人,日均活跃度保持在35%以上,成为当地最活跃的线上文学社区。
2. 技术架构设计
2.1 核心框架选型
选择Express作为基础框架主要基于三个考量:
- 中间件机制完美适配文学平台的多层次业务逻辑
- 路由系统天然支持RESTful API设计
- 丰富的插件生态可以快速实现文件上传、表单验证等文学社区必备功能
javascript复制// 典型中间件配置示例
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/uploads', express.static('public/uploads'));
2.2 数据库设计
采用MongoDB + Mongoose的方案,文档型数据库特别适合文学作品这种半结构化数据。核心集合包括:
| 集合名称 | 主要字段 | 索引设计 |
|---|---|---|
| users | username, email, bio | 唯一索引(email) |
| works | title, content, author, tags | 复合索引(author + createdAt) |
| comments | content, workId, userId | 工作ID哈希索引 |
3. 核心功能实现
3.1 作品发布模块
实现带Markdown支持的富文本编辑器是关键难点。最终方案采用:
- 前端:Toast UI Editor
- 后端:marked库转换Markdown
- 存储:原始Markdown和渲染后的HTML双存储
javascript复制// Markdown处理中间件
const parseMarkdown = (req, res, next) => {
if(req.body.content) {
req.body.htmlContent = marked(req.body.content);
}
next();
}
3.2 互动交流系统
设计了三级评论体系:
- 主评论:直接针对作品
- 子评论:回复主评论
- 私密评论:仅作者可见
使用聚合管道实现高效查询:
javascript复制Comment.aggregate([
{ $match: { workId: workId } },
{ $graphLookup: { ... } } // 构建评论树
])
4. 性能优化实践
4.1 缓存策略
采用Redis实现三层缓存:
- 作品详情:TTL 15分钟
- 热门列表:LFU算法维护
- 用户会话:JWT+Redis双校验
4.2 文件存储优化
文学平台面临大量文本和封面图片存储:
- 小文件(<10MB):直接MongoDB GridFS
- 大文件:阿里云OSS分片上传
- 图片:Sharp库自动生成三种尺寸缩略图
5. 安全防护方案
5.1 内容安全
实现了一套完整的审核流程:
- 前端:关键词过滤(2000+敏感词库)
- 后端:阿里云内容安全API二次校验
- 人工:举报机制+定时巡检
5.2 接口防护
关键防护措施:
- 速率限制:express-rate-limit
- CSRF防护:csurf中间件
- SQL注入:mongoose内置防护
- XSS:DOMPurify清洗
6. 部署与监控
6.1 容器化部署
采用Docker Compose编排:
yaml复制services:
app:
image: node:16
command: npm start
ports:
- "3000:3000"
redis:
image: redis:6
mongo:
image: mongo:5
6.2 监控体系
搭建的监控指标包括:
- 业务指标:日活、作品发布量
- 性能指标:API响应时间、DB查询耗时
- 系统指标:CPU/内存使用率
使用Prometheus+Grafana实现可视化监控。
7. 踩坑实录
7.1 文件上传内存泄漏
最初使用multer内存存储导致服务崩溃。解决方案:
- 改用磁盘存储
- 实现文件流式处理
- 添加文件大小限制中间件
7.2 评论通知风暴
当热门作品有新评论时,最初设计会立即推送所有关注者,导致系统过载。优化方案:
- 合并通知(15分钟窗口期)
- 重要度分级(作者回复优先)
- 离线计算+批量发送
这个项目让我深刻体会到,文学类平台的技术挑战不仅在于基础功能实现,更在于如何处理高并发的内容交互和保持社区氛围。后续我们计划引入AI辅助的内容推荐算法,但这需要谨慎平衡推荐效率和社区调性。