NodeJS全栈开发面试题讲解——P10微服务架构(Node.js + 多服务协作)
✅ 10.1 单体架构和微服务的主要区别是什么?
维度 | 单体架构 | 微服务架构 |
---|---|---|
模块组织 | 所有功能打包在一个代码仓库中 | 拆分为多个独立服务 |
部署方式 | 部署一次包含全部逻辑 | 各服务独立部署、独立扩缩容 |
开发协作 | 多人协作易冲突 | 团队按服务划分,职责清晰 |
可维护性 | 功能多时变得复杂,修改风险大 | 单个服务小巧,便于维护和迭代 |
技术选型 | 通常限制于单一技术栈 | 各服务可用不同技术栈(polyglot) |
缺点 | 不易扩展、部署慢、耦合严重 | 运维复杂、服务治理成本高 |
✅ 10.2 微服务之间如何通信?同步与异步方式分别是什么?
🔹 同步通信(常用):
-
HTTP / REST API(最常见)
-
gRPC(高性能、结构化)
🔹 异步通信:
-
消息队列:如 RabbitMQ、Kafka、Redis Pub/Sub
-
事件驱动架构(EDA):服务发布事件,其他服务监听处理
✅ 选择建议:
-
实时请求场景 → 同步(如:下单、查询用户)
-
解耦+高并发处理 → 异步(如:发短信、订单通知、日志写入)
✅ 10.3 如何做服务注册与发现?你用过哪些方案?
在大型微服务系统中,服务数量多、地址动态变化,需注册中心协调。
✅ 常见方案:
工具 | 说明 |
---|---|
Consul | HashiCorp 出品,支持健康检查 |
Eureka | Netflix 出品,SpringCloud 默认使用 |
etcd / Zookeeper | CAP 选 P,K8s 内部注册服务 |
Nacos | 阿里开源,适配 SpringCloud |
🛠 使用方式:
-
服务启动时向注册中心注册(服务名 + IP + 端口)
-
消费者根据服务名获取地址列表,实现负载均衡调用
✅ 10.4 如何处理分布式事务问题?常见解决方案有哪些?
在多个微服务协同处理一个业务请求时,数据一致性成为挑战。
✅ 解决方案:
名称 | 描述 | 代表库/框架 |
---|---|---|
2PC | 两阶段提交(强一致) | XA、Atomikos |
TCC | Try-Confirm-Cancel,需实现三个接口 | Seata TCC 模式 |
SAGA | 长事务拆分为本地事务 + 补偿机制(最终一致) | Seata Saga、自实现 |
事务消息 | 操作数据库 + 发送消息(半消息 +确认) | RocketMQ 事务消息 |
🚨 Node.js 中可用策略:
-
事务消息 + 重试机制
-
自定义 SAGA 模式(数据库操作 + 补偿接口)
-
使用可靠消息服务(如 RabbitMQ + 补偿处理)
✅ 10.5 如何实现服务间的认证授权?使用了 JWT、API Key 还是其他方案?
✅ 主要方案:
方式 | 描述 | 使用场景 |
---|---|---|
JWT | 携带用户身份和权限信息,可被多个服务校验 | 用户登录态在多个服务间透传 |
API Key | 为每个服务/第三方分配独立访问凭证 | 内部服务调用、开放平台 API |
OAuth2 | 适用于用户授权第三方系统访问 | 开放授权(微信/Google 登录) |
mTLS | 双向证书验证,确保服务身份 | 高安全场景,如银行、支付系统 |
多数微服务系统使用 JWT + 内部签名校验,搭配 API 网关统一验证
✅ 10.6 你怎么处理服务之间的依赖关系?如何避免耦合?
✅ 降低耦合的策略:
-
使用接口约定(API schema):如 OpenAPI / Swagger
-
服务编排层(如 BFF)负责协调多个服务调用
-
通过事件驱动解耦:一个服务完成后发布事件,其他服务订阅处理
-
定义领域边界(DDD):每个服务聚焦自己的业务领域
✅ 10.7 如何做服务熔断、限流、降级?你用过哪些中间件?
🔒 熔断(Circuit Breaker):
-
防止调用故障服务造成连锁反应
-
工具:
opossum
(Node.js 熔断器)
🚦 限流(Rate Limiting):
-
限制请求频率
-
工具:
express-rate-limit
、Nginx 限速、Redis 计数器
📉 降级(Fallback):
-
某服务不可用时返回默认数据或提示稍后重试
-
可配合熔断器一起实现 fallback 回调
✅ 10.8 如何监控整个微服务系统的健康状态?用什么工具?
✅ 监控指标:
-
每个服务的 CPU / 内存 / QPS / 响应时间
-
接口错误率、失败请求报警
-
服务是否存活(健康检查)
✅ 工具推荐:
工具 | 说明 |
---|---|
Prometheus | 拉取指标数据,配合 Grafana 展示 |
Grafana | 可视化界面、设置报警规则 |
OpenTelemetry | 全链路追踪、服务调用链分析 |
Jaeger | 服务链路追踪 |
PM2 + Keymetrics | Node.js 特化监控 |
✅ 10.9 微服务部署中你是如何组织目录结构和配置的?
✅ 一般组织方式:
/services/auth-service/user-service/order-service/shared
/dockerdocker-compose.yml
.env
-
每个服务单独 repo 或 mono-repo 中一个文件夹
-
配置统一放
.env
/ config 模块中,使用 dotenv 管理 -
使用
docker-compose
启动多服务
✅ 10.10 NestJS 如何支持微服务?你用过它的 @Microservice() 装饰器吗?
NestJS 内置微服务支持,通过以下方式实现不同协议的服务。
✅ 微服务通信协议支持:
-
TCP(默认)
-
Redis
-
NATS
-
MQTT
-
Kafka
-
gRPC
✅ 使用方式:
const app = await NestFactory.createMicroservice(AppModule, {transport: Transport.TCP,options: { host: '127.0.0.1', port: 3001 },
});
app.listen();
✅ 消息处理:
@MessagePattern('get_user')
handleUser(@Payload() data: any) {return this.userService.findUser(data.id);
}
@MessagePattern()
是微服务专用装饰器,用于监听消息主题,替代 HTTP 的@Get()
、@Post()
✅ 总结表格
编号 | 关键知识点 | 核心工具/关键词 |
---|---|---|
10.1 | 单体 vs 微服务 | 模块拆分、独立部署 |
10.2 | 通信方式 | REST / gRPC / MQ |
10.3 | 注册与发现 | Consul / Eureka / Nacos |
10.4 | 分布式事务 | TCC / SAGA / 事务消息 |
10.5 | 鉴权方案 | JWT / API Key / OAuth2 |
10.6 | 解耦策略 | OpenAPI / 事件驱动 / BFF |
10.7 | 熔断限流降级 | opossum / express-rate-limit / Redis |
10.8 | 服务监控 | Prometheus / Grafana / Jaeger |
10.9 | 项目结构与配置管理 | Mono-repo / Docker / dotenv |
10.10 | NestJS 微服务 | @Microservice() / @MessagePattern() |