Spring Cloud 入门
Spring Cloud 入门
一、Spring Cloud 是什么
Spring Cloud 是一套基于 Spring Boot 的分布式系统开发工具集,用于快速构建分布式系统中的常见模式(如配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、分布式会话等)。
核心特性
| 特性 | 说明 |
|---|---|
| 服务注册与发现 | 通过 Eureka/Nacos/Consul 实现服务自动注册与发现 |
| 负载均衡 | Spring Cloud LoadBalancer / Ribbon 客户端负载均衡 |
| 远程调用 | OpenFeign 声明式 HTTP 客户端 |
| 断路器 | Resilience4j / Sentinel 实现熔断、降级、限流 |
| 网关路由 | Spring Cloud Gateway 提供 API 网关 |
| 配置中心 | Spring Cloud Config / Nacos Config 集中管理配置 |
| 消息总线 | Spring Cloud Bus 实现配置动态刷新 |
| 分布式链路追踪 | Micrometer Tracing + Zipkin 实现全链路监控 |
Spring Cloud 主要组件
┌─────────────────────────────────────────────────────┐
│ Spring Cloud │
├──────────────┬──────────────────┬──────────────────┤
│ 服务治理 │ 服务调用 │ 服务网关 │
│ Nacos │ OpenFeign │ Gateway │
│ Eureka │ LoadBalancer │ Zuul │
├──────────────┼──────────────────┼──────────────────┤
│ 配置管理 │ 服务保护 │ 链路追踪 │
│ Nacos Config│ Sentinel │ Zipkin │
│ Config │ Resilience4j │ Micrometer │
├──────────────┴──────────────────┴──────────────────┤
│ 消息驱动: Stream / Bus │
└─────────────────────────────────────────────────────┘
版本对应关系
| Spring Cloud | Spring Boot | Spring Cloud Alibaba |
|---|---|---|
| 2022.0.x (Kilburn) | 3.0.x | 2022.0.x |
| 2023.0.x (Leyton) | 3.2.x | 2023.0.x |
| 2024.0.x | 3.4.x | 2024.0.x |
二、Spring Cloud 环境搭建
2.1 基础环境要求
| 软件 | 版本要求 |
|---|---|
| JDK | 17+ (Spring Boot 3.x 要求) |
| Maven | 3.6+ |
| MySQL | 8.0+ |
| Nacos | 2.4+ (服务注册与配置中心) |
| IDEA | 2023+ (推荐) |
2.2 安装 Nacos
# 下载 Nacos
wget https://github.com/alibaba/nacos/releases/download/2.4.3/nacos-server-2.4.3.zip
# 解压
unzip nacos-server-2.4.3.zip -d /opt/nacos
# 单机模式启动
cd /opt/nacos/bin
bash startup.sh -m standalone
# 访问 http://localhost:8848/nacos 默认账号密码: nacos/nacos
2.3 Maven 项目父 POM 配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.5</version>
</parent>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2024.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2024.0.1.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud BOM -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud Alibaba BOM -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
三、Demo 代码(精简版)
3.1 项目结构
springcloud-demo/
├── pom.xml # 父 POM
├── common/ # 公共模块
├── gateway/ # API 网关
├── user-service/ # 用户服务
└── order-service/ # 订单服务
3.2 核心依赖伪代码
<!-- 各服务模块通用依赖 -->
<dependencies>
<!-- Web 支持 -->
<dependency>org.springframework.boot:spring-boot-starter-web</dependency>
<!-- Nacos 服务注册发现 -->
<dependency>com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery</dependency>
<!-- Nacos 配置中心(可选) -->
<dependency>com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config</dependency>
<!-- LoadBalancer(负载均衡) -->
<dependency>org.springframework.cloud:spring-cloud-starter-loadbalancer</dependency>
</dependencies>
3.3 服务配置伪代码
application.yml:
server:
port: 8081 # 服务端口
spring:
application:
name: user-service # 服务名称(用于注册发现)
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos 地址
datasource:
url: jdbc:mysql://localhost:3306/demo
username: root
password: root
3.4 启动类伪代码
@SpringBootApplication
@EnableDiscoveryClient // 启用服务注册发现
@MapperScan("com.example.mapper") // 扫描 Mapper(如有数据库操作)
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
3.5 Controller 伪代码
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/{id}")
public Result<User> getById(@PathVariable Long id) {
return Result.ok(userService.getById(id));
}
@PostMapping
public Result<User> create(@RequestBody User user) {
return Result.ok(userService.create(user));
}
// ... 其他 CRUD 方法
}
3.6 OpenFeign 远程调用伪代码
order-service 调用 user-service:
// 1. 启动类添加注解
@SpringBootApplication
@EnableFeignClients // 启用 Feign 客户端
public class OrderServiceApplication { }
// 2. 定义 Feign 接口
@FeignClient(name = "user-service") // 指定目标服务名
public interface UserFeignClient {
@GetMapping("/users/{id}")
Result<Map<String, Object>> getUserById(@PathVariable("id") Long id);
}
// 3. 在 Controller/Service 中注入使用
@RestController
@RequestMapping("/orders")
@RequiredArgsConstructor
public class OrderController {
private final UserFeignClient userFeignClient;
@PostMapping
public Result<Order> createOrder(@RequestBody OrderRequest req) {
// 通过 Feign 调用用户服务
Result<Map<String, Object>> userResult = userFeignClient.getUserById(req.getUserId());
if (userResult.getCode() != 200) {
return Result.fail(400, "User not found");
}
// 创建订单逻辑...
return Result.ok(order);
}
}
3.7 Gateway 网关伪代码
pom.xml 依赖:
<dependencies>
<dependency>org.springframework.cloud:spring-cloud-starter-gateway</dependency>
<dependency>com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery</dependency>
</dependencies>
application.yml 路由配置:
server:
port: 8080
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true # 启用服务发现路由
lower-case-service-id: true
routes:
- id: user-service
uri: lb://user-service # lb:// 表示负载均衡
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1 # 去掉前缀 /api
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- StripPrefix=1
四、编译方法
4.1 Maven 编译
# 进入项目根目录
cd springcloud-demo
# 清理并编译整个项目(跳过测试)
mvn clean package -DskipTests
# 仅编译指定模块及其依赖
mvn clean package -pl user-service -am -DskipTests
常用参数说明:
-DskipTests: 跳过单元测试-pl <module>: 指定编译模块-am: 同时编译依赖模块-P<profile>: 激活特定 profile(如 dev/test/prod)
4.2 本地运行
# 方式1: Maven 插件运行
mvn spring-boot:run -pl user-service
# 方式2: 直接运行 jar
java -jar user-service/target/user-service-1.0.0.jar
# 指定环境
java -jar user-service-1.0.0.jar --spring.profiles.active=dev
4.3 Docker 镜像构建
Dockerfile:
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8081
ENV JAVA_OPTS="-Xms256m -Xmx512m"
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
# 构建镜像
docker build -t demo/user-service:1.0.0 -f Dockerfile user-service/
五、部署方法
5.1 Docker Compose 部署
docker-compose.yml 核心结构:
version: '3.8'
services:
nacos:
image: nacos/nacos-server:v2.4.3
environment:
- MODE=standalone
ports:
- "8848:8848"
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: demo
ports:
- "3306:3306"
user-service:
build: ./user-service
ports:
- "8081:8081"
environment:
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER-ADDR=nacos:8848
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/demo
depends_on:
- nacos
- mysql
order-service:
build: ./order-service
ports:
- "8082:8082"
depends_on:
- nacos
- user-service
gateway:
build: ./gateway
ports:
- "8080:8080"
depends_on:
- nacos
- user-service
- order-service
# 一键启动
docker compose up -d
# 查看状态
docker compose ps
# 查看日志
docker compose logs -f user-service
# 停止
docker compose down
5.2 Kubernetes 部署要点
Deployment 核心配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 2 # 副本数
selector:
matchLabels:
app: user-service
template:
spec:
containers:
- name: user-service
image: demo/user-service:1.0.0
ports:
- containerPort: 8081
env:
- name: SPRING_CLOUD_NACOS_DISCOVERY_SERVER-ADDR
value: nacos:8848
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe: # 存活探针
httpGet:
path: /actuator/health
port: 8081
readinessProbe: # 就绪探针
httpGet:
path: /actuator/health
port: 8081
# 应用配置
kubectl apply -f deployment.yaml
# 查看状态
kubectl get pods -l app=user-service
# 扩缩容
kubectl scale deployment/user-service --replicas=3
# 回滚
kubectl rollout undo deployment/user-service
5.3 多环境配置
resources/
├── application.yml # 公共配置
├── application-dev.yml # 开发环境
├── application-test.yml # 测试环境
└── application-prod.yml # 生产环境
# 激活指定环境
java -jar app.jar --spring.profiles.active=prod
# 或通过环境变量
export SPRING_PROFILES_ACTIVE=prod
六、接口测试
# 通过网关访问(统一入口 :8080)
# 创建用户
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"username":"zhangsan","email":"zs@example.com"}'
# 查询用户
curl http://localhost:8080/api/users/1
# 创建订单(内部通过 Feign 调用 user-service)
curl -X POST http://localhost:8080/api/orders \
-H "Content-Type: application/json" \
-d '{"userId":1,"product":"iPhone","amount":6999}'
七、常见问题
| 问题 | 解决方案 |
|---|---|
| Nacos 连接失败 | 检查 Nacos 是否启动、防火墙开放 8848/9848 端口 |
| Feign 调用 404 | 确认路径与被调用服务一致 |
| 服务注册后不可见 | 检查 namespace 是否一致 |
| Gateway 路由 503 | 确认目标服务已注册、discovery.locator.enabled=true |
| 数据库连接失败 | 检查 URL、驱动类名 com.mysql.cj.jdbc.Driver |
八、参考文档
- Spring Cloud: https://spring.io/projects/spring-cloud
- Spring Cloud Alibaba: https://sca.aliyun.com/
- Nacos: https://nacos.io/docs/latest/
- Spring Boot: https://docs.spring.io/spring-boot/docs/current/reference/