成神之路的博客 成神之路的博客
首页
Java进阶
常用框架
架构设计
AI探索
Python
大数据
工具资源
关于博主
GitHub (opens new window)
首页
Java进阶
常用框架
架构设计
AI探索
Python
大数据
工具资源
关于博主
GitHub (opens new window)
  • Spring全家桶

  • 微服务框架

    • SpringCloud微服务实战
      • 前言
      • 微服务架构概述
        • 微服务的优势
        • 微服务的挑战
      • SpringCloud技术栈
        • 核心组件
      • 项目实战:电商微服务系统
        • 系统架构
        • 服务划分
        • 技术选型
        • 项目搭建
        • 1. 创建父工程
        • 2. 配置Nacos注册中心
        • 3. 实现用户服务
        • 4. 服务间调用(OpenFeign)
        • 5. 配置网关路由
        • 6. 分布式事务处理
        • 7. 分布式追踪
        • 性能优化与最佳实践
        • 1. 服务拆分原则
        • 2. API设计
        • 3. 缓存策略
        • 4. 异步处理
        • 5. 限流熔断
      • 微服务监控与运维
        • 监控系统
        • 日志收集
        • CI/CD流水线
        • 灰度发布
      • 案例分析:秒杀系统架构
        • 挑战
        • 解决方案
        • 核心代码实现
      • 总结与展望
  • 常用框架
  • 微服务框架
starxu
2023-12-10
目录

SpringCloud微服务实战

# SpringCloud微服务实战

# 前言

随着业务规模的不断扩大,单体应用逐渐暴露出扩展性差、维护成本高等问题。微服务架构作为一种解决方案,受到了越来越多企业的青睐。本文将结合实际项目经验,详细介绍SpringCloud微服务架构的实践。

# 微服务架构概述

微服务是一种将单体应用拆分为多个小型服务的架构风格,每个服务运行在自己的进程中,服务之间通过轻量级通信机制(通常是HTTP API)进行通信。

# 微服务的优势

  • 技术异构性:不同服务可以使用不同的技术栈
  • 弹性:单个服务故障不会导致整个系统崩溃
  • 可扩展性:可以针对不同服务进行独立扩展
  • 易于部署:服务可以独立部署,不影响其他服务
  • 组织对齐:小团队负责小服务,提高开发效率

# 微服务的挑战

  • 分布式系统复杂性:需要处理网络延迟、容错、消息传递等问题
  • 服务间通信:需要设计高效的通信机制
  • 数据一致性:跨服务事务难以保证
  • 测试复杂度增加:需要测试服务间交互
  • 运维复杂度增加:需要管理多个服务实例

# SpringCloud技术栈

SpringCloud是构建微服务架构的一站式解决方案,提供了一系列工具和框架:

SpringCloud技术栈

# 核心组件

  1. Spring Cloud Netflix

    • Eureka:服务注册与发现
    • Hystrix:断路器
    • Zuul:API网关
    • Ribbon:客户端负载均衡
  2. Spring Cloud Alibaba

    • Nacos:服务注册与配置中心
    • Sentinel:流量控制与熔断降级
    • Seata:分布式事务
  3. 其他组件

    • 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. 配置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

# 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

# 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

# 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

# 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

# 7. 分布式追踪

spring:
  sleuth:
    sampler:
      probability: 1.0  # 采样率,1.0表示全部采样
  zipkin:
    base-url: http://localhost:9411
1
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

# 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

# 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

# 微服务监控与运维

# 监控系统

  • 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

# 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

# 案例分析:秒杀系统架构

# 挑战

  • 瞬时高并发:短时间内大量请求
  • 库存超卖:并发导致的数据一致性问题
  • 恶意请求:防止刷单和机器人攻击

# 解决方案

  1. 流量控制:

    • 前端限流(按钮置灰、倒计时)
    • 网关限流(令牌桶算法)
    • 服务端限流(Sentinel)
  2. 库存处理:

    • Redis预减库存
    • 数据库乐观锁
    • 消息队列异步处理订单
  3. 防刷策略:

    • 验证码
    • 用户行为分析
    • 黑名单机制
  4. 系统架构:

用户请求 -> CDN -> 网关(限流) -> 秒杀服务(Redis校验+预减库存) -> 
消息队列 -> 订单服务(异步创建订单) -> 库存服务(最终扣减库存)
1
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

# 总结与展望

SpringCloud微服务架构为企业提供了灵活、可扩展的解决方案,但同时也带来了分布式系统的复杂性。在实践中,需要根据业务特点和团队能力选择合适的技术栈,并遵循微服务最佳实践。

随着云原生技术的发展,Kubernetes、Service Mesh等技术正在改变微服务的实现方式。未来,微服务将更加轻量化、标准化,并与云平台深度融合。

希望本文能为你的微服务实践提供参考和帮助。

上次更新: 2025/07/01, 01:17:09
Spring核心原理详解

← Spring核心原理详解

最近更新
01
单例模式
03-11
02
Java并发编程实战
11-05
03
JVM性能调优实战
10-15
更多文章>
Theme by Vdoing | Copyright © 2023-2025 star Xu | MIT License | xxxxx号 | xxxxxx
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式