Java 分布式相关面试题总结

Java 分布式相关面试题总结 下面整理一篇适合 Java 后端开发面试的分布式相关面试题覆盖分布式基础、CAP、分布式锁、分布式事务、注册中心、配置中心、服务调用、限流熔断、消息队列、缓存一致性等常见内容。一、分布式基础1. 什么是分布式系统分布式系统是指多个独立的计算机节点通过网络进行通信和协作对外提供统一服务的系统。简单理解一个业务系统不再部署在一台机器上而是拆分成多个服务部署在多台机器上通过网络调用完成整体功能。例如用户服务订单服务商品服务支付服务库存服务这些服务共同组成一个电商系统。2. 为什么要使用分布式系统主要原因有以下几点1提升系统性能单机性能有限通过多台机器共同处理请求可以提升系统整体吞吐量。2提高系统可用性某个节点宕机后其他节点仍然可以继续提供服务。3方便系统扩展当流量变大时可以通过增加机器节点进行水平扩容。4降低系统耦合将复杂系统拆分成多个独立服务不同服务可以独立开发、部署和维护。3. 分布式系统会带来哪些问题分布式系统虽然可以提升性能和扩展性但也会带来很多问题网络延迟网络故障服务调用失败数据一致性问题分布式事务问题分布式锁问题服务注册与发现问题配置管理问题日志追踪问题接口幂等性问题雪崩、限流、熔断、降级问题二、CAP 和 BASE 理论4. 什么是 CAP 理论CAP 理论指的是分布式系统中的三个特性CConsistency一致性AAvailability可用性PPartition Tolerance分区容错性CAP 理论认为在分布式系统中C、A、P 三者最多只能同时满足两个不能三者兼得。5. CAP 中的一致性是什么意思一致性指的是多个节点上的数据在同一时刻保持一致。例如用户下单后订单服务和库存服务的数据应该保持一致。6. CAP 中的可用性是什么意思可用性指的是系统在任何时候都能够对客户端请求返回响应。即使部分节点发生故障系统也要尽可能继续提供服务。7. CAP 中的分区容错性是什么意思分区容错性指的是当分布式系统出现网络分区时系统仍然可以继续运行。网络分区可以理解为部分节点之间因为网络故障无法正常通信。在分布式系统中网络故障是无法完全避免的所以P 通常是必须保证的。8. CAP 在实际项目中如何取舍在实际分布式系统中通常必须保证 P因此需要在 C 和 A 之间取舍。CP 系统保证一致性和分区容错性牺牲部分可用性。例如ZooKeeperetcd适合对一致性要求高的场景如分布式锁、配置管理。AP 系统保证可用性和分区容错性牺牲强一致性。例如Eureka部分缓存系统适合对可用性要求高、允许短暂数据不一致的场景。9. 什么是 BASE 理论BASE 是对 CAP 中 AP 方案的延伸。BASE 包括Basically Available基本可用Soft State软状态Eventually Consistent最终一致性核心思想是不追求强一致性而是通过最终一致性来提升系统可用性。三、分布式锁10. 什么是分布式锁分布式锁是用于解决分布式环境下多个节点并发访问共享资源的问题。在单体应用中可以使用synchronized或ReentrantLock控制并发。但在分布式环境中不同服务部署在不同 JVM 中本地锁无法跨进程生效所以需要分布式锁。11. 分布式锁有哪些实现方式常见实现方式有基于数据库实现基于 Redis 实现基于 ZooKeeper 实现12. Redis 如何实现分布式锁Redis 实现分布式锁通常使用SET key value NX EX seconds含义NX只有 key 不存在时才设置成功EX设置过期时间防止死锁value锁标识防止误删其他线程的锁Java 示例Boolean success redisTemplate.opsForValue() .setIfAbsent(lock:order:1001, uuid, 30, TimeUnit.SECONDS); if (Boolean.TRUE.equals(success)) { try { // 执行业务逻辑 } finally { // 判断 value 是否一致再删除锁 } }13. Redis 分布式锁为什么要设置过期时间为了防止服务在加锁后宕机导致锁永远无法释放。如果不设置过期时间其他线程或服务将一直无法获取锁造成死锁。14. Redis 分布式锁为什么要设置唯一 value为了防止误删其他线程的锁。例如线程 A 获取锁过期时间 10 秒线程 A 执行业务超过 10 秒锁自动过期线程 B 获取到同一把锁线程 A 执行完后删除锁此时线程 A 可能把线程 B 的锁删掉所以释放锁时要先判断 value 是否是自己的。15. Redis 分布式锁释放锁为什么要用 Lua 脚本因为判断 value 和删除 key 这两个操作需要保证原子性。Lua 脚本示例if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 endJava 中可以通过 RedisTemplate 执行 Lua 脚本。16. 什么是 RedissonRedisson 是一个基于 Redis 的 Java 分布式工具框架提供了很多分布式对象和服务。常用功能包括分布式锁可重入锁公平锁读写锁信号量延迟队列分布式集合使用 Redisson 可以简化 Redis 分布式锁的实现。17. Redisson 分布式锁的看门狗机制是什么Redisson 默认锁过期时间是 30 秒。如果业务线程还没有执行完成Redisson 会自动续期锁的过期时间这个机制称为看门狗机制。默认情况下每隔 10 秒续期一次每次续期到 30 秒这样可以避免业务执行时间过长导致锁提前过期。四、分布式事务18. 什么是分布式事务分布式事务是指一个事务操作涉及多个数据库、多个服务或多个资源需要保证这些操作要么全部成功要么全部失败。例如用户下单创建订单扣减库存扣减余额增加积分这些操作可能分布在不同服务和数据库中因此需要解决分布式事务问题。19. 分布式事务有哪些解决方案常见方案有2PC两阶段提交3PC三阶段提交TCC本地消息表MQ 事务消息Saga 模式Seata 框架20. 什么是 2PC2PC 是 Two Phase Commit两阶段提交。分为两个阶段第一阶段准备阶段协调者询问所有参与者是否可以提交事务。参与者执行本地事务但不提交然后返回是否成功。第二阶段提交阶段如果所有参与者都成功协调者通知所有参与者提交事务。如果有任何一个参与者失败协调者通知所有参与者回滚事务。21. 2PC 有什么缺点2PC 的缺点主要有同步阻塞参与者在等待协调者指令期间会一直占用资源。单点问题如果协调者宕机事务可能无法继续。数据不一致风险如果提交阶段部分节点成功部分节点失败就可能出现数据不一致。性能较差强一致性会带来较大的性能损耗。22. 什么是 TCCTCC 是一种补偿型分布式事务方案。TCC 包括三个阶段Try预留资源Confirm确认执行Cancel取消执行例如扣库存Try 阶段冻结库存。Confirm 阶段真正扣减冻结库存。Cancel 阶段释放冻结库存。TCC 适合对一致性要求较高并且业务可以拆分为 Try、Confirm、Cancel 三个动作的场景。23. 什么是本地消息表本地消息表是一种实现最终一致性的分布式事务方案。基本流程执行业务操作在同一个本地事务中写入消息表后台任务扫描消息表将消息发送到 MQ消费者消费消息并执行业务成功后更新消息状态优点实现简单可靠性较高适合最终一致性场景缺点存在一定延迟需要定时任务扫描需要处理消息重复消费24. 什么是 MQ 事务消息MQ 事务消息是指消息发送和本地事务执行保持一致。以 RocketMQ 为例事务消息流程发送半消息执行本地事务根据本地事务结果提交或回滚消息如果 RocketMQ 不确定事务状态会进行事务回查适合下单、支付、库存等最终一致性场景。25. 什么是 SeataSeata 是一款开源的分布式事务解决方案。Seata 支持多种事务模式AT 模式TCC 模式Saga 模式XA 模式其中 AT 模式使用较多适合大多数关系型数据库场景。五、服务注册与发现26. 什么是服务注册与发现在微服务架构中服务实例数量可能很多并且服务地址会动态变化。服务注册与发现就是为了解决服务之间如何找到彼此的问题。基本流程服务启动后将自己的地址注册到注册中心消费者从注册中心获取服务地址列表消费者通过负载均衡调用服务提供者服务下线时从注册中心移除27. 常见注册中心有哪些常见注册中心包括EurekaNacosZooKeeperConsuletcd28. Eureka 和 ZooKeeper 有什么区别Eureka偏 AP更强调可用性注册中心短暂不一致可以接受适合微服务注册发现ZooKeeper偏 CP更强调一致性如果 Leader 选举期间可能短暂不可用适合分布式协调、分布式锁、配置管理29. Nacos 有什么作用Nacos 是阿里开源的服务注册与配置管理平台。主要功能服务注册与发现配置中心动态 DNS 服务服务健康检查在 Spring Cloud Alibaba 中Nacos 使用非常广泛。六、服务调用与负载均衡30. 微服务之间如何调用常见方式HTTP REST 调用RPC 调用消息队列异步调用Java 中常见组件OpenFeignRestTemplateWebClientDubbogRPC31. OpenFeign 是什么OpenFeign 是 Spring Cloud 中常用的声明式 HTTP 客户端。通过接口和注解就可以完成远程服务调用。示例FeignClient(name user-service) public interface UserClient { GetMapping(/user/{id}) UserDTO getUserById(PathVariable(id) Long id); }优点使用简单和 Spring Cloud 集成方便支持负载均衡支持熔断降级32. 什么是负载均衡负载均衡是指将请求分发到多个服务实例上避免某一台机器压力过大。常见负载均衡算法轮询随机加权轮询加权随机最少连接数一致性哈希33. 什么是一致性哈希一致性哈希是一种常用于分布式缓存和负载均衡的算法。它可以减少节点新增或删除时带来的数据迁移量。常见应用场景Redis 分片分布式缓存RPC 路由分布式存储七、熔断、限流、降级34. 什么是服务雪崩服务雪崩是指一个服务故障后引发调用链路上的其他服务大量失败最终导致整个系统不可用。例如订单服务调用库存服务库存服务响应变慢导致订单服务线程被大量阻塞最终订单服务也不可用。35. 什么是服务熔断服务熔断是指当某个服务异常比例过高时系统暂时停止调用该服务直接返回失败或降级结果。类似电路保险丝当故障过多时先断开调用防止故障扩散。36. 什么是服务降级服务降级是指当系统压力过大或部分服务不可用时主动降低部分功能的服务质量保证核心功能可用。例如商品详情页不展示推荐商品下单时暂时不发优惠券查询接口返回缓存数据评论模块暂时关闭37. 什么是限流限流是指限制系统在单位时间内能够处理的请求数量防止流量过大导致系统崩溃。常见限流算法固定窗口滑动窗口漏桶算法令牌桶算法38. 漏桶算法和令牌桶算法有什么区别漏桶算法请求进入桶中以固定速率流出。特点流出速度固定可以平滑流量不支持突发流量令牌桶算法系统以固定速率生成令牌请求必须拿到令牌才能被处理。特点支持一定突发流量使用更灵活常用于接口限流39. Sentinel 是什么Sentinel 是阿里开源的流量治理组件。主要功能包括流量控制熔断降级系统保护热点参数限流实时监控在 Spring Cloud Alibaba 体系中Sentinel 经常和 Nacos、OpenFeign 一起使用。八、消息队列40. 为什么要使用消息队列消息队列主要作用异步处理应用解耦流量削峰消息广播最终一致性例如用户下单成功后可以异步发送短信、发优惠券、增加积分不需要阻塞主流程。41. 使用消息队列会带来哪些问题常见问题包括消息丢失消息重复消费消息顺序问题消息堆积分布式事务问题消费失败重试问题42. 如何保证消息不丢失可以从三个方面考虑1生产者不丢消息开启发送确认机制发送失败进行重试记录本地消息表2MQ 不丢消息开启消息持久化主从复制多副本机制3消费者不丢消息消费成功后再手动 ACK消费失败进行重试记录消费状态43. 如何解决消息重复消费消息重复消费通常无法完全避免所以消费者需要保证幂等性。常见方案使用唯一业务 ID 去重数据库唯一索引Redis setnx 去重消费记录表状态机控制例如订单支付成功消息可以根据订单号判断是否已经处理过。44. 如何保证消息顺序消费常见方案同一业务 ID 的消息发送到同一个队列同一个队列只由一个消费者线程消费消费端根据版本号或状态机控制顺序例如同一个订单的创建、支付、发货、完成消息应该按照顺序处理。45. 如何处理消息堆积处理方式增加消费者数量提高消费线程数优化消费逻辑批量消费临时扩容消费者将堆积消息转移到新的 Topic排查下游服务是否成为瓶颈九、缓存与数据一致性46. 什么是缓存穿透缓存穿透是指查询一个数据库中也不存在的数据导致请求直接打到数据库。例如大量请求查询不存在的用户 ID。解决方案缓存空值布隆过滤器参数校验接口限流47. 什么是缓存击穿缓存击穿是指某个热点 key 过期后大量请求同时访问数据库导致数据库压力过大。解决方案热点 key 永不过期加互斥锁重建缓存提前异步刷新缓存48. 什么是缓存雪崩缓存雪崩是指大量缓存 key 在同一时间失效导致大量请求直接访问数据库。解决方案设置随机过期时间热点数据永不过期Redis 高可用集群服务限流降级多级缓存49. 如何保证 Redis 缓存和数据库一致性常见策略1先更新数据库再删除缓存这是实际项目中比较常用的方案。流程更新数据库删除缓存下次查询时重新加载缓存2延迟双删流程删除缓存更新数据库延迟一段时间后再次删除缓存用于降低并发场景下脏数据问题。3基于消息队列删除缓存数据库更新后发送消息消费者异步删除缓存。4监听 binlog通过 Canal 等工具监听数据库 binlog异步更新或删除缓存。50. 为什么通常是删除缓存而不是更新缓存因为更新缓存可能存在以下问题并发更新时容易出现旧数据覆盖新数据有些缓存数据是复杂计算结果更新成本高某些数据更新后不一定马上被访问更新缓存可能浪费资源所以常见做法是更新数据库后删除缓存让下一次查询重新构建缓存。十、接口幂等性51. 什么是接口幂等性接口幂等性是指同一个请求执行一次和执行多次产生的结果是一样的。例如查询接口天然幂等删除接口通常幂等支付、下单、扣库存接口必须重点保证幂等52. 哪些场景需要保证幂等性常见场景用户重复点击提交按钮MQ 消息重复消费网络超时导致接口重试第三方支付回调多次通知分布式任务重复执行53. 如何实现接口幂等性常见方案唯一索引Token 机制Redis setnx状态机控制防重表乐观锁版本号54. Token 防重复提交怎么实现基本流程用户进入页面时后端生成一个唯一 tokentoken 存入 Redis并返回给前端用户提交请求时携带 token后端使用 Redis 删除 token删除成功表示第一次提交删除失败表示重复提交核心点token 只能被消费一次。十一、分布式 ID55. 为什么需要分布式 ID在分布式系统中多个服务或多个数据库节点都可能生成主键 ID。如果使用数据库自增 ID可能出现ID 冲突扩展性差数据库压力大分库分表后不方便合并数据因此需要全局唯一的分布式 ID。56. 分布式 ID 有哪些实现方式常见方案UUID数据库自增 IDRedis 自增雪花算法 Snowflake美团 Leaf百度 UidGenerator57. 雪花算法是什么雪花算法是 Twitter 提出的一种分布式 ID 生成算法。生成的是一个 64 位 long 类型 ID。常见结构符号位 时间戳 机器ID 序列号优点全局唯一趋势递增性能高不依赖数据库缺点依赖机器时钟时钟回拨可能导致 ID 重复58. 雪花算法如何解决时钟回拨问题常见方案检测到时钟回拨时等待回拨时间较短则阻塞等待回拨时间较长则报警使用备用机器 ID引入逻辑时钟十二、分布式链路追踪59. 什么是分布式链路追踪在微服务系统中一个请求可能经过多个服务。分布式链路追踪用于记录请求经过的完整调用链路方便排查问题和性能瓶颈。例如一个下单请求可能经过网关 - 用户服务 - 订单服务 - 库存服务 - 支付服务 - 消息服务链路追踪可以看到每个服务的调用耗时和异常情况。60. 常见的链路追踪工具有哪些常见工具SkyWalkingZipkinPinpointJaegerSleuth目前 Java 微服务项目中SkyWalking 使用较多。十三、网关61. 什么是 API 网关API 网关是微服务系统的统一入口。客户端请求先进入网关再由网关转发到具体的后端服务。62. API 网关有什么作用常见作用路由转发统一鉴权限流熔断日志记录跨域处理黑白名单请求参数校验统一异常处理63. 常见网关有哪些常见网关Spring Cloud GatewayZuulNginxKongAPISIX目前 Spring Cloud Gateway 在 Spring Cloud 项目中使用较多。十四、常见综合面试题64. 如果一个服务调用失败你会怎么处理可以从以下几个方面回答设置合理的超时时间增加重试机制但要避免无限重试使用熔断降级记录日志和监控告警对核心接口做兜底处理使用消息队列异步解耦保证接口幂等性避免重试导致数据重复65. 如何设计一个高可用的分布式系统可以从以下方面考虑服务多实例部署注册中心高可用数据库主从或集群Redis 集群MQ 集群网关集群限流、熔断、降级数据备份监控告警灰度发布和快速回滚66. 分布式系统如何排查线上问题排查思路查看监控指标如 CPU、内存、磁盘、网络、QPS、响应时间。查看日志根据 traceId 查询完整调用链路日志。查看链路追踪判断哪个服务耗时高或报错。查看数据库是否有慢 SQL、锁等待、连接池耗尽。查看缓存Redis 是否出现大 key、热 key、连接异常。查看 MQ是否有消息堆积、消费失败。查看依赖服务判断是否是第三方接口或下游服务异常。67. 分布式系统中如何防止重复下单常见方案前端按钮置灰后端 token 防重复提交Redis 分布式锁数据库唯一索引订单状态机控制接口幂等设计推荐组合Token 防重复提交 数据库唯一索引 接口幂等68. 秒杀系统中如何使用分布式技术秒杀系统常见设计前端静态化CDN 加速网关限流Redis 预扣库存MQ 异步下单数据库削峰写入分布式锁控制并发防重复提交用户维度限购熔断降级保护系统69. 如何保证秒杀库存不超卖常见方案Redis 原子扣减库存Lua 脚本保证判断库存和扣减库存的原子性数据库乐观锁数据库条件更新例如 SQLUPDATE product_stock SET stock stock - 1 WHERE product_id 1001 AND stock 0;如果影响行数为 1说明扣减成功如果为 0说明库存不足。70. 微服务拆分时需要注意什么微服务拆分原则按业务边界拆分高内聚、低耦合避免过度拆分数据库尽量按服务拆分服务之间通过接口通信核心链路减少远程调用做好接口版本管理做好日志、监控、链路追踪十五、面试回答技巧回答分布式问题时不要只背概念最好按照下面结构回答1. 先解释概念 2. 再说明应用场景 3. 然后说常见方案 4. 最后补充项目实践和注意事项例如面试官问Redis 分布式锁怎么实现可以这样回答Redis 分布式锁主要用于解决分布式环境下多个服务实例并发访问共享资源的问题。一般使用 set key value nx ex 命令加锁同时设置过期时间防止死锁value 使用唯一标识防止误删其他线程的锁。释放锁时需要先判断 value 是否一致再删除 key并且这个过程要用 Lua 脚本保证原子性。在实际项目中也可以直接使用 Redisson它支持可重入锁和看门狗自动续期机制。总结Java 分布式面试重点通常集中在以下几个方向分布式理论CAP、BASE 分布式锁Redis、Redisson、ZooKeeper 分布式事务TCC、MQ、本地消息表、Seata 服务治理注册中心、配置中心、负载均衡 稳定性限流、熔断、降级、雪崩 消息队列可靠投递、重复消费、顺序消费 缓存一致性穿透、击穿、雪崩、双写一致性 分布式 IDUUID、雪花算法 链路追踪SkyWalking、Zipkin 网关Gateway、Nginx如果准备 Java 中高级后端面试建议重点掌握Redis 分布式锁分布式事务解决方案MQ 消息可靠性缓存和数据库一致性服务雪崩与限流熔断分布式 ID 生成方案微服务调用链路排查思路