云计算百科
云计算领域专业知识百科平台

【Java面试】——分布式架构

好的,我们继续按照原大纲,补充 微服务与分布式(★★★★★)、高并发与架构(★★★★★)、云原生(★★★★☆)、制造业与跨境电商(★★★★★)、代码能力与线上排查(★★★★★) 等剩余核心模块。这部分是高级工程师的“分水岭”,涵盖了从代码落地到架构设计、再到行业场景落地的完整闭环。


六、微服务与分布式架构(核心能力 15% + 15%)

6.1 Spring Cloud 生态核心组件精讲

6.1.1 服务注册与发现:Nacos(阿里双模注册中心)

Nacos 最大的特点是同时支持 CP 和 AP 模式(通过 spring.cloud.nacos.discovery.ephemeral 控制):

模式一致性协议适用场景数据存储
AP 模式(临时实例,默认) Distro + 异步心跳 服务发现(注重可用性,允许短暂不一致) 内存 + 异步持久化
CP 模式(持久实例) Raft 协议 配置管理、分布式锁(注重一致性) 磁盘 + 日志

核心机制:

  • 服务心跳:客户端每 5 秒发送心跳,若 15 秒未收到则标记为不健康,30 秒未收到则剔除。
  • 服务保护阈值(Protection Threshold) :当健康实例比例低于阈值(如 0.3)时,Nacos 会返回所有实例(包括不健康的),防止所有流量因少数实例宕机而完全熔断(雪崩保护)。
  • 配置中心:支持 @NacosValue 动态刷新、监听器回调(Listener)、多环境隔离(Namespace + Group + DataId)。

6.1.2 声明式远程调用:OpenFeign

  • 核心原理:利用 Spring 的 @Import + FactoryBean + JDK 动态代理。Feign 客户端接口被代理后,方法调用被编码为 HTTP 请求(通过 Contract 解析注解,Encoder 序列化参数,Client 执行 HTTP 调用)。
  • 性能优化要点:
    • 连接池:必须配置 feign.httpclient.enabled=true 并引入 Apache HttpClient 或 OkHttp,替代默认的 HttpURLConnection(无连接池,每次新建连接)。
    • 超时设置:connectTimeout(连接超时)与 readTimeout(读取超时)必须区分设置,防止下游慢 SQL 拖垮上游。
  • 熔断集成:feign.sentinel.enabled=true(若引入 Sentinel),可实现调用失败时的降级逻辑(fallback 或 fallbackFactory,可捕获异常)。

6.1.3 API 网关:Spring Cloud Gateway(基于 WebFlux)

  • 核心架构:Route(路由) + Predicate(断言工厂) + Filter(过滤器)。
  • 工作原理:Netty 接收请求 → 通过 RoutePredicateHandlerMapping 匹配路由 → 调用 FilteringWebHandler 执行全局过滤器链(Global Filter Chain) → 转发到后端微服务。
  • 关键过滤器:
    • RetryGatewayFilterFactory:重试机制(需谨慎配置,防止幂等性问题)。
    • RequestRateLimiterGatewayFilterFactory:基于 Redis + Lua 脚本实现令牌桶限流。
    • 自定义全局过滤器:实现 GlobalFilter + Ordered,用于统一鉴权、日志染色(TraceId 注入)、请求篡改等。
  • 与 Zuul 1.x 对比:Gateway 基于非阻塞(Netty + Reactor),性能远超同步阻塞的 Zuul 1.x;Zuul 2.x 虽也异步,但社区活跃度不及 Gateway。

6.1.4 熔断、限流、降级:Sentinel(阿里流量防卫兵)

Sentinel 比 Hystrix 设计更优(Hystrix 已进入维护状态):

特性SentinelHystrix
限流维度 支持 QPS、线程数、系统负载(自适应)、热点参数 仅线程池/信号量隔离
熔断策略 慢调用比例、异常比例、异常数(滑动窗口实时统计) 基于滑动窗口的失败率,需配置 metrics.rollingStats.timeInMilliseconds
规则持久化 支持动态数据源(Nacos、Apollo、Zookeeper) 需自行扩展
控制台 功能强大(实时监控、规则推送、机器列表) 简陋

