微服务架构是将应用拆分为一组小型、独立部署的服务,每个服务运行在自己的进程中,通过轻量级机制通信。
| 对比项 | 单体架构 | 微服务架构 |
|---|
| 部署 | 整体部署 | 独立部署 |
| 技术栈 | 统一 | 可异构 |
| 扩展 | 整体扩展 | 按需扩展 |
| 故障隔离 | 差 | 好 |
| 开发效率 | 初期快 | 初期慢,后期快 |
| 运维复杂度 | 低 | 高 |
| 组件 | 作用 | 常用实现 |
|---|
| 服务注册发现 | 服务地址管理 | Nacos、Consul、Eureka |
| 配置中心 | 统一配置管理 | Nacos、Apollo、Spring Cloud Config |
| API 网关 | 统一入口、路由 | Spring Cloud Gateway、Kong |
| 负载均衡 | 流量分发 | Spring Cloud LoadBalancer |
| 熔断降级 | 故障隔离 | Sentinel、Resilience4j |
| 链路追踪 | 调用链监控 | SkyWalking、Zipkin、Jaeger |
| 消息队列 | 异步解耦 | RocketMQ、Kafka |
| 特性 | Nacos | Eureka |
|---|
| CAP | CP + AP 可切换 | AP |
| 健康检查 | TCP/HTTP/MySQL | 心跳 |
| 配置管理 | 支持 | 不支持 |
| 雪崩保护 | 支持 | 支持 |
| 访问协议 | HTTP/DNS/gRPC | HTTP |
| 维护状态 | 活跃 | 停止维护 |
# Nacos 配置
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: dev
config:
server-addr: localhost:8848
file-extension: yaml
| 模式 | 说明 | 示例 |
|---|
| 客户端发现 | 客户端查询注册中心,自己负载均衡 | Eureka + Ribbon |
| 服务端发现 | 通过负载均衡器路由,客户端无感知 | Kubernetes Service |
- Route(路由):网关的基本构建块,包含 ID、目标 URI、断言和过滤器
- Predicate(断言):匹配请求的条件(路径、Header、参数等)
- Filter(过滤器):修改请求和响应
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- AddRequestHeader=X-Request-Id, ${random.uuid}
@Configuration
public class RateLimiterConfig {
@Bean
public KeyResolver userKeyResolver() {
// 基于用户 ID 限流
return exchange -> Mono.just(
exchange.getRequest().getHeaders().getFirst("X-User-Id")
);
}
}
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 每秒10个令牌
redis-rate-limiter.burstCapacity: 20 # 桶容量20
key-resolver: "#{@userKeyResolver}"
| 概念 | 触发条件 | 目的 |
|---|
| 熔断 | 下游服务故障 | 快速失败,保护系统 |
| 降级 | 资源不足/非核心功能 | 保证核心功能可用 |
| 限流 | 流量超过阈值 | 保护系统不被压垮 |
// 定义资源
@SentinelResource(
value = "getUser",
blockHandler = "getUserBlockHandler",
fallback = "getUserFallback"
)
public User getUser(Long id) {
return userService.getById(id);
}
// 限流/熔断处理
public User getUserBlockHandler(Long id, BlockException ex) {
return new User(-1L, "限流用户");
}
// 异常降级处理
public User getUserFallback(Long id, Throwable ex) {
return new User(-1L, "降级用户");
}
Sentinel 规则类型:
| 规则 | 说明 |
|---|
| 流控规则 | QPS/线程数限流 |
| 熔断规则 | 慢调用/异常比例/异常数 |
| 热点规则 | 热点参数限流 |
| 系统规则 | 系统自适应保护 |
| 授权规则 | 黑白名单 |
| 方案 | 一致性 | 性能 | 适用场景 |
|---|
| 2PC/XA | 强一致 | 低 | 传统数据库 |
| TCC | 最终一致 | 中 | 资金交易 |
| Saga | 最终一致 | 高 | 长事务 |
| 本地消息表 | 最终一致 | 高 | 异步场景 |
| Seata AT | 最终一致 | 中 | 通用场景 |
@GlobalTransactional
public void createOrder(OrderDTO order) {
// 扣减库存
stockService.deduct(order.getProductId(), order.getCount());
// 创建订单
orderService.create(order);
// 扣减余额
accountService.deduct(order.getUserId(), order.getAmount());
}
// 定义 Feign 客户端
@FeignClient(name = "user-service", fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping("/users/{id}")
User getById(@PathVariable Long id);
@PostMapping("/users")
User create(@RequestBody User user);
}
// 降级实现
@Component
public class UserClientFallback implements UserClient {
@Override
public User getById(Long id) {
return new User(-1L, "降级用户");
}
}
OpenFeign 原理:
- 扫描
@FeignClient 注解,生成代理对象 - 解析方法注解,构建 HTTP 请求模板
- 通过负载均衡器选择服务实例
- 发送 HTTP 请求,解析响应
| 特性 | REST | gRPC |
|---|
| 协议 | HTTP/1.1 | HTTP/2 |
| 数据格式 | JSON/XML | Protobuf |
| 性能 | 一般 | 高 |
| 流式传输 | 不支持 | 支持 |
| 代码生成 | 可选 | 必须 |
| 浏览器支持 | 好 | 需要代理 |
核心概念:
- Trace:一次完整的请求链路
- Span:一次服务调用
- TraceId:全局唯一,贯穿整个调用链
- SpanId:当前调用的唯一标识
- ParentSpanId:父调用的 SpanId
# Spring Boot 3.x + Micrometer Tracing
management:
tracing:
sampling:
probability: 1.0 # 采样率
zipkin:
tracing:
endpoint: http://localhost:9411/api/v2/spans
| 变化 | 说明 |
|---|
| 基于 Spring Boot 3.x | 要求 Java 17+ |
| Jakarta EE | javax.* → jakarta.* |
| 移除 Netflix 组件 | Ribbon、Hystrix、Zuul |
| 新负载均衡 | Spring Cloud LoadBalancer |
| 新熔断器 | Resilience4j |
| 新网关 | Spring Cloud Gateway |
| 观测性 | Micrometer Tracing |
// Spring Boot 3.x 包名变化
// 旧:javax.servlet.http.HttpServletRequest
// 新:jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletRequest;
微服务架构面试重点:
- 微服务核心组件和作用
- 服务注册发现原理
- 网关的路由和限流
- 熔断降级的区别和实现
- 分布式事务解决方案
- 链路追踪原理
- Spring Cloud 新版本变化
高频面试题
- 微服务架构的优缺点?
- 如何保证微服务的高可用?
- 分布式事务如何解决?
- 服务雪崩如何预防?
- 如何设计一个网关?