其他
用 Express.js 构建可扩展微服务时的中间件、路由…
在 Node.js/Express.js 中构建生产级微服务时,提供中间件、路由、错误处理、可扩展性与部署架构的完整做法。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 52/100 ×0.15
适用场景
用 Express.js 构建可扩展微服通用
解决思路
- 按顺序定义中间件:中间件按定义顺序执行,用 app.use() 注册全局中间件,用 next() 传递控制权。
- 在请求对象上共享数据:在中间件中给 req 挂载字段(如 req.user、req.requestTime),后续路由直接读取。
- 编写错误处理中间件:使用 4 个参数 (err, req, res, next),定义在所有其他中间件之后;同步错误自动捕获,异步错误必须调用 next(err)。
- 将错误处理拆分为 errorConverter 与 errorHandler:前者把非 ApiError 统一转换为 ApiError,后者根据环境返回状态码、消息与堆栈。
- 用 catchAsync 包装异步路由处理器:Promise.resolve(fn(req,res,next)).catch(next),避免每个控制器写 try/catch。
- 为特定路由挂载中间件:app.get('/protected', requestLogger, handler),或对一组路由使用 app.use('/api/admin/', cors(adminCorsOptions))。
- 实现 JWT 认证中间件:从 Authorization 头取 Bearer token,jwt.verify 校验后把用户挂到 req.user,失败返回 401/403。
- 实现基于角色的授权中间件:authorize(...roles) 返回中间件,检查 req.user.role 是否在允许列表内。
- 实现请求校验中间件:用 express-validator 的 body/param/query 定义规则,validate(validations) 工厂统一执行并返回 400 与错误详情。
- 实现限流中间件:用 express-rate-limit,内存版用于单实例,RedisStore 版用于分布式;对登录等敏感路由单独设置更小 max。
- 实现日志中间件:用 winston 创建结构化 logger,morgan 输出 HTTP 日志并写入 logger;自定义中间件在 res.on('finish') 中记录方法、路径、状态码、耗时、IP、UA。
- 配置 CORS 中间件:用 cors(corsOptions) 设置 origin 白名单、credentials、methods、allowedHeaders、exposedHeaders、maxAge。
- 配置安全中间件:helmet 设置安全头,mongoSanitize 防 NoSQL 注入,xss-clean 防 XSS,hpp 防参数污染,helmet.contentSecurityPolicy 设置 CSP。
- 用 Router 模块化路由:express.Router() 定义路由与路由级中间件,module.exports 后在 app.js 中 app.use('/api/users', usersRouter) 挂载。
- 使用路由参数与参数中间件::userId 命名参数,app.param('userId', ...) 预取资源并挂到 req,支持多个回调数组。
- 处理查询参数:从 req.query 解构 role、active、page、limit、sort,构造查询对象并做分页 skip/limit。
- 实现 API 版本化:为 v1/v2 分别创建 Router 并挂载到 /api/v1、/api/v2,或按 api-version 请求头分发。
- 按控制器/服务/路由分层组织代码:controllers 处理请求响应,services 封装业务逻辑,routes 只做路由映射。
- 实现水平扩展:用 cluster 模块按 CPU 核数 fork worker,master 监听 exit 事件自动重启。
- 用 Nginx 做负载均衡:upstream 配置 least_conn 与多个后端,proxy_pass 并设置 X-Real-IP、X-Forwarded-For 等头。
- 实现缓存中间件:用 Redis 缓存 GET 响应,重写 res.json 写入缓存,提供 invalidateCache(pattern) 在写操作后失效缓存。
- 配置数据库连接池:MongoDB 用 poolSize,PostgreSQL 用 pg.Pool 的 max、idleTimeoutMillis、connectionTimeoutMillis。
- 启用响应压缩:app.use(compression()),可自定义 filter、level、threshold。
- 对大响应做节流:用 stream-throttle 的 Throttle 限制速率后 pipe 到 res。
- 用 Docker 多阶段构建:builder 阶段 npm ci --only=production,生产镜像用 node:18-alpine,创建非 root 用户,设置 HEALTHCHECK。
- 用 docker-compose 编排:定义 api、redis、mongo、nginx 服务,设置 replicas、资源限制、depends_on、restart、volumes。
- 用 PM2 管理进程:ecosystem.config.js 中 instances:'max'、exec_mode:'cluster'、max_memory_restart、日志文件与环境变量。
- 实现健康检查端点:/health 检查 uptime、数据库 ping、Redis ping,失败返回 503;另设 /ready 与 /live。
- 实现优雅关闭:监听 SIGTERM/SIGINT,server.close 后依次关闭数据库与 Redis 连接,超时 10 秒强制退出。
- 接入 Prometheus 监控:prom-client 注册默认指标与自定义 Histogram/Counter,中间件在 res.on('finish') 记录,暴露 /metrics。
- 接入分布式追踪:用 OpenTelemetry 注册 HttpInstrumentation 与 ExpressInstrumentation,自定义中间件创建 span 并设置 http 属性。
- 用 Joi 校验环境变量:定义 schema 校验 NODE_ENV、PORT、MONGODB_URI、REDIS_HOST、JWT_SECRET 等,失败时抛错。
- 用 ApiError 类统一错误:包含 statusCode、isOperational、stack,生产环境非操作性错误返回 500 与通用消息。
- 编写集成测试:用 supertest 对 app 发请求,beforeEach 清理数据,断言状态码与响应体,覆盖创建、校验失败、404 等场景。
- 做性能优化:只 select 需要的字段、用 lean() 返回普通对象、实现分页、为常用查询建索引、用 keep-alive 的 http.Agent。
- 落实安全实践:输入校验与转义、登录限流、参数化查询、CSRF 保护、httpOnly+secure+sameSite 的 Cookie、bcrypt 哈希密码。
- 用 API Gateway 模式:用 http-proxy-middleware 把 /api/users、/api/products、/api/orders 代理到对应服务,网关层统一认证与限流。
适用边界 · 注意事项
- 不使用 Node.js/Express.js 技术栈的项目
- 不需要微服务架构、单体应用已足够的小型项目
- 无法引入 Redis、Docker、Nginx 等基础设施的受限环境