核心工作流程(Slot Chain):

  • NodeSelectorSlot:构建资源调用链。
  • ClusterBuilderSlot:统计集群维度数据。
  • StatisticSlot:实时统计 QPS、响应时间、异常数。
  • ParamFlowSlot:热点参数限流(如 userId 维度)。
  • SystemSlot:系统自适应保护(CPU、Load、RT)。
  • FlowSlot:流控规则判断(QPS/线程数)。
  • DegradeSlot:熔断降级判断。
  • AuthoritySlot:黑白名单授权。
  • 生产最佳实践:所有 Feign 调用和 HTTP 入口均配置 @SentinelResource,并指定 blockHandler(限流触发)和 fallback(异常触发),配合 Nacos 实现规则动态推送。


    6.2 分布式理论基石(★★★★★)

    6.2.1 CAP 定理(布鲁尔定理)

    在分布式系统中,一致性(C)、可用性(A)、分区容错性(P) 三者不可兼得,最多只能同时满足两个。

    场景选择典型中间件
    网络正常(无分区) CA(但网络分区是常态,故基本不讨论纯 CA) 单机数据库
    发生网络分区(必选 P) CP(牺牲可用性,保证一致性) ZooKeeper、Etcd、HBase
    发生网络分区(必选 P) AP(牺牲一致性,保证可用性,最终一致) Eureka、Nacos(AP 模式)、Cassandra、RocketMQ

    在微服务中的权衡:注册中心通常选 AP(服务发现宁可读到旧地址,也不能完全不可用);配置中心/分布式锁通常选 CP(宁可短暂无法获取配置,也不能读到错误配置)。

    6.2.2 BASE 理论(AP 的延伸)

    • Basically Available(基本可用):故障时允许损失部分功能或响应时间。
    • Soft state(软状态):系统状态允许中间状态(如数据同步延迟)。
    • Eventually consistent(最终一致性):经过一段时间后,数据最终达到一致。

    实践落地:订单状态“支付中”是软状态,通过消息队列或定时对账任务保证最终一致性。


    6.3 分布式事务解决方案(★★★★★ 核心难点)

    6.3.1 两阶段提交(XA)—— 强一致性

    • 原理:Transaction Manager 协调多个资源管理器(RM),分 Prepare 和 Commit 两阶段。
    • 实现:Seata 的 AT 模式(基于 XA 改良)或 Atomikos。
    • 缺点:阻塞式锁资源(Prepare 后一直持有锁),性能差,不适合高并发;仅适合短事务。

    6.3.2 TCC(Try-Confirm-Cancel)—— 柔性事务

    三个阶段:

  • Try:预留业务资源(如扣减库存时,将库存从“可用”冻结为“已分配”)。
  • Confirm:确认执行(冻结库存真正扣减,生成订单)。
  • Cancel:取消回滚(释放冻结库存)。
  • 三大难题(必须解决,★★★★★):

    • 空回滚(Empty Rollback):Try 未执行(网络超时或未收到请求),Cancel 先到达。必须允许 Cancel 在无 Try 记录时直接返回成功(使用事务日志表判断)。
    • 悬挂(Suspension):Cancel 先执行(空回滚),后续 Try 再到达,此时 Try 应被直接拒绝(防止资源被错误预留)。方案:使用主键或 transaction_id 状态判断,若已 Cancel,则 Try 直接返回失败。
    • 幂等性(Idempotent):Try、Confirm、Cancel 都可能被重试(网络抖动),必须支持幂等(通过事务 ID 判重)。

    适用场景:订单支付、积分扣减等强一致性但允许短暂中间状态的场景。

    6.3.3 Saga(长事务补偿)—— 不用 Try 预留

    • 原理:将长事务拆分为多个本地事务(子事务),每个子事务都有对应的补偿操作(Compensation)。
    • 执行模式:
      • 向前恢复(Forward Recovery):子事务失败后,重试直到成功(适合最终成功的场景)。
      • 向后恢复(Backward Recovery):子事务失败后,逆向依次执行之前已成功子事务的补偿操作。
    • 协调方式:
      • 编排(Choreography):各服务通过事件(MQ)自行触发下一个子事务(解耦,但链路复杂难追踪)。
      • 控制(Orchestration,推荐):由 Saga 协调器 集中控制(如 Seata Saga、Apache Camel),便于管理和监控。
    • 适用场景:跨多个微服务的业务流程(如旅游预订:订酒店 → 订机票 → 订车),每个步骤允许较长时间。

    6.3.4 本地消息表 + MQ(最终一致性经典方案)

    • 核心思想:将事务执行和消息发送放在同一个本地事务中。
    • 流程:
    • 业务方执行本地事务(INSERT 订单),同时向 本地消息表 插入一条“待发送”消息(在同一本地事务中提交)。
    • 独立的 消息恢复/轮询任务(定时 Job) 扫描本地消息表,将状态为“待发送”的消息投递到 MQ。
    • MQ 消费方消费消息,执行本地事务,成功后向 MQ 回传 ACK(消费确认)。
    • 若消费方执行失败,消息重试或进入死信队列,人工/补偿机制兜底。
    • 优点:不依赖 MQ 的事务消息(对中间件无特殊要求)。
    • 缺点:需要轮询扫描表,可能产生延迟;对数据库压力较大(需建索引)。

    6.3.5 MQ 事务消息(RocketMQ / Kafka 事务)—— Outbox 模式变种

    • RocketMQ 事务消息流程:
    • 生产者发送 半消息(Half Message) ,暂不可消费。
    • 执行本地事务(如扣库存)。
    • 根据本地事务结果,向 Broker 发送 Commit 或 Rollback。
    • Broker 若长时间未收到二次确认,会回查生产者的事务执行状态(需实现 TransactionListener 的 checkLocalTransaction)。
    • Commit 后消息对消费者可见。

    与本地消息表的对比:RocketMQ 事务消息避免了数据库轮询,实时性更高,但需要 MQ 中间件支持;本地消息表方案更通用(兼容 Kafka/RabbitMQ)。

    6.3.6 Outbox 模式(微服务架构最佳实践)

    • 利用 Debezium(CDC,Change Data Capture) 或 Canal 监听数据库 Binlog(如订单表 INSERT)。
    • Binlog 变化触发同步任务,将事件推送至 MQ。这样业务代码完全零侵入,且绝对保证“至少一次”的投递。
    • 适合场景:已有老系统改造,不愿引入复杂事务逻辑。

    6.4 幂等性设计(★★★★★ 贯穿所有分布式方案)

    为什么需要幂等? 网络超时、MQ 重试、前端重复点击导致同一操作被执行多次,必须保证结果一致。

    6 种幂等实现方案:

    方案原理适用场景
    数据库唯一键 业务单号(如 order_no)作为唯一索引,重复 INSERT 直接报错 插入型业务(订单创建)
    乐观锁(版本号) UPDATE table SET version = version + 1 WHERE id = ? AND version = old_version 更新型业务(库存扣减)
    状态机(防回退) 状态流转强制单向(如 待支付 → 支付中 → 支付成功 → 已发货),不允许重复/回退 订单生命周期管理
    Token 机制(全局唯一 ID) 请求携带 request_id,服务端用 Redis 存储 SETNX request_id 1 EX 600,处理完再删除 前端表单重复提交
    分布式锁(Redis/ZK) key = 业务ID + 操作类型,tryLock 成功才执行,执行完释放(需权衡锁超时) 互斥资源操作
    消息去重表(MQ 消费方) 消费时插入 Redis(业务ID + 消费状态),处理完更新状态,通过状态判断是否已处理 异步消息消费

    七、高并发与性能优化(核心能力 10%)

    7.1 秒杀系统设计(★★★★★ 必考架构题)

    场景:100 万人抢 100 件商品。核心是 削峰填谷 + 极致读多写少。

    7.1.1 整体分层架构

    层级技术栈核心职责
    客户端层 CDN + 静态资源分离 + 页面静态化(HTML 缓存) 减少静态资源请求打到后端
    接入层(网关) Nginx + Gateway + Sentinel 限流(令牌桶)、IP 黑名单、拦截刷子流量
    业务逻辑层 微服务集群(库存、订单、用户) 业务校验(参数、库存)、异步下单
    数据层 Redis(缓存) + MQ(削峰) + DB(最终落盘) 读写分离、异步解耦、数据持久化

    7.1.2 关键步骤与核心技术

    (1)库存预热(提前加载)

    • 秒杀开始前 30 分钟,将商品库存从 DB 加载到 Redis(HSET seckill:stock:{id} total 100)。
    • 同时生成商品详情页的静态 HTML 并推送到 CDN。

    (2)极致限流(入口保护)

    • Nginx 层:limit_req_zone 按 IP 限流(如 5 次/秒)。
    • Gateway 层:基于 Redis 的令牌桶(RequestRateLimiter),每秒放行固定数量的请求(如 5000 QPS),其余直接返回“排队中”或“已售罄”。

    (3)Redis Lua 脚本(原子扣减库存)

    — 扣减库存,返回剩余数量
    local stock = redis.call('GET', KEYS[1])
    if not stock or tonumber(stock) <= 0 then
    return 1 — 无库存
    end
    redis.call('DECR', KEYS[1])
    return 1

    关键:Lua 保证原子性,避免超卖。如果库存为 0,直接返回失败,不创建订单。

    (4)异步下单 + MQ 削峰

    • 扣减 Redis 库存成功后,生成预下单 Token(如 order:token:{userId})并放入 MQ。
    • MQ 消费者(速率可控,如 200 TPS)拉取消息,执行数据库事务(创建订单、扣减 DB 库存、生成支付链接)。
    • 目的:将 100 万瞬时请求削峰为 200 TPS 的稳定流量,保护数据库。

    (5)库存分段(HotKey 分摊)

    • 如果单商品 HotKey 过于集中,可将 100 件库存拆分为 10 段(如 stock_1 ~ stock_10),每段 10 件,随机路由到不同 Redis 节点或不同 Lua 键,分散热点压力。

    (6)兜底与防重

    • Redis 标记用户抢购状态:SETNX user:123:seckill:456 1 EX 86400,防止同一用户重复抢购。
    • 异步确保最终一致:DB 扣库存失败时,需通过 MQ 反向补偿(释放 Redis 库存)。

    7.1.3 压测与容量评估

    • 使用 JMeter / Locust 模拟混合场景(正常用户 + 脚本刷子)。
    • 通过 Arthas 线上热力图 或 Grafana 监控,观察 JVM GC、系统 Load、Redis 连接数、MQ 积压情况,反向调整限流阈值和线程池大小。

    八、架构能力与 DDD 落地(核心能力 10%)

    8.1 微服务拆分原则(Monolith → Microservices)

    原则说明
    高内聚、低耦合 按业务域(Domain)而非技术层(Controller/Service/DAO)拆分
    单一职责(SRP) 一个服务只负责一个业务能力(如订单服务不处理用户登录)
    独立数据库 每个微服务拥有自己的数据库(物理隔离或 Schema 隔离),避免跨库 JOIN
    组织对齐(康威定律) 团队结构与服务架构匹配(一个团队负责一个域)

    8.2 DDD(领域驱动设计)落地实践

    核心战术模式:

    • 聚合根(Aggregate Root):外部访问聚合的唯一入口。如 Order 是聚合根,OrderItem 属于其内部实体,外部不能直接修改 OrderItem。
    • 值对象(Value Object):无唯一标识,不可变,如 Money、Address。
    • 领域事件(Domain Event):聚合根状态变更后发布事件(如 OrderCreatedEvent),通过 Spring 的 ApplicationEventPublisher 发布,其它服务监听并处理(解耦)。

    CQRS(命令查询职责分离):

    • Command 端:处理写操作(DDD 领域模型,强一致,事务性强)。
    • Query 端:处理读操作(直接查询 DB 或 Elasticsearch 视图,简单 SQL,不做复杂业务逻辑)。
    • 优点:读写分离,可独立优化;缺点:复杂度高,数据存在短暂不一致(需最终一致性同步)。

    Event Sourcing(事件溯源):

    • 原理:不存储聚合的当前状态,只存储一系列领域事件(Event Store)。聚合的当前状态通过重放(Replay)所有事件计算得出。
    • 优点:完美的审计日志、可回溯任意时间点状态。
    • 何时使用:金融账本、区块链、复杂业务流程审计等。
    • 何时不要用:简单 CRUD、对延迟敏感的系统(重放大量事件太慢)。

    九、云原生与可观测性(核心能力 5%)

    9.1 Docker + Kubernetes(K8s)核心要点

    • Pod:K8s 最小调度单元,一个 Pod 可包含多个容器(共享 Network Namespace)。
    • Deployment:无状态应用部署(滚动更新、回滚、副本数控制)。
    • StatefulSet:有状态应用(如 MySQL、Redis 集群),提供稳定的网络标识(pod-0、pod-1)和持久化存储(PVC)。
    • Service:服务发现与负载均衡(ClusterIP、NodePort、LoadBalancer)。
    • Ingress:七层 HTTP 路由(域名 -> Service)。
    • ConfigMap / Secret:配置与敏感信息注入(环境变量或 Volume 挂载)。
    • HPA(Horizontal Pod Autoscaler):基于 CPU/内存/自定义指标(如 QPS)自动扩缩 Pod。

    高级工程师视角:不仅要会 kubectl apply,还要理解 Pod 生命周期(Pending → Running → Succeeded/Failed)、探针(Startup/Readiness/Liveness Probe) 对发布和稳定性底线的保障。

    9.2 可观测性三大支柱

    支柱技术栈核心目的
    监控(Metrics) Prometheus + Grafana 指标采集(CPU、内存、QPS、错误率),设置告警规则(如“5分钟内错误率 > 10%”)
    日志(Logging) ELK(Elasticsearch + Logstash + Kibana) / Loki 结构化日志存储与检索,排查业务异常堆栈
    链路追踪(Tracing) Jaeger / Zipkin + OpenTelemetry 分布式调用链追踪(TraceId + SpanId),定位跨服务慢调用

    实战要求:微服务必须传递 TraceId(通过 MDC 或 ThreadLocal)并在日志、监控、链路中关联,形成 “Metrics → Logs → Traces” 的联动排查闭环。


    十、行业场景能力(跨境电商 + 制造业)

    10.1 制造业(MES/工业互联)

    • MES(制造执行系统) 需要实时采集 PLC(可编程逻辑控制器)数据。
    • 工业协议:Modbus(串口/以太网)、OPC UA(标准化工业通信)、MQTT(轻量级物联网协议,适合云边协同)。
    • 为什么不能用 HTTP? 工业现场设备资源受限(低功耗、弱网),TCP/HTTP 握手开销大;且实时性要求毫秒级(轮询周期 50ms~200ms),HTTP 延迟不可控。
    • 可靠性保障:边缘网关做本地缓存(断网续传),数据先写入 InfluxDB/TDEngine(时序数据库),再同步云端。

    10.2 跨境电商订单全流程状态机

    完整状态流转:

    创建(CREATED) → 支付中(PAYING) → 已支付(PAID) → 锁库存成功(STOCK_LOCKED) →
    待发货(WAIT_SHIP) → 清关中(CLEARING) → 已清关(CLEARED) →
    运输中(TRANSITING) → 签收(DELIVERED) → 完成(COMPLETED)
    ↘ 退款中(REFUNDING) → 已退款(REFUNDED)
    ↘ 售后中(AFTER_SALE) → 售后完成(AFTER_DONE)

    核心难点:

    • 支付与库存的最终一致性:支付成功但库存扣减失败 → 自动退款(TCC 或 MQ 事务)。
    • 跨境清关数据同步:对接海关系统(异步回调 + 轮询补偿),需设计超时重试和异常工单告警。
    • 价格与货币转换:价格中心需维护多币种汇率(BigDecimal 精确计算,禁止 float/double)。

    十一、代码能力与设计模式(核心能力贯穿始终)

    11.1 SOLID 原则实战映射

    原则微服务/代码体现
    单一职责(S) 一个 Service 类只做一种业务(如 PaymentService 不写物流逻辑)
    开闭原则(O) 使用策略模式处理不同支付渠道(微信/支付宝),新增渠道不修改老代码
    里氏替换(L) 子类扩展父类功能,不重写父类非抽象方法(避免破坏契约)
    接口隔离(I) 自定义 Feign 接口粒度要细(如 OrderReadClient 和 OrderWriteClient 分离)
    依赖倒置(D) 高层模块依赖抽象接口(如 PaymentGateway 接口),不依赖具体实现

    11.2 常用设计模式场景

    模式应用场景
    工厂模式 创建不同 MQ 连接(KafkaProducerFactory / RabbitMQFactory)
    策略模式 不同风控规则、不同运费计算逻辑
    模板方法 抽象 BaseExportService,子类实现 CSV/Excel/PDF 导出细节
    责任链模式 过滤器链(Filter)、权限校验链
    观察者模式 Spring 事件监听(ApplicationListener)
    建造者模式 复杂对象构建(Order.builder().userId().amount().build())

    11.3 日志与异常规范

    • 日志级别:ERROR(系统不可用)、WARN(可自愈异常)、INFO(关键业务节点)、DEBUG(仅在开发/压测开启)。
    • 异常分类:业务异常(BizException) 和系统异常(SystemException) 分离。全局异常处理器(@ControllerAdvice)统一返回标准化错误码(如 PAY_001),不将堆栈抛给前端。

    十二、线上问题排查闭环(★★★★★ 终极能力)

    形成标准的 PDCA 循环:定位(Discover)→ 分析(Analyze)→ 验证(Verify)→ 修复(Fix)→ 复盘(Review)。

    12.1 典型场景速查表

    故障现象第一反应工具核心排查思路
    CPU 100% top -H -p + jstack + Arthas thread 死循环(正则回溯、JSON 序列化大对象)、频繁 GC、锁竞争
    内存飙升/OOM jmap -dump + MAT / Arthas heap 内存泄漏(静态集合、ThreadLocal 未清理)、大对象直接进入老年代
    Full GC 频繁 jstat -gcutil + GC 日志 检查老年代占用率、元空间是否膨胀、是否有内存泄漏
    接口响应慢 SkyWalking/Jaeger 链路 + Arthas trace 定位慢 SQL(数据库)、外部调用超时(Feign)、锁等待
    数据库死锁 SHOW ENGINE INNODB STATUS 分析加锁顺序、间隙锁冲突,统一访问顺序或降级 RC
    Redis 慢查询 SLOWLOG GET 100 + redis-cli –bigkeys 是否存在 BigKey 或 KEYS * 命令;检查网络延迟
    Kafka 积压 kafka-consumer-groups –describe 消费者数量/处理能力不足、分区倾斜、Rebalance 风暴
    线程池满 jstack 查看 WAITING/BLOCKED 线程 核心线程数过小、队列堆积、任务执行时间过长(无超时)

    12.2 复盘文化(终极成长)

    每次故障后输出 故障报告(Incident Report),包含:

  • 时间线(Timeline):发现 → 响应 → 解决 的时间点。
  • 根因(Root Cause):5-Why 分析法深挖(如“为什么 GC?→ 因为缓存对象太大 → 为什么大?→ 未设置过期时间 → 为什么未设置?→ 规范缺失”)。
  • 改进措施(Action Items):技术改进(代码/配置) + 管理改进(发布流程/监控完善),并明确责任人与截止日期。

  • 至此,我们已经完整覆盖了你复习路线图从 Java 基础、Spring、数据库、Redis、MQ、微服务分布式、高并发架构、云原生、行业场景到代码质量与线上排查的全部内容。这份文档可以作为你博客系统化知识库的底稿,也可以作为高级工程师面试的查漏补缺清单。祝你学习顺利!

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 【Java面试】——分布式架构
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!