欢迎光临
我们一直在努力

Java高频考点微服务篇,针对微服务的常见方案

一问一答:流行的微服务解决方案

问:目前主流的微服务开源解决方案有哪几种?答:主要有三种:Dubbo、Spring Cloud Netflix、Spring Cloud Alibaba。


问:Dubbo 是什么样的方案?答:Dubbo 是阿里开源的高性能 Java 微服务框架,核心是 RPC 调用,性能很高。它分控制面和数据面:控制面做服务治理(服务发现、流量管控等),数据面是 Consumer 和 Provider 通过 RPC 通信。支持多种协议和序列化方式,现在迭代到 Dubbo3,社区活跃度也不错。


问:Spring Cloud Netflix 呢?答:它是 Spring Cloud 的子项目,整合了 Netflix 的一堆组件,比如 Eureka 做服务发现、Ribbon 负载均衡、Hystrix 熔断、Zuul 网关。不过 Netflix 在 2018 年就停止维护这些组件了,所以现在这个方案已经进入维护模式,新项目一般不推荐用了。


问:Spring Cloud Alibaba 又是什么?答:它是 Spring Cloud 和阿里生态整合的方案,用 Nacos 做服务注册和配置中心,Sentinel 做流量控制和熔断,还集成了 RocketMQ 消息队列。组件更贴合国内业务场景,社区也比较活跃,现在是很多公司的主流选择。


问:这三个方案核心区别在哪?答:我用几个关键点对比一下:

  • 通信方式:Dubbo 是 RPC,性能更高;Spring Cloud 系列是 HTTP 调用,更通用。
  • 服务注册:Dubbo 用 ZooKeeper/Nacos,Netflix 用 Eureka(已停更),Alibaba 用 Nacos。
  • 熔断限流:Dubbo 和 Alibaba 用 Sentinel,Netflix 用 Hystrix(已停更)。
  • 社区状态:Netflix 已经凉了,Dubbo 和 Alibaba 现在都还在活跃迭代。
  • 微服务网格:Dubbo 有 Dubbo Mesh,Alibaba 支持 Service Mesh,Netflix 不支持。

问:那实际项目里该怎么选?答:

  • 追求极致性能、老项目迁移:选 Dubbo。
  • 要和阿里生态打通、国内云环境:选 Spring Cloud Alibaba。
  • Spring Cloud Netflix 就别选了,组件都停更了,踩坑没人救。

一问一答:微服务有哪些核心组件

问:微服务架构里都有哪些核心组件?答:微服务的核心组件可以分成 8 类,就像一个城市的各个职能部门,各司其职:


问:注册中心是做什么的?有哪些实现?答:注册中心就是微服务的 “电话簿”,负责服务的注册和发现,让服务之间能找到彼此。常见实现:Eureka、Nacos、Consul。


问:配置中心呢?答:配置中心是 “统一控制台”,集中管理所有服务的配置,改配置不用重启服务。常见实现:Spring Cloud Config、Nacos Config。


问:远程调用组件是干嘛的?答:远程调用就是服务之间 “打电话” 的方式,分两种:

  • RESTful API:比如 RestTemplate、Feign,像发 HTTP 请求一样调用;
  • RPC:比如 Dubbo、gRPC,性能更高,适合内部服务调用。

问:API 网关是什么角色?答:API 网关是微服务的 “大门保安 + 前台”,统一对外暴露服务,还做路由、负载均衡、安全认证、限流等。常见实现:Zuul、Gateway、APISIX。


问:分布式事务组件解决什么问题?答:分布式事务保证跨多个服务的操作要么都成功,要么都失败,避免数据不一致。常见实现:Seata。


问:熔断器和限流降级组件有什么用?答:

  • 熔断器:防止服务故障扩散,就像 “保险丝”,下游服务挂了就快速熔断,不拖垮整个系统;
  • 限流降级:防止服务被打垮,就像 “流量闸门”,请求太多就限制或降级处理。常见实现:Hystrix、Sentinel、Resilience4j。

