一问一答:流行的微服务解决方案
问:目前主流的微服务开源解决方案有哪几种?答:主要有三种: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 作为协调者,分两阶段:
- 优点:强一致性,业务代码无侵入;缺点:性能差,锁定资源时间长,不适合高并发场景。
问:实际项目里怎么选这些模式?答:
- 追求简单、对性能要求不极端:选AT 模式(默认方案,最省心);
- 高并发、性能优先:选TCC 模式(需要自己写补偿逻辑);
- 长流程、异步业务:选SAGA 模式;
- 强一致性要求、并发不高:选XA 模式(比如金融核心场景)。
一问一答:Kafka 消息丢失的情况及解决办法
问:Kafka 消息丢失主要分哪几类?答:主要分两类:发送端丢失和消费端丢失。
问:发送端为什么会丢消息?怎么解决?答:发送端丢失和acks配置强相关,分三种情况:
-
- 解决:除非是对数据丢失不敏感的场景(比如统计报表),否则别用这个配置。
-
- 解决:把acks设为-1(也就是all),同时配合min.insync.replicas配置大于 1,保证至少有 2 个副本同步成功。
-
- 注意:如果min.insync.replicas=1,那效果和acks=1一样,还是可能丢消息,所以要保证这个值≥2。
问:消费端为什么会丢消息?怎么解决?答:消费端丢失主要是自动提交 offset导致的:
- 如果配置了自动提交,consumer 刚拿到消息还没处理完,就自动提交了 offset;如果此时 consumer 宕机,这条未处理的消息就永远丢了,下次也消费不到。
- 解决:
问:还有其他可能丢消息的场景吗?答:还有一种是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,处理前加锁,处理完释放;
-
- 开启enable.idempotence=true,让 producer 保证同一条消息只会被写入一次;
- 配合acks=-1和min.insync.replicas≥2,从源头减少重复消息的产生;
-
- 尽量让消息处理逻辑轻量化,缩短处理时间,减少服务挂在 “处理中未提交” 的概率;
- 或者用批量处理 + 分段提交,处理完一小批就提交一次 offset,降低重复范围。
问:有没有更简单的幂等方案?答:最常用的是数据库唯一键 + 消息 ID:
- 每条消息都有唯一标识(比如业务 ID + 时间戳,或 Kafka 自带的topic+partition+offset);
- 处理消息前,先把这个唯一标识插入到数据库的幂等表中,用唯一约束保证不会重复插入;
- 插入成功就继续处理业务,插入失败就直接跳过,认为这条消息已经处理过了。
一问一答:Kafka 线上消息积压如何解决
问:Kafka 线上出现消息积压该怎么处理?答:遇到积压,先看原因,通常分消费慢和消费失败两种情况,对应两种紧急处理方案。
问:第一种情况,发送太快 / 消费太慢导致大量积压,怎么解决?答:这是生产速度大于消费速度,导致堆积了上百万条消息。
- 临时扩容:修改消费端代码,把收到的消息快速转发到一个新的 Topic(新 Topic 可以设置很多分区);
- 并发消费:然后启动多个消费者实例,同时消费新 Topic 的不同分区,利用多分区 + 多消费者提升消费并行度,快速把积压数据 “掏空”。
问:第二种情况,消费失败一直重试导致积压,怎么解决?答:这是消费端逻辑有 bug 或格式变更,导致一直消费不成功,越积越多。
- 转移死信队列:把这些消费失败的消息,直接转发到 ** 专门的死信队列(DLQ)** 里,先保证主消费链路不阻塞;
- 事后复盘:等线上压力缓解后,再慢慢分析死信队列里的问题,修复代码后把失败消息重新消费,避免线上雪崩。
问:日常怎么预防消息积压?答:



