SpringCloud微服务实战
# SpringCloud微服务实战
# 前言
随着业务规模的不断扩大,单体应用逐渐暴露出扩展性差、维护成本高等问题。微服务架构作为一种解决方案,受到了越来越多企业的青睐。本文将结合实际项目经验,详细介绍SpringCloud微服务架构的实践。
# 微服务架构概述
微服务是一种将单体应用拆分为多个小型服务的架构风格,每个服务运行在自己的进程中,服务之间通过轻量级通信机制(通常是HTTP API)进行通信。
# 微服务的优势
- 技术异构性:不同服务可以使用不同的技术栈
- 弹性:单个服务故障不会导致整个系统崩溃
- 可扩展性:可以针对不同服务进行独立扩展
- 易于部署:服务可以独立部署,不影响其他服务
- 组织对齐:小团队负责小服务,提高开发效率
# 微服务的挑战
- 分布式系统复杂性:需要处理网络延迟、容错、消息传递等问题
- 服务间通信:需要设计高效的通信机制
- 数据一致性:跨服务事务难以保证
- 测试复杂度增加:需要测试服务间交互
- 运维复杂度增加:需要管理多个服务实例
# SpringCloud技术栈
SpringCloud是构建微服务架构的一站式解决方案,提供了一系列工具和框架:

# 核心组件
Spring Cloud Netflix
- Eureka:服务注册与发现
- Hystrix:断路器
- Zuul:API网关
- Ribbon:客户端负载均衡
Spring Cloud Alibaba
- Nacos:服务注册与配置中心
- Sentinel:流量控制与熔断降级
- Seata:分布式事务
其他组件
- Spring Cloud Gateway:新一代API网关
- Spring Cloud Config:配置中心
- Spring Cloud Sleuth & Zipkin:分布式追踪
- Spring Cloud Stream:消息驱动
# 项目实战:电商微服务系统
下面以一个电商系统为例,介绍如何构建微服务架构。
# 系统架构

# 服务划分
- 用户服务(user-service):用户注册、登录、信息管理
- 商品服务(product-service):商品管理、库存管理
- 订单服务(order-service):订单创建、支付、物流
- 支付服务(payment-service):支付渠道管理、支付处理
- 评价服务(review-service):商品评价、用户评分
- 搜索服务(search-service):商品搜索、推荐
- API网关(gateway):请求路由、认证授权、限流熔断
# 技术选型
- 注册中心:Nacos
- 配置中心:Nacos Config
- 网关:Spring Cloud Gateway
- 服务调用:OpenFeign
- 负载均衡:Spring Cloud LoadBalancer
- 熔断降级:Sentinel
- 分布式事务:Seata
- 分布式追踪:Sleuth + Zipkin
- 消息队列:RocketMQ
- 数据库:MySQL + Redis
# 项目搭建
# 1. 创建父工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
</parent>
<properties>
<spring-cloud.version>2021.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 2. 配置Nacos注册中心
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: dev
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
namespace: dev
group: DEFAULT_GROUP
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 3. 实现用户服务
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserById(id));
}
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(userService.createUser(user));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 4. 服务间调用(OpenFeign)
// 在订单服务中调用用户服务
@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserServiceClient {
@GetMapping("/users/{id}")
User getUserById(@PathVariable("id") Long id);
}
// 实现降级处理
@Component
public class UserServiceFallback implements UserServiceClient {
@Override
public User getUserById(Long id) {
// 返回默认用户或空对象
return User.builder().id(id).username("unknown").build();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 5. 配置网关路由
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
- id: product-service
uri: lb://product-service
predicates:
- Path=/api/products/**
filters:
- StripPrefix=1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 6. 分布式事务处理
// 在订单服务中创建订单并扣减库存
@GlobalTransactional
public OrderDTO createOrder(OrderCreateRequest request) {
// 1. 创建订单
Order order = orderRepository.save(Order.builder()
.userId(request.getUserId())
.totalAmount(request.getTotalAmount())
.status(OrderStatus.CREATED)
.build());
// 2. 扣减库存(远程调用)
for (OrderItem item : request.getItems()) {
productServiceClient.reduceStock(item.getProductId(), item.getQuantity());
}
// 3. 创建支付记录(远程调用)
paymentServiceClient.createPayment(order.getId(), request.getTotalAmount());
return convertToDTO(order);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 7. 分布式追踪
spring:
sleuth:
sampler:
probability: 1.0 # 采样率,1.0表示全部采样
zipkin:
base-url: http://localhost:9411
1
2
3
4
5
6
2
3
4
5
6
# 性能优化与最佳实践
# 1. 服务拆分原则
- 单一职责:每个服务只负责一个业务功能
- 高内聚低耦合:服务内部紧密关联,服务间松散耦合
- 领域驱动设计:按业务领域划分服务边界
# 2. API设计
- RESTful风格:使用HTTP动词表达操作意图
- 版本控制:在URL中包含API版本
- 统一响应格式:使用一致的响应结构
- 错误处理:明确的错误码和错误信息
# 3. 缓存策略
- 本地缓存:使用Caffeine缓存热点数据
- 分布式缓存:使用Redis缓存共享数据
- 多级缓存:本地缓存 + 分布式缓存 + 数据库
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductRepository productRepository;
@Autowired
private StringRedisTemplate redisTemplate;
private LoadingCache<Long, Product> localCache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build(this::getProductFromDb);
@Override
public Product getProductById(Long id) {
// 先查本地缓存
Product product = localCache.get(id);
if (product != null) {
return product;
}
// 查Redis缓存
String key = "product:" + id;
String json = redisTemplate.opsForValue().get(key);
if (StringUtils.hasText(json)) {
product = JSON.parseObject(json, Product.class);
// 更新本地缓存
localCache.put(id, product);
return product;
}
// 查数据库
product = getProductFromDb(id);
if (product != null) {
// 更新Redis缓存
redisTemplate.opsForValue().set(key, JSON.toJSONString(product), 30, TimeUnit.MINUTES);
// 更新本地缓存
localCache.put(id, product);
}
return product;
}
private Product getProductFromDb(Long id) {
return productRepository.findById(id).orElse(null);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 4. 异步处理
使用消息队列处理异步任务:
// 发送消息
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Override
public void createOrder(OrderCreateRequest request) {
// 创建订单
Order order = createOrderInDb(request);
// 发送消息,异步处理库存和支付
OrderMessage message = new OrderMessage(order.getId(), request.getItems());
rocketMQTemplate.convertAndSend("order-topic", message);
return convertToDTO(order);
}
}
// 消费消息
@Component
@RocketMQMessageListener(
topic = "order-topic",
consumerGroup = "order-consumer-group"
)
public class OrderMessageListener implements RocketMQListener<OrderMessage> {
@Autowired
private ProductServiceClient productServiceClient;
@Autowired
private PaymentServiceClient paymentServiceClient;
@Override
public void onMessage(OrderMessage message) {
// 扣减库存
for (OrderItem item : message.getItems()) {
productServiceClient.reduceStock(item.getProductId(), item.getQuantity());
}
// 创建支付记录
paymentServiceClient.createPayment(message.getOrderId(), message.getTotalAmount());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 5. 限流熔断
使用Sentinel实现限流和熔断:
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/{id}")
@SentinelResource(
value = "getProductById",
blockHandler = "getProductByIdBlockHandler",
fallback = "getProductByIdFallback"
)
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
return ResponseEntity.ok(productService.getProductById(id));
}
// 限流处理
public ResponseEntity<Product> getProductByIdBlockHandler(Long id, BlockException ex) {
log.warn("Request blocked: {}", ex.getMessage());
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS)
.body(null);
}
// 熔断降级处理
public ResponseEntity<Product> getProductByIdFallback(Long id, Throwable ex) {
log.error("Service degraded: {}", ex.getMessage());
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(null);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 微服务监控与运维
# 监控系统
- Prometheus + Grafana:收集和可视化监控指标
- Spring Boot Admin:监控Spring Boot应用
- Skywalking:分布式追踪和性能监控
# 日志收集
- ELK Stack:Elasticsearch + Logstash + Kibana
- 日志格式统一:包含traceId、spanId等信息
logging:
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId},%X{spanId}] %-5level %logger{36} - %msg%n"
1
2
3
2
3
# CI/CD流水线
- Jenkins/GitLab CI:自动化构建、测试、部署
- Docker + Kubernetes:容器化部署和编排
# 灰度发布
使用Spring Cloud Gateway实现灰度发布:
spring:
cloud:
gateway:
routes:
- id: product-service-v1
uri: lb://product-service-v1
predicates:
- Path=/api/products/**
- Weight=product-service, 80
filters:
- StripPrefix=1
- id: product-service-v2
uri: lb://product-service-v2
predicates:
- Path=/api/products/**
- Weight=product-service, 20
filters:
- StripPrefix=1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 案例分析:秒杀系统架构
# 挑战
- 瞬时高并发:短时间内大量请求
- 库存超卖:并发导致的数据一致性问题
- 恶意请求:防止刷单和机器人攻击
# 解决方案
流量控制:
- 前端限流(按钮置灰、倒计时)
- 网关限流(令牌桶算法)
- 服务端限流(Sentinel)
库存处理:
- Redis预减库存
- 数据库乐观锁
- 消息队列异步处理订单
防刷策略:
- 验证码
- 用户行为分析
- 黑名单机制
系统架构:
用户请求 -> CDN -> 网关(限流) -> 秒杀服务(Redis校验+预减库存) ->
消息队列 -> 订单服务(异步创建订单) -> 库存服务(最终扣减库存)
1
2
2
# 核心代码实现
@Service
public class SeckillServiceImpl implements SeckillService {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Override
@SentinelResource(value = "seckill", blockHandler = "seckillBlockHandler")
public boolean doSeckill(Long userId, Long productId) {
// 1. 判断是否重复下单
String orderKey = "seckill:order:" + productId + ":" + userId;
Boolean hasOrdered = redisTemplate.hasKey(orderKey);
if (Boolean.TRUE.equals(hasOrdered)) {
return false;
}
// 2. 预减库存
String stockKey = "seckill:stock:" + productId;
Long stock = redisTemplate.opsForValue().decrement(stockKey);
if (stock == null || stock < 0) {
// 库存不足,恢复库存
if (stock != null && stock < 0) {
redisTemplate.opsForValue().increment(stockKey);
}
return false;
}
// 3. 记录用户下单
redisTemplate.opsForValue().set(orderKey, "1", 24, TimeUnit.HOURS);
// 4. 发送消息,异步创建订单
SeckillMessage message = new SeckillMessage(userId, productId);
rocketMQTemplate.convertAndSend("seckill-topic", message);
return true;
}
// 限流处理
public boolean seckillBlockHandler(Long userId, Long productId, BlockException ex) {
log.warn("Seckill request blocked: {}", ex.getMessage());
return false;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 总结与展望
SpringCloud微服务架构为企业提供了灵活、可扩展的解决方案,但同时也带来了分布式系统的复杂性。在实践中,需要根据业务特点和团队能力选择合适的技术栈,并遵循微服务最佳实践。
随着云原生技术的发展,Kubernetes、Service Mesh等技术正在改变微服务的实现方式。未来,微服务将更加轻量化、标准化,并与云平台深度融合。
希望本文能为你的微服务实践提供参考和帮助。
上次更新: 2025/07/01, 01:17:09