问:分布式追踪和监控组件呢?答:分布式追踪是 “全链路监控器”,能跟踪一个请求在所有服务里的流转路径和性能,方便排查问题。常见实现:Sleuth+Zipkin、SkyWalking、Sentinel Dashboard。

一问一答:HTTP 和 RPC 的区别

问:HTTP 和 RPC 到底有什么区别?答:严格来说,它们不是一个层面的东西:

  • HTTP 是应用层通信协议,只管 “怎么传数据”;
  • RPC 是远程过程调用的思想 / 框架,强调 “像调用本地方法一样调用远程服务”,底层可以用 HTTP、TCP 等协议来传输。

问:那它们的关系是什么样的?答:可以这么理解:

  • RPC 是一个大的 “调用框架”,HTTP 可以作为它底层的传输协议;
  • 很多现代 RPC 框架(比如 gRPC、Dubbo3),底层就是用 HTTP/2 来做数据传输的,所以也可以说 RPC 是在 HTTP 之上封装的一层调用逻辑。

问:那实际开发里怎么选?答:

  • 对外服务、跨语言、通用性强:用 HTTP(RESTful API),比如给前端或第三方提供接口;
  • 内部微服务、追求高性能:用 RPC(比如 Dubbo、gRPC),减少序列化开销,调用更高效。

问:能举个通俗的例子吗?答:

  • HTTP 就像 “寄快递”:按固定格式打包(HTTP 报文),走通用快递路线(HTTP 协议),谁都能收;
  • RPC 就像 “叫同城闪送”:直接告诉闪送员 “把东西送到 XX 家”,底层可以走电动车、汽车(对应 TCP/HTTP),调用更直接、更快。

一问一答:常见的负载均衡算法

问:常见的负载均衡算法有哪些?答:主要有 6 种,分别是轮询、加权轮询、随机、加权随机、最少连接、哈希。


问:轮询算法是什么样的?答:轮询就是按顺序挨个分配请求,比如有 5 台服务器,就 1→2→3→4→5→1 循环发。适合所有服务器性能差不多的场景,简单公平,但不考虑机器实际负载。


问:加权轮询和普通轮询有什么区别?答:加权轮询会给每台服务器设一个权重,性能好的机器权重高,分到的请求就更多。比如 A 机器权重是 3,B 是 2,C 是 1,那分配顺序就会偏向 A,让更强的机器多干活。


问:随机算法呢?答:随机就是随便挑一台服务器发请求,每台机器被选中的概率一样。实现简单,适合服务器性能相近的场景,但完全不考虑负载,可能会把请求堆到某台忙的机器上。


问:加权随机和随机的区别?答:加权随机是在随机的基础上加上权重,权重越高的机器,被随机选中的概率越大。既保留了随机的简单,又能根据机器性能分配流量,比纯随机更合理。


问:最少连接算法是什么原理?答:最少连接会看每台服务器当前的活跃连接数,把新请求发给连接数最少的那台。适合请求处理时间不一样的场景,能动态平衡负载,避免忙的机器更忙。


问:哈希算法是怎么用的?答:哈希算法会根据请求的某个特征(比如客户端 IP、用户 ID、URL)算哈希值,再映射到对应的服务器。这样同一个用户的请求总会落到同一台机器上,适合需要会话保持的场景,比如登录状态、缓存。


问:实际项目里怎么选这些算法?答:

  • 机器性能差不多:用轮询或随机;
  • 机器性能有差异:用加权轮询或加权随机;
  • 要动态平衡负载:用最少连接;
  • 要会话保持:用哈希。

一问一答:Seata 支持的分布式事务模式

问:Seata 支持哪些分布式事务模式?答:Seata 主要支持 4 种模式:AT 模式、TCC 模式、SAGA 模式和 XA 模式。


