java面试-微服务组件篇

一、服务注册与发现

1.1 Eureka(Netflix)

核心概念

  • 服务注册:微服务启动时向 Eureka Server 注册自己的网络地址(IP + Port + 服务名)

  • 服务发现:消费者从 Eureka Server 拉取服务提供者列表,通过 Ribbon 进行负载均衡调用

  • 心跳机制:客户端每 30 秒发送一次心跳,90 秒未收到则剔除服务

面试重点

复制代码
Q: Eureka 的自我保护机制是什么?
A: 当 15 分钟内超过 85% 的客户端心跳异常时,Eureka 进入自我保护模式,不再剔除服务。
   目的是防止网络分区故障导致服务大规模下线(CAP 中的 AP 体现)。

Q: Eureka 与 Zookeeper 的区别?
A: Eureka 追求 AP(可用性+分区容错),Zookeeper 追求 CP(一致性+分区容错)。
   Eureka 有自我保护机制,Zookeeper 使用 ZAB 协议保证强一致性。

关键配置

复制代码
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka1:8761/eureka,http://eureka2:8762/eureka
  instance:
    lease-renewal-interval-in-seconds: 30  # 心跳间隔
    lease-expiration-duration-in-seconds: 90 # 过期时间

1.2 Nacos(Alibaba)

优势对比

特性 Eureka Nacos
一致性 AP AP/CP 可切换
配置中心 不支持 内置支持
健康检查 客户端心跳 TCP/HTTP/MySQL 多种方式
负载均衡 Ribbon 内置 + Ribbon
生态 Spring Cloud Netflix Spring Cloud Alibaba

Nacos 注册中心原理

  1. 临时实例:通过心跳维持(类似 Eureka),AP 模式

  2. 永久实例:服务端主动探测,CP 模式(Raft 协议)

  3. 服务订阅:客户端长轮询(Long Polling)获取配置变更

    // Nacos 服务注册示例
    NamingService naming = NamingFactory.createNamingService("localhost:8848");
    naming.registerInstance("user-service", "192.168.1.100", 8080);


二、配置中心

2.1 Spring Cloud Config

架构

  • Config Server:从 Git/SVN 读取配置文件

  • Config Client:启动时从 Server 拉取配置

  • 刷新机制:依赖 Bus 消息总线 + Webhook 实现动态刷新

痛点

  • 配置实时性依赖手动刷新或 Webhook

  • 无灰度发布支持

  • 无配置权限管理

2.2 Nacos Config

核心特性

  • 动态刷新:客户端长轮询,配置变更实时推送(1 秒延迟)

  • 灰度配置:基于 Namespace + Group + DataId 隔离

  • 历史版本:支持配置回滚

  • 权限控制:RBAC 模型

    bootstrap.yml

    spring:
    cloud:
    nacos:
    config:
    server-addr: localhost:8848
    namespace: dev # 环境隔离
    group: DEFAULT_GROUP
    file-extension: yaml
    shared-configs:
    - data-id: common.yaml
    group: DEFAULT_GROUP
    refresh: true

@RefreshScope 原理

复制代码
@RefreshScope
@RestController
public class ConfigController {
    @Value("${user.name}")
    private String userName;
}

底层通过代理对象实现:配置变更时销毁旧 Bean,重新创建并注入新值。

2.3 Apollo(携程)

架构设计

  • Config Service:提供配置读取接口,客户端长轮询

  • Admin Service:提供配置管理接口(Portal 调用)

  • Portal:Web 管理界面

  • Meta Server:Eureka 注册中心(内置)

优势

  • 支持多环境、多集群

  • 完善的灰度发布、版本管理

  • 配置变更审计日志


三、服务网关

3.1 Zuul(Netflix)

过滤器类型

  1. PRE:请求路由前(认证、限流)

  2. ROUTING:路由请求到微服务

  3. POST:请求返回后(日志、统计)

  4. ERROR:错误处理

性能瓶颈

  • 基于 Servlet 阻塞 IO,单线程处理请求

  • 高并发场景性能较差(已被 Spring Cloud Gateway 取代)

3.2 Spring Cloud Gateway

核心优势

  • Reactive 非阻塞:基于 WebFlux + Netty,高并发性能优异

  • 动态路由:支持通过配置中心实时更新路由规则

  • 集成度高:内置熔断、限流、重试

核心概念

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service  # lb: 负载均衡
          predicates:
            - Path=/api/user/**
            - Method=GET
            - Header=X-Request-Id, \d+
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request-From,Gateway
            - CircuitBreaker=name=userCB,fallbackUri=forward:/fallback

Predicate 断言工厂

断言 说明
Path 路径匹配
Method HTTP 方法匹配
Header 请求头匹配
Query 查询参数匹配
Before/After/Between 时间匹配
RemoteAddr IP 匹配
Weight 权重分流

Filter 过滤器

  • GatewayFilter:单一路由生效(StripPrefix、AddHeader)

  • GlobalFilter:全局生效(认证、日志、限流)

    // 自定义全局过滤器:JWT 认证
    @Component
    public class AuthGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    String token = exchange.getRequest().getHeaders().getFirst("Authorization");
    if (token == null || !validateToken(token)) {
    exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
    return exchange.getResponse().setComplete();
    }
    return chain.filter(exchange);
    }

    复制代码
      @Override
      public int getOrder() { return -100; } // 优先级

    }


四、负载均衡

4.1 Ribbon(Netflix)

负载均衡策略

策略 说明
RoundRobinRule 轮询(默认)
RandomRule 随机
WeightedResponseTimeRule 响应时间加权
RetryRule 重试机制
BestAvailableRule 最小并发连接
ZoneAvoidanceRule 区域感知(结合 Eureka 元数据)

核心原理

  1. 从 Eureka 获取服务列表(ServerList)

  2. 通过 IRule 选择实例

  3. IPing 健康检查剔除不可用实例

    @Bean
    public IRule ribbonRule() {
    return new WeightedResponseTimeRule(); // 自定义策略
    }

4.2 Spring Cloud LoadBalancer

替代 Ribbon

  • 支持 Reactive 编程模型

  • 缓存服务列表(Caffeine)

  • 支持自定义负载均衡策略

    // 自定义负载均衡器
    public class CustomLoadBalancer implements ReactorServiceInstanceLoadBalancer {
    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
    // 自定义选择逻辑
    return Mono.just(new DefaultResponse(instance));
    }
    }


五、熔断与限流

5.1 Hystrix(Netflix,已停更)

核心概念

  • 熔断器状态:CLOSED(关闭)→ OPEN(打开)→ HALF_OPEN(半开)

  • 降级策略:快速失败、静默失败、缓存返回

  • 舱壁模式:线程池隔离(默认)或信号量隔离

配置参数

复制代码
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: THREAD  # THREAD / SEMAPHORE
          thread:
            timeoutInMilliseconds: 1000
      circuitBreaker:
        requestVolumeThreshold: 20    # 10秒内请求数阈值
        errorThresholdPercentage: 50  # 错误率阈值
        sleepWindowInMilliseconds: 5000 # 熔断持续时间

为什么停更?

  • 性能问题:基于线程池隔离开销大

  • 功能局限:无自适应限流、无控制台

  • Netflix 转向内部替代方案

5.2 Sentinel(Alibaba)

流量控制规则

控制维度 说明
QPS 每秒查询数
线程数 并发线程数
关联限流 当关联资源达到阈值时限流当前资源
链路限流 针对调用链路的入口资源限流

熔断策略

  1. 慢调用比例:慢调用占比超过阈值触发熔断

  2. 异常比例:异常比例超过阈值触发熔断

  3. 异常数:异常数超过阈值触发熔断

    @SentinelResource(
    value = "getUser",
    blockHandler = "getUserBlockHandler", // 限流/降级处理
    fallback = "getUserFallback" // 异常处理
    )
    public User getUser(Long id) {
    return userMapper.selectById(id);
    }

    public User getUserBlockHandler(Long id, BlockException ex) {
    return new User("限流降级");
    }

Sentinel vs Hystrix

特性 Hystrix Sentinel
隔离策略 线程池/信号量 信号量
熔断策略 错误率 慢调用/异常比例/异常数
限流 不支持 支持 QPS/线程数/热点参数
控制台 简陋 强大(实时监控、规则配置)
自适应 不支持 支持系统自适应保护

5.3 Gateway 限流

基于 Redis 的令牌桶算法

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: rate_limit_route
          uri: lb://user-service
          predicates:
            - Path=/api/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10  # 每秒填充速率
                redis-rate-limiter.burstCapacity: 20  # 桶容量
                key-resolver: "#{@userKeyResolver}"    # 限流维度

@Bean
public KeyResolver userKeyResolver() {
    return exchange -> Mono.just(
        exchange.getRequest().getHeaders().getFirst("X-User-Id")
    );
}

六、分布式事务

6.1 Seata(Alibaba)

核心角色

  • TC (Transaction Coordinator):事务协调器,维护全局事务状态

  • TM (Transaction Manager):事务管理器,定义全局事务范围

  • RM (Resource Manager):资源管理器,管理分支事务

四种模式

模式 原理 适用场景
AT 自动补偿(Undo Log) 简单 CRUD,无复杂 SQL
TCC Try-Confirm-Cancel 复杂业务,需预留资源
Saga 长事务,正向+逆向补偿 业务流程长,需状态机
XA 两阶段提交 强一致性要求

AT 模式原理

复制代码
1. TM 开启全局事务 @GlobalTransactional
2. RM 执行业务 SQL,记录 Undo Log(前后镜像)
3. 一阶段:直接提交本地事务
4. 二阶段:成功则删除 Undo Log,失败则回滚

@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
public void createOrder(Order order) {
    orderService.create(order);      // 分支事务 1
    storageService.deduct(order);    // 分支事务 2
    accountService.debit(order);     // 分支事务 3
}

脏写问题解决方案

  • 全局锁:一阶段提交前获取全局锁,二阶段释放

  • 脏写检查:回滚时对比当前数据与 Undo Log 后镜像


七、链路追踪

7.1 Sleuth + Zipkin

核心概念

  • Trace:一次完整请求链路(全局唯一 TraceId)

  • Span:一次调用单元(SpanId + ParentId)

  • Annotation:时间戳事件(cs/sr/ss/cr)

集成方式

复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>

spring:
  zipkin:
    base-url: http://localhost:9411
    sender:
      type: kafka  # 高并发场景用消息队列传输
  sleuth:
    sampler:
      probability: 0.1  # 采样率 10%

7.2 SkyWalking

优势

  • 自动探针:无代码侵入(Java Agent)

  • 多语言支持:Java、.NET、Node.js、Go

  • 性能分析:方法级性能剖析

  • 告警机制:支持 Webhook 通知

核心指标

  • CPM:每分钟调用数

  • Avg Response Time:平均响应时间

  • P99/P95:百分位延迟

  • Apdex:应用性能指数


八、服务间通信

8.1 OpenFeign

声明式 HTTP 客户端

复制代码
@FeignClient(
    name = "user-service",
    fallback = UserClientFallback.class,
    configuration = FeignConfig.class
)
public interface UserClient {
    @GetMapping("/users/{id}")
    User getUser(@PathVariable("id") Long id);
    
    @PostMapping("/users")
    User createUser(@RequestBody User user);
}

性能优化

复制代码
feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 10000
  compression:
    request:
      enabled: true   # 开启 Gzip 压缩
    response:
      enabled: true
  httpclient:
    enabled: false
  okhttp:
    enabled: true     # 使用 OkHttp(连接池复用)
  hystrix:
    enabled: true     # 开启熔断

8.2 Dubbo(Alibaba)

核心架构

  • Provider:服务提供者

  • Consumer:服务消费者

  • Registry:注册中心(Nacos/Zookeeper)

  • Monitor:监控中心

  • Container:服务运行容器

通信协议

协议 特点
Dubbo 默认,NIO 异步,TCP 长连接
RMI JDK 标准,阻塞 IO
Hessian HTTP 协议,跨语言
gRPC HTTP/2,ProtoBuf 序列化

负载均衡策略

  • Random(默认)

  • RoundRobin

  • LeastActive(最少活跃调用数)

  • ConsistentHash(一致性哈希)


九、消息驱动

9.1 Spring Cloud Stream

核心概念

  • Binder:绑定器(RabbitMQ/Kafka/RocketMQ)

  • Channel:消息通道(Source/Processor/Sink)

  • Binding:桥接 Channel 与外部消息系统

    @EnableBinding(Sink.class)
    public class MessageConsumer {
    @StreamListener(Sink.INPUT)
    public void handle(String message) {
    System.out.println("Received: " + message);
    }
    }

9.2 RocketMQ

消息类型

  • 普通消息:同步/异步/单向发送

  • 顺序消息:全局有序 / 分区有序(HashKey)

  • 延时消息:18 个固定延迟级别

  • 事务消息:Half Message + 本地事务 + 回查

    // 事务消息
    TransactionMQProducer producer = new TransactionMQProducer("group");
    producer.setTransactionListener(new TransactionListener() {
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
    // 执行本地事务
    return LocalTransactionState.COMMIT_MESSAGE;
    }

    复制代码
      @Override
      public LocalTransactionState checkLocalTransaction(MessageExt msg) {
          // 事务回查
          return LocalTransactionState.COMMIT_MESSAGE;
      }

    });


十、高频面试题汇总

Q1: Spring Cloud 与 Dubbo 的区别?

答:

  1. 通信方式:Spring Cloud 基于 HTTP(REST),Dubbo 基于 RPC(TCP)

  2. 生态完整性:Spring Cloud 是一站式解决方案(网关、配置、熔断),Dubbo 需自行集成

  3. 性能:Dubbo RPC 性能优于 HTTP,但 HTTP 更易调试和跨语言

  4. 注册中心:Spring Cloud 可用 Eureka/Nacos,Dubbo 常用 Zookeeper/Nacos

  5. 适用场景:Spring Cloud 适合快速构建微服务,Dubbo 适合高性能、大规模服务治理

Q2: 微服务拆分原则?

答:

  • DDD bounded context:按业务领域拆分

  • 高内聚低耦合:服务间依赖最小化

  • 数据独立性:每个服务独立数据库

  • 团队规模:遵循"两个披萨原则"(6-10 人维护一个服务)

  • 演进式拆分:从单体逐步拆分,避免过度设计

Q3: 分布式事务如何解决?

答:

  • 最终一致性:消息队列 + 本地事务表 + 定时补偿

  • 强一致性:Seata AT/XA 模式(性能损耗大)

  • TCC:业务层实现 Try/Confirm/Cancel

  • Saga:长事务拆分,失败时执行补偿操作

  • 最大努力通知:如支付回调,允许失败重试

Q4: 服务雪崩怎么解决?

答:

  1. 熔断:Hystrix/Sentinel 快速失败

  2. 限流:网关层 QPS 限制、热点参数限流

  3. 降级:非核心功能关闭,保证核心链路

  4. 隔离:线程池隔离、舱壁模式

  5. 超时设置:合理设置 RPC 超时时间

  6. 缓存:多级缓存减少数据库压力

Q5: 如何设计高可用微服务架构?

答:

  • 多活部署:同城双活 / 异地多活

  • 注册中心集群:Eureka 对等复制、Nacos Raft 集群

  • 配置中心高可用:Apollo 多环境部署、Nacos 集群

  • 网关层:多节点 + Nginx/Keepalived 负载均衡

  • 数据库:读写分离、分库分表、主从复制

  • 监控告警:Prometheus + Grafana + Alertmanager


十一、技术选型建议

场景 推荐方案 备选方案
注册中心 Nacos Consul、Eureka
配置中心 Nacos / Apollo Spring Cloud Config
服务网关 Spring Cloud Gateway Kong、APISIX
熔断限流 Sentinel Hystrix(已过时)
分布式事务 Seata AT TCC 自研、Saga
链路追踪 SkyWalking Zipkin、Jaeger
消息队列 RocketMQ Kafka、RabbitMQ
服务通信 OpenFeign + Ribbon Dubbo、gRPC
相关推荐
一只大袋鼠1 小时前
Java进阶:CGLIB动态代理解析
java·开发语言
环流_1 小时前
HTTP 协议的基本格式
java·网络协议·http
爱滑雪的码农1 小时前
Java基础十三:Java中的继承、重写(Override)与重载(Overload)详解
java·开发语言
【 】4231 小时前
C++&STL(Standard Template Library,标准模板库)
java·开发语言·c++
茉莉玫瑰花茶1 小时前
LangChain 核心组件 [ 2 ]
java·数据库·langchain
信徒_2 小时前
ID 生成技术选型
java
a8a3022 小时前
Laravel8.x新特性全解析
java·spring boot·后端
XiYang-DING2 小时前
【Java EE】CAS(Compare And Swap)
java·开发语言·java-ee
前端百草阁2 小时前
【吃透 Promise】从基础到面试高频(手写 + 输出题 + 原理)
okhttp·面试·职场和发展