谢飞机面试记:Spring Boot + Kafka + Redis 在电商秒杀场景中的技术连环问
2026/7/31 17:41:52 网站建设 项目流程

谢飞机面试记:Spring Boot + Kafka + Redis 在电商秒杀场景中的技术连环问

面试官:严肃、眼神锐利、笔记本上画着时序图
谢飞机:格子衫+双肩包,坐下前先擦了三遍椅子,简历写着“精通Spring全家桶(除源码)”


🌟 第一轮:秒杀基础架构 —— “你真用过Spring Boot写高并发?”

面试官(翻开简历):你们项目里做618秒杀,QPS 5万,用的什么技术栈?

谢飞机(挺直腰板):Spring Boot 2.7!我写了@RestController,加了@Valid校验用户ID和商品ID,还用了Lombok,一行代码搞定@Data!

✅ 面试官点头:嗯,注解用得熟——那Controller层怎么防刷?

谢飞机:加了@RateLimit!…啊不是,是用拦截器+Redis计数器,每分钟最多5次请求!

✅ 面试官微笑:不错,知道用Redis做限流。那——如果同一用户反复抢同一个商品,你怎么保证只扣一次库存?

谢飞机(挠头):呃…我用synchronized(this)锁住service方法…

❌ 面试官皱眉:单机OK,集群呢?

谢飞机(小声):那…加个分布式锁?Redis…setnx?

✅ 面试官:勉强及格——下一题:库存扣减成功后,订单怎么生成?同步还是异步?

谢飞机:当然是同步!new Order() → orderDao.insert() → return success!

❌ 面试官合上本子:…你刚说QPS 5万,DB扛得住吗?


⚡ 第二轮:削峰填谷 —— “Kafka不是用来发日志的”

面试官(打开架构图):我们把订单创建拆成两阶段:预占库存 → 异步落单。用什么解耦?

谢飞机(自信):RabbitMQ!我配过application.yml,exchange type是direct,routingKey是order.create…

✅ 面试官:很好,但为什么不用Kafka?

谢飞机(卡壳):Kafka…吞吐高?…好像比RabbitMQ快一点?

❌ 面试官:不只是快。它有分区、副本、ISR机制,能支撑百万级TPS写入;更重要的是——顺序性保障。比如用户A的3次下单请求,必须按时间顺序处理,否则可能超卖。RabbitMQ单队列是FIFO,但集群下多消费者无法保证全局有序;而Kafka通过指定partition key(如userId),让同用户请求进同一分区,天然保序。

谢飞机(恍然):哦!所以key设成userId,就能串行处理!

✅ 面试官:对。那消息失败怎么办?

谢飞机:重试!…重试三次,再进死信队列!

✅ 面试官追问:重试时发现库存已扣完,怎么避免重复下单?

谢飞机(憋红脸):…加唯一索引?订单号MD5去重?

✅ 面试官:接近了——更优解是幂等性设计:用Redis记录「用户+商品+活动ID」的已处理标识(SETNX + 过期时间),消费前先校验,通过才落库。


🧠 第三轮:缓存攻防战 —— “Redis不是万能钥匙”

面试官(画出缓存穿透/击穿/雪崩三连图):秒杀商品详情页,缓存怎么设计?

谢飞机:用Redis缓存JSON!key是item:1001,value是商品VO,过期时间30分钟!

✅ 面试官:基础正确。但如果黑客用脚本狂刷item:-1item:9999999这种不存在的商品ID呢?

谢飞机(愣住):…Redis里没这个key,就查DB,DB压力大…

✅ 面试官:这就是缓存穿透。解决方案?

谢飞机:布隆过滤器!…我…背过名字!

✅ 面试官:Bloom Filter可拦截99%无效请求。但还有个问题——热门商品item:1001缓存过期瞬间,大量请求同时打穿Redis直达DB,怎么办?

谢飞机(抓耳挠腮):…加随机过期时间?

✅ 面试官:对!叫缓存击穿防护:给热点key设置永不过期 + 后台异步刷新;或用Redis分布式锁(如SET key value EX 30 NX),首个请求加载DB并回填,其余等待。

最后问:如果Redis集群某节点宕机,秒杀服务直接报错?

谢飞机(叹气):…应该…有降级?熔断?

✅ 面试官:正是!用Resilience4j配置fallback:缓存不可用时,降级为本地Caffeine缓存 + 简化版商品信息(仅名称+价格),保证核心链路可用。


🚪 面试尾声

面试官合上笔记本,推了推眼镜:

“谢同学,你对Spring Boot和基础中间件有实操感,也意识到分布式问题的存在——这是工程师成长的关键起点。但秒杀不是‘功能实现’,而是业务、性能、容错、监控的系统工程。回去把Kafka分区策略、Redis布隆过滤器实现、Resilience4j fallback写个Demo,下周HR联系你二面。”

(起身握手) “祝你——下次别擦椅子了,我们等你带方案来。”


✅ 附:技术点详解(小白友好版)

🔹 场景定位:电商秒杀

  • 业务特征:瞬时超高并发(万人抢100件)、强一致性要求(库存不能超卖)、弱实时性(订单可异步生成)
  • 技术目标:削峰(抗流量)、保一致(不超卖)、高可用(故障降级)

🔹 Spring Boot:快速构建Web入口

  • @RestController+@Valid做参数校验,拦截非法请求
  • @Async或事件驱动(ApplicationEvent)解耦主流程,但生产慎用默认线程池(需自定义大小+拒绝策略)

🔹 Kafka:可靠有序的消息管道

  • 分区键(key)= userId→ 同用户请求路由到同一partition → 保证处理顺序 → 避免因乱序导致库存误判
  • acks=all + min.insync.replicas=2→ 强一致性写入,防止消息丢失
  • 消费者手动提交offset→ 处理成功后再commit,避免重复消费

🔹 Redis:多维度缓存防护体系

| 问题类型 | 现象 | 解决方案 | 关键代码/配置 | |----------|------|-----------|----------------| |缓存穿透| 查不存在key,击穿DB | 布隆过滤器(BloomFilter)预判 | Guava BloomFilter or RedisBloom module | |缓存击穿| 热点key过期,瞬时并发击穿 | 逻辑过期 + 分布式锁 |SET item:1001 "json" EX 300000 NX| |缓存雪崩| 大量key同一时间过期 | 随机TTL + 多级缓存(本地+Caffeine) |redisTemplate.expire(key, 30 + random(10), TimeUnit.MINUTES)|

🔹 分布式锁进阶提醒

  • synchronized/ReentrantLock:仅限单JVM,集群失效
  • SETNX裸用:无自动续期,易死锁
  • ✅ 推荐:RedissonRLock.lock(30, TimeUnit.SECONDS)→ 自动看门狗续期 + 可重入 + 公平锁支持

🔹 监控兜底:Micrometer + Prometheus

  • 暴露/actuator/metrics端点,监控cache.hit.ratiokafka.consumer.fetch-ratejvm.memory.used等指标
  • Grafana看板告警:当Redis命中率<95%或Kafka积压>1w,立即触发运维介入

💡 学习建议:不要死记命令!在本地用Docker跑起Spring Boot + Kafka + Redis三件套,模拟秒杀压测(JMeter),观察日志与监控变化——问题永远在现场,不在八股文里。


📌 文章标签:Java面试,Spring Boot,Kafka,Redis,电商秒杀,分布式系统
📌 作者提示:谢飞机真实存在(ID:xiefeiji_2023),已入职某电商中台组,现正学习JVM调优…

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询