问:AT 模式是什么?它是怎么工作的?答:AT 模式是 Seata 默认的模式,也是最常用的一种,属于自动补偿型。

  • 原理:Seata 会拦截业务 SQL,在本地事务提交前,生成回滚日志(undo log);
  • 一阶段:各分支事务本地提交,释放本地锁,但保留全局锁;
  • 二阶段:如果所有分支都成功,就全局提交并清理 undo log;如果有失败,就根据 undo log 自动回滚。
  • 优点:对业务代码侵入小,几乎无感知;缺点:依赖数据库行锁,性能有一定损耗。

问:TCC 模式是什么?答:TCC 是Try-Confirm-Cancel的缩写,属于业务补偿型,需要业务代码自己实现三个阶段:

  • Try:预留资源(比如冻结库存、冻结金额);
  • Confirm:确认提交,真正扣减资源;
  • Cancel:取消预留,回滚资源。
  • 优点:性能高,不依赖数据库锁,适合高并发场景;缺点:代码侵入大,需要自己保证幂等和防悬挂。

问:SAGA 模式是什么?答:SAGA 是事件驱动型的长事务模式,适合业务流程长、多个服务串联的场景。

  • 原理:把一个大事务拆成多个子事务,每个子事务对应一个服务,依次执行;
  • 如果某个子事务失败,就反向执行之前所有子事务的补偿操作,逐步回滚到初始状态;
  • 优点:适合长流程、异步场景,扩展性好;缺点:数据一致性是最终一致,不是强一致,补偿逻辑复杂。

