51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

从单体架构到微服务架构,描述一下你参与的投放系统架构演进过程,以及微服务拆分的原则和遇到的挑战。

360Web服务端开发工程师-投放方向难度:中等

答案

1) 【一句话结论】我参与的投放系统从单体架构演进到微服务架构,核心是为了突破单体系统的扩展瓶颈(如数据库连接池耗尽、CPU满载导致性能下降),通过按业务能力拆分服务(用户、创意、策略、统计服务),依据领域驱动设计(DDD)的子域划分作为拆分边界,采用Saga模式处理数据一致性,借助Nacos注册发现、Hystrix熔断等工具解决服务治理问题,最终实现用户服务QPS从1万提升至5万,故障恢复时间缩短至30秒以内。

2) 【原理/概念讲解】老师口吻解释:单体架构是将所有业务模块(用户管理、广告创意、投放策略、数据统计)部署在单一应用内,共享数据库。当用户量增长时,会出现扩展瓶颈:比如数据库连接池耗尽(连接数达到最大值,新请求被拒绝,因为所有连接都在使用,无法获取新连接),CPU利用率100%(业务逻辑中,策略服务需要实时计算投放规则,包含大量数学运算,如线性回归、权重调整,导致CPU占用率持续在95%以上),响应时间超时(用户点击投放按钮后,等待结果时间过长,影响用户体验)。微服务架构则是将系统拆分为多个独立服务,每个服务负责单一业务能力(如用户服务仅处理用户信息、权限验证;创意服务仅管理广告素材、模板;策略服务仅生成投放规则、缓存策略;统计服务仅记录投放数据、分析指标),独立部署、独立开发、独立扩展,服务间通过轻量级通信(HTTP/REST或消息队列)交互。类比:单体像“一个装满所有食材的大锅,加热时所有食材都受热,调整某食材(如增加盐)需要动整个锅,所有食材都受影响;微服务像多个小锅,每个小锅负责特定食材(如汤锅、菜锅),可以单独调整每个锅的温度(如汤锅加火,菜锅保持温度),互不干扰,加热效率更高,且调整某食材只需动对应的小锅。”

3) 【对比与适用场景】

特性/维度单体架构微服务架构注意点
定义所有模块部署在单一应用内,共享数据库系统拆分为多个独立服务,每个服务负责单一业务能力微服务需考虑服务治理(注册发现、熔断等)
扩展性整体扩展,难以针对特定模块针对特定服务扩展,资源利用率高需评估服务拆分粒度,避免过度拆分
数据管理共享数据库,事务复杂(如全量事务)每服务独立数据库,需分布式事务方案(如Saga)数据一致性是关键挑战
开发与部署整体开发,部署一次模块化开发,服务独立部署(Docker容器化)部署复杂度增加,需自动化部署工具
通信方式内部调用(低延迟,强耦合)服务间调用(HTTP同步或消息队列异步)异步通信可解耦,但需消息队列保证可靠性
适用场景小规模系统(<100人团队,用户量<10万,业务单一)复杂系统(>100人团队,用户量>100万,多团队协作,业务复杂)需平衡复杂度与收益,考虑团队协作成本

4) 【示例】
假设投放系统原本是单体应用,用户量增长至10万时出现瓶颈:数据库连接池耗尽(连接数1000,实际请求量1.2万/秒,导致新请求被拒绝,错误码“连接池耗尽”),CPU利用率100%(业务逻辑中,策略服务实时计算投放规则导致CPU占用过高),响应时间超时(800ms,用户点击投放按钮后,等待结果时间过长,影响用户体验)。演进过程:

  • 拆分步骤:按业务能力拆分服务,依据DDD子域划分:
    • 核心子域(用户管理、广告创意):拆为独立服务(用户服务、创意服务),独立数据库(MySQL、MongoDB)。用户服务负责用户信息、权限验证,数据库表包括user_info、user_permission;创意服务负责广告素材、模板管理,数据库表包括creative_material、template_info。
    • 支撑子域(投放策略、数据统计):拆为独立服务(策略服务、统计服务),策略服务用Redis缓存规则(如周末促销规则),数据库表包括strategy_rule;统计服务用InfluxDB存储时序数据(如投放次数、点击率),避免写入MySQL导致性能瓶颈。
  • 请求流程对比:
    • 单体架构:投放请求 → 单体应用(用户服务查询用户信息 + 创意服务获取素材 + 策略服务生成规则 + 统计服务记录)(依赖共享MySQL数据库,模块间强耦合,用户服务查询用户信息时,连接池耗尽导致请求失败;策略服务计算规则时,CPU占用100%,导致响应超时)。
    • 微服务架构:`投放请求 → 用户服务(查询用户信息,连接池压力降低,因为独立数据库,连接数需求减少,从1000减少到200,实际请求量1.2万/秒时,连接池仍可用) → 创意服务(获取素材,MongoDB独立扩展,支持高并发读写,素材查询时间从200ms降至50ms) → 策略服务(生成规则,Redis缓存,规则查询时间从100ms降至10ms,因为缓存命中率高) → 统计服务(异步写入InfluxDB,通过消息队列(如Kafka)发送数据,不影响实时响应,写入时间从100ms降至5ms)。
  • 实际效果:用户服务扩展10个实例后,QPS从1万提升至5万(CPU利用率降至60%),策略服务规则调整(如增加周末促销折扣)仅需更新Redis缓存,无需重启服务,投放准确率提升10%;故障恢复时间从之前的2分钟缩短至30秒(因为服务独立,故障隔离,不影响其他服务)。

5) 【面试口播版答案】(约90秒)
“面试官您好,我参与的投放系统从单体架构演进到微服务架构,核心是为了解决单体系统的扩展瓶颈。最初系统是单体部署,所有模块(用户管理、广告创意、投放策略、数据统计)共享数据库,当用户量增长到10万时,出现数据库连接池耗尽(连接数1000,实际请求量1.2万/秒,新请求被拒绝)、CPU利用率100%(策略服务实时计算投放规则导致CPU占用过高)、响应时间超时(800ms)的问题。演进过程中,我们按业务能力拆分服务,依据领域驱动设计(DDD)的子域划分:用户管理(核心子域)拆为用户服务(独立MySQL数据库),广告创意(核心子域)拆为创意服务(独立MongoDB),投放策略(支撑子域)拆为策略服务(Redis+MySQL),数据统计(支撑子域)拆为统计服务(InfluxDB)。拆分原则是‘单一职责’,数据一致性用Saga模式处理(用户信息变更后,创意服务通过消息队列(Kafka)执行更新,失败则补偿回滚,确保数据最终一致)。服务治理用Nacos注册发现(配置服务地址,动态更新服务列表),Hystrix设置熔断阈值(失败率>50%触发,隔离故障服务,避免级联故障)。最终,用户服务QPS从1万提升至5万,故障恢复时间缩短至30秒,系统可扩展性和稳定性显著提升。”

6) 【追问清单】

  • 问题1:服务拆分边界如何确定?
    回答要点:依据业务能力边界(如用户管理、广告创意属于独立业务拆为服务),避免拆分过细(如用户服务拆为注册、登录、权限),结合DDD子域划分(核心子域拆独立服务,支撑子域可合并,如策略服务与统计服务可合并,因为策略生成后统计记录,逻辑相关)。
  • 问题2:如何处理微服务间的数据一致性?
    回答要点:采用Saga模式,通过消息队列异步通信,用户信息变更后发送消息到创意服务,创意服务执行更新并触发补偿步骤(如更新失败,补偿步骤回滚用户信息变更,确保数据最终一致)。
  • 问题3:服务间通信选择HTTP还是消息队列?
    回答要点:同步调用用HTTP(如用户服务查询用户信息,实时性要求高,需要立即返回结果),异步通知用消息队列(如投放成功后发送消息到统计服务,解耦调用链,提高吞吐量,避免实时响应受影响)。
  • 问题4:如何保证微服务的独立演进?
    回答要点:服务独立部署(Docker容器化,每个服务有自己的容器镜像),独立数据库(避免强依赖,如用户服务数据库与创意服务数据库分离),API版本管理(v1/v2并存,兼容旧版本调用),服务治理(熔断、限流、降级,确保服务故障不影响其他服务)。
  • 问题5:遇到的最大挑战是什么?
    回答要点:服务间通信延迟与故障隔离(如创意服务故障导致调用链中断,用Hystrix熔断隔离故障,避免级联故障,同时通过消息队列重试机制,提高可靠性)。

7) 【常见坑/雷区】

  • 拆分过细:将业务模块拆为过多服务(如用户服务拆为注册、登录、权限),增加通信成本,导致服务间调用次数过多,影响性能。
  • 忽略数据一致性:微服务独立数据库导致数据不一致(如用户信息更新后,创意服务未同步),未采用Saga方案,导致业务逻辑错误(如投放时使用旧素材信息)。
  • 没有考虑通信成本:过度依赖HTTP同步调用,导致延迟高,应结合异步消息队列,避免实时响应变慢。
  • 缺乏服务治理:未做服务注册发现、熔断、限流,导致故障扩散,如一个服务故障导致整个调用链中断。
  • 没有API版本管理:服务升级后旧版本调用失败,影响业务连续性,如策略服务从v1升级到v2,旧版本调用返回错误,导致投放失败。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1