本文目录导读:

- 项目架构概览
- 父工程 pom.xml
- common-api 模块
- user-service(用户服务)
- order-service(订单服务)
- gateway-service(网关服务)
- Nacos 配置中心配置
- 测试流程
- Sentinel 流量控制配置
- 扩展建议
下面是一个完整的 Spring Cloud Alibaba 微服务实战案例,涵盖服务注册与发现(Nacos)、配置中心(Nacos Config)、远程调用(OpenFeign)、流量控制(Sentinel)和网关(Gateway)。
项目架构概览
spring-cloud-alibaba-demo
├── pom.xml (父工程)
├── user-service (用户服务,端口8081)
├── order-service (订单服务,端口8082)
├── gateway-service (网关服务,端口8080)
└── common-api (公共API模块)
技术栈:Spring Boot 2.7 + Spring Cloud Alibaba 2021.0.5.0 + Nacos 2.2 + Sentinel 1.8.6
父工程 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>spring-cloud-alibaba-demo</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>common-api</module>
<module>user-service</module>
<module>order-service</module>
<module>gateway-service</module>
</modules>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud -->
<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 -->
<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>
</project>
common-api 模块
定义公共实体和DTO,供各服务复用。
User.java:
package com.example.common.entity;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
public class User implements Serializable {
private Long id;
private String username;
private String email;
}
Order.java:
package com.example.common.entity;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class Order implements Serializable {
private Long id;
private Long userId;
private String productName;
private BigDecimal amount;
private LocalDateTime createTime;
}
Result.java(统一响应体):
package com.example.common.result;
import lombok.Data;
import java.io.Serializable;
@Data
public class Result<T> implements Serializable {
private Integer code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("success");
result.setData(data);
return result;
}
public static <T> Result<T> error(Integer code, String message) {
Result<T> result = new Result<>();
result.setCode(code);
result.setMessage(message);
return result;
}
}
user-service(用户服务)
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Nacos 注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Nacos 配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 公共模块 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>common-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
bootstrap.yml
spring:
application:
name: user-service
cloud:
nacos:
server-addr: localhost:8848
config:
file-extension: yaml
namespace: public
group: DEFAULT_GROUP
discovery:
namespace: public
group: DEFAULT_GROUP
application.yml
server: port: 8081 # 从 Nacos 配置中心读取的配置 user: default-role: USER
启动类和控制器
UserServiceApplication.java:
package com.example.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
UserController.java:
package com.example.user.controller;
import com.example.common.entity.User;
import com.example.common.result.Result;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/user")
public class UserController {
// 模拟数据库
private static final Map<Long, User> USER_DB = new HashMap<>() {{
put(1L, new User(1L, "张三", "zhangsan@example.com"));
put(2L, new User(2L, "李四", "lisi@example.com"));
}};
@GetMapping("/{id}")
public Result<User> getUserById(@PathVariable Long id) {
return Result.success(USER_DB.get(id));
}
@GetMapping("/list")
public Result<Map<Long, User>> listUsers() {
return Result.success(USER_DB);
}
}
order-service(订单服务)
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Nacos 注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Nacos 配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- OpenFeign 远程调用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Sentinel 流量控制 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 公共模块 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>common-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
bootstrap.yml
spring:
application:
name: order-service
cloud:
nacos:
server-addr: localhost:8848
config:
file-extension: yaml
discovery:
server-addr: localhost:8848
sentinel:
transport:
dashboard: localhost:8080 # Sentinel 控制台地址
port: 8719
application.yml
server: port: 8082
Feign 客户端
UserFeignClient.java:
package com.example.order.feign;
import com.example.common.entity.User;
import com.example.common.result.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name = "user-service", fallback = UserFeignFallback.class)
public interface UserFeignClient {
@GetMapping("/api/user/{id}")
Result<User> getUserById(@PathVariable Long id);
}
UserFeignFallback.java(熔断降级):
package com.example.order.feign;
import com.example.common.entity.User;
import com.example.common.result.Result;
import org.springframework.stereotype.Component;
@Component
public class UserFeignFallback implements UserFeignClient {
@Override
public Result<User> getUserById(Long id) {
return Result.error(500, "服务降级:用户服务不可用");
}
}
启动类和控制器
OrderServiceApplication.java:
package com.example.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
OrderController.java:
package com.example.order.controller;
import com.example.common.entity.Order;
import com.example.common.entity.User;
import com.example.common.result.Result;
import com.example.order.feign.UserFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/order")
public class OrderController {
@Autowired
private UserFeignClient userFeignClient;
private static final Map<Long, Order> ORDER_DB = new HashMap<>() {{
put(1L, new Order(1L, 1L, "iPhone 15", new BigDecimal("5999.00"), LocalDateTime.now()));
put(2L, new Order(2L, 2L, "MacBook Pro", new BigDecimal("12999.00"), LocalDateTime.now()));
}};
@GetMapping("/{id}")
public Result<Map<String, Object>> getOrderWithUser(@PathVariable Long id) {
Order order = ORDER_DB.get(id);
if (order == null) {
return Result.error(404, "订单不存在");
}
// 通过 Feign 调用用户服务
Result<User> userResult = userFeignClient.getUserById(order.getUserId());
return Result.success(Map.of(
"order", order,
"user", userResult.getData()
));
}
@GetMapping("/list")
public Result<Map<Long, Order>> listOrders() {
return Result.success(ORDER_DB);
}
}
gateway-service(网关服务)
pom.xml
<dependencies>
<!-- 网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Nacos 注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Nacos 配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
application.yml
server:
port: 8080
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true # 启用服务发现路由
lower-case-service-id: true
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
- id: order-service-route
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
启动类
GatewayServiceApplication.java:
package com.example.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
}
Nacos 配置中心配置
在 Nacos 控制台创建配置文件:
Data ID: order-service.yaml
# order-service 的动态配置 order: max-amount: 10000 discount: 0.9
Data ID: user-service.yaml
# user-service 的动态配置 user: default-role: ADMIN
测试流程
启动基础设施
# 启动 Nacos cd nacos/bin ./startup.sh -m standalone # 启动 Sentinel 控制台(可选) java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8888 -jar sentinel-dashboard-1.8.6.jar
启动服务
# 依次启动 mvn spring-boot:run -pl user-service mvn spring-boot:run -pl order-service mvn spring-boot:run -pl gateway-service
测试接口
通过网关调用订单服务:
curl http://localhost:8080/order/api/order/1
直接调用订单服务:
curl http://localhost:8082/api/order/1
通过网关调用用户服务:
curl http://localhost:8080/user/api/user/1
测试降级(停止 user-service 后再次调用):
curl http://localhost:8082/api/order/1
# 预期返回:{"code":500,"message":"服务降级:用户服务不可用"}
Sentinel 流量控制配置
在 Sentinel 控制台(localhost:8888)为 order-service 添加流控规则:
资源名: /api/order/list
- 阈值类型: QPS
- 单机阈值: 1
- 流控效果: 快速失败
扩展建议
- 添加分布式事务:集成 Seata 处理跨服务事务
- 链路追踪:集成 SkyWalking 或 Zipkin
- 消息队列:使用 RocketMQ 实现异步解耦
- 服务监控:集成 Prometheus + Grafana
- 安全认证:接入 Spring Security OAuth2 或 JWT
这个案例涵盖了 Spring Cloud Alibaba 的核心组件,可以直接运行学习,如有任何问题,欢迎继续交流!