问:XA 模式是什么?答:XA 模式是基于数据库 XA 协议的两阶段提交模式,属于强一致型。

  • 原理:依赖数据库本身的 XA 事务能力,Seata 作为协调者,分两阶段:
  • Prepare:各分支事务预提交,锁定资源;
  • Commit/Rollback:全局协调者通知所有分支提交或回滚;
    • 优点:强一致性,业务代码无侵入;缺点:性能差,锁定资源时间长,不适合高并发场景。

    问:实际项目里怎么选这些模式?答:

    • 追求简单、对性能要求不极端:选AT 模式(默认方案,最省心);
    • 高并发、性能优先:选TCC 模式(需要自己写补偿逻辑);
    • 长流程、异步业务:选SAGA 模式;
    • 强一致性要求、并发不高:选XA 模式(比如金融核心场景)。

    一问一答:Kafka 消息丢失的情况及解决办法

    问:Kafka 消息丢失主要分哪几类?答:主要分两类:发送端丢失和消费端丢失。


    问:发送端为什么会丢消息?怎么解决?答:发送端丢失和acks配置强相关,分三种情况:

  • acks=0:producer 发完就走,完全不等 broker 确认,性能最高但最容易丢消息。
      • 解决:除非是对数据丢失不敏感的场景(比如统计报表),否则别用这个配置。
  • acks=1:只等 leader 写入本地日志就返回,不等 follower 同步。如果 leader 刚写完就挂了,而 follower 还没同步,消息就丢了。
      • 解决:把acks设为-1(也就是all),同时配合min.insync.replicas配置大于 1,保证至少有 2 个副本同步成功。
  • acks=-1/all:leader 要等所有min.insync.replicas配置的副本都写入成功才返回。只要还有一个副本存活,消息就不会丢。
      • 注意:如果min.insync.replicas=1,那效果和acks=1一样,还是可能丢消息,所以要保证这个值≥2。

    问:消费端为什么会丢消息?怎么解决?答:消费端丢失主要是自动提交 offset导致的:

    • 如果配置了自动提交,consumer 刚拿到消息还没处理完,就自动提交了 offset;如果此时 consumer 宕机,这条未处理的消息就永远丢了,下次也消费不到。
    • 解决:
  • 关闭自动提交,改成手动提交 offset;
  • 等业务逻辑处理完成后,再手动调用commitSync()或commitAsync()提交 offset;
  • 配合重试机制,保证消息处理失败后能重新消费。

  • 问:还有其他可能丢消息的场景吗?答:还有一种是Broker 端丢失:

    • 比如 Broker 所在机器突然断电,而消息还没刷盘(只在内存里),就会丢失。
    • 解决:把log.flush.interval.messages和log.flush.interval.ms调小,让消息尽快刷盘;或者使用acks=-1+ 多副本,保证即使一个 Broker 挂了,还有其他副本能恢复数据。

    一问一答:Kafka 消息重复消费的情况及解决办法

    问:Kafka 消息重复消费主要有哪几类场景?答:主要分两类:发送端导致的重复和消费端导致的重复。


    问:发送端为什么会造成重复消费?答:发送端配置了重试机制时容易出现:

    • 比如网络抖动导致发送超时,producer 以为消息没发成功,就会重试发送;
    • 但实际上 broker 已经收到并写入了消息,重试后就会产生两条一模一样的消息;
    • 消费端拉取时,就会重复消费这两条内容相同的消息。

    问:消费端为什么会重复消费?答:消费端重复消费主要和手动提交 offset有关:

    • 消费端拉取了一批消息,处理了一部分,但还没来得及提交 offset,服务就挂了;
    • 下次重启后,consumer 会从上次提交的 offset 位置重新拉取这批数据,导致已经处理过的消息被再次处理;
    • 这就造成了重复消费。

    问:怎么解决消息重复消费的问题?答:核心思路是消费端做幂等处理,保证同一条消息被处理多次和处理一次的结果一致:

  • 业务幂等:
      • 利用数据库唯一约束:比如用消息 ID 作为唯一键,插入前先判断是否存在,存在就跳过;
      • 或者用分布式锁(Redis/Redisson),以消息 ID 为锁 key,处理前加锁,处理完释放;
  • Kafka 幂等生产者:
      • 开启enable.idempotence=true,让 producer 保证同一条消息只会被写入一次;
      • 配合acks=-1和min.insync.replicas≥2,从源头减少重复消息的产生;
  • 优化消费提交:
      • 尽量让消息处理逻辑轻量化,缩短处理时间,减少服务挂在 “处理中未提交” 的概率;
      • 或者用批量处理 + 分段提交,处理完一小批就提交一次 offset,降低重复范围。

    问:有没有更简单的幂等方案?答:最常用的是数据库唯一键 + 消息 ID:

    • 每条消息都有唯一标识(比如业务 ID + 时间戳,或 Kafka 自带的topic+partition+offset);
    • 处理消息前,先把这个唯一标识插入到数据库的幂等表中,用唯一约束保证不会重复插入;
    • 插入成功就继续处理业务,插入失败就直接跳过,认为这条消息已经处理过了。

    一问一答:Kafka 线上消息积压如何解决

    问:Kafka 线上出现消息积压该怎么处理?答:遇到积压,先看原因,通常分消费慢和消费失败两种情况,对应两种紧急处理方案。


    问:第一种情况,发送太快 / 消费太慢导致大量积压,怎么解决?答:这是生产速度大于消费速度,导致堆积了上百万条消息。

    • 临时扩容:修改消费端代码,把收到的消息快速转发到一个新的 Topic(新 Topic 可以设置很多分区);
    • 并发消费:然后启动多个消费者实例,同时消费新 Topic 的不同分区,利用多分区 + 多消费者提升消费并行度,快速把积压数据 “掏空”。

    问:第二种情况,消费失败一直重试导致积压,怎么解决?答:这是消费端逻辑有 bug 或格式变更,导致一直消费不成功,越积越多。

    • 转移死信队列:把这些消费失败的消息,直接转发到 ** 专门的死信队列(DLQ)** 里,先保证主消费链路不阻塞;
    • 事后复盘:等线上压力缓解后,再慢慢分析死信队列里的问题,修复代码后把失败消息重新消费,避免线上雪崩。

    问:日常怎么预防消息积压?答:

  • 监控预警:设置堆积阈值,比如分区堆积超过 10 万条就报警;
  • 动态扩容:根据监控自动增加消费实例数;
  • 异步处理:消费端如果逻辑复杂,先把消息落地(比如写入本地缓存 / 队列),再异步处理,提高消费速度。
  • 赞(0)
    未经允许不得转载:171主机测评 » Java高频考点微服务篇,针对微服务的常见方案
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址