单体应用拆成微服务,听起来很高大上,但落地的时候一堆问题:服务怎么注册?配置怎么管?网关怎么搭?服务间怎么调用?出了问题怎么追踪?
Spring Cloud就是来解决这些问题的。今天把五大核心组件讲清楚。
微服务架构全景
┌─────────────┐
│ API网关 │ ← Spring Cloud Gateway
└──────┬──────┘
│
┌────────────┼────────────┐
↓ ↓ ↓
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户服务 │ │ 订单服务 │ │ 商品服务 │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
└─────────────┼─────────────┘
↓
┌─────────────┐
│ 注册中心 │ ← Nacos / Eureka
└─────────────┘
┌─────────────┐
│ 配置中心 │ ← Nacos Config
└─────────────┘
┌─────────────┐
│ 链路追踪 │ ← Sleuth + Zipkin
└─────────────┘
组件一:服务注册与发现(Nacos/Eureka)
每个微服务启动时把自己的地址注册到注册中心,调用方从注册中心获取可用实例列表。
# application.yml(Nacos)
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: dev
application:
name: user-service
// 调用方通过服务名访问
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/order/{userId}")
public Order getOrder(@PathVariable Long userId) {
// "user-service" 会被自动解析为实际地址
User user = restTemplate.getForObject(
"http://user-service/user/" + userId, User.class);
return new Order(user);
}
}
组件二:配置中心(Nacos Config)
所有微服务的配置文件集中管理,修改后自动刷新,不用重启。
# bootstrap.yml
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
shared-configs:
- data-id: common.yaml
refresh: true
在Nacos控制台统一管理配置,支持多环境(dev/test/prod)、灰度发布、配置回滚。
组件三:API网关(Spring Cloud Gateway)
所有外部请求的统一入口,负责路由转发、鉴权、限流。
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service # lb://表示负载均衡
predicates:
- Path=/api/user/**
filters:
- StripPrefix=2 # 去掉/api/user前缀
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/order/**
自定义全局过滤器(比如统一鉴权):
@Component
public class AuthFilter 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 -1; // 优先级最高
}
}
组件四:服务调用(OpenFeign)
服务间的HTTP调用,用声明式接口的方式,像调本地方法一样调远程服务。
// 定义Feign客户端
@FeignClient(name = "user-service")
public interface UserClient {
@GetMapping("/user/{id}")
User getUser(@PathVariable("id") Long id);
@PostMapping("/user/list")
List<User> getUsers(@RequestBody List<Long> ids);
}
// 使用
@Service
public class OrderService {
@Autowired
private UserClient userClient;
public Order createOrder(Long userId, Long productId) {
User user = userClient.getUser(userId); // 像调本地方法一样
// ...
}
}
组件五:链路追踪(Sleuth + Zipkin)
微服务调用链很长,出了问题怎么定位是哪个服务慢?
请求 → 网关(5ms) → 订单服务(10ms) → 用户服务(50ms) → 数据库(200ms)
↑ 原来是这里慢!
# application.yml
spring:
zipkin:
base-url: http://zipkin-server:9411
sleuth:
sampler:
probability: 1.0 # 100%采样率(生产环境调低)
Zipkin界面可以可视化整个调用链,每个节点的耗时一目了然。
五大组件速查
| 组件 | 解决的问题 | 主流实现 |
|---|---|---|
| 注册中心 | 服务发现、健康检查 | Nacos、Eureka |
| 配置中心 | 集中管理配置 | Nacos Config、Apollo |
| API网关 | 路由、鉴权、限流 | Spring Cloud Gateway |
| 服务调用 | 声明式HTTP调用 | OpenFeign |
| 链路追踪 | 调用链可视化 | Sleuth + Zipkin |
Spring Cloud的组件很多,但核心就是这五个。理解了每个组件解决什么问题,架构设计就有了方向。
如果是新项目,推荐用Spring Cloud Alibaba(Nacos + Sentinel + Seata),比Netflix OSS更活跃。
你们项目用的什么微服务方案?