Spring Boot、Redis、RabbitMQ 在项目中的核心作用详解

文章目录

    • [一、Spring Boot:快速开发的利器](#一、Spring Boot:快速开发的利器)
      • [1.1 Spring Boot 的核心作用](#1.1 Spring Boot 的核心作用)
      • [1.2 Spring Boot 项目结构](#1.2 Spring Boot 项目结构)
      • [1.3 Spring Boot 自动配置原理](#1.3 Spring Boot 自动配置原理)
      • [1.4 Spring Boot 在项目中的架构位置](#1.4 Spring Boot 在项目中的架构位置)
    • 二、Redis:高性能缓存与数据存储
      • [2.1 Redis 的核心作用](#2.1 Redis 的核心作用)
      • [2.2 Redis 在 Spring Boot 中的集成](#2.2 Redis 在 Spring Boot 中的集成)
      • [2.3 Redis 缓存使用示例](#2.3 Redis 缓存使用示例)
      • [2.4 Redis 数据结构应用场景](#2.4 Redis 数据结构应用场景)
      • [2.5 Redis 在系统架构中的位置](#2.5 Redis 在系统架构中的位置)
    • 三、RabbitMQ:可靠的消息中间件
      • [3.1 RabbitMQ 的核心作用](#3.1 RabbitMQ 的核心作用)
      • [3.2 RabbitMQ 在 Spring Boot 中的配置](#3.2 RabbitMQ 在 Spring Boot 中的配置)
      • [3.3 RabbitMQ 消息生产者](#3.3 RabbitMQ 消息生产者)
      • [3.4 RabbitMQ 消息消费者](#3.4 RabbitMQ 消息消费者)
      • [3.5 RabbitMQ 高级特性配置](#3.5 RabbitMQ 高级特性配置)
      • [3.6 RabbitMQ 在系统架构中的消息流](#3.6 RabbitMQ 在系统架构中的消息流)
    • 四、三者在项目中的协同工作
      • [4.1 完整电商订单处理流程](#4.1 完整电商订单处理流程)
      • [4.2 系统架构图](#4.2 系统架构图)
      • [4.3 性能优化配置](#4.3 性能优化配置)
    • 五、总结

在现代企业级应用开发中,Spring Boot、Redis 和 RabbitMQ 已经成为不可或缺的技术组件。它们各自在项目中扮演着重要角色,共同构建出高性能、高可用的分布式系统。本文将深入剖析这三者在实际项目中的作用,并通过代码示例和流程图展示它们的实际应用。

一、Spring Boot:快速开发的利器

1.1 Spring Boot 的核心作用

Spring Boot 是一个基于 Spring 框架的快速开发脚手架,其主要作用体现在:

  • 简化配置:通过自动配置和约定优于配置的原则,大幅减少 XML 配置
  • 快速启动:内嵌 Tomcat、Jetty 等 Web 容器,无需部署 WAR 包
  • 生产就绪:提供健康检查、指标监控等生产级特性
  • 微服务支持:完美支持 Spring Cloud 微服务生态

1.2 Spring Boot 项目结构

java 复制代码
// 主启动类
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// 控制器层
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User savedUser = userService.createUser(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
    }
}

// 服务层
@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    public User getUserById(Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("User not found"));
    }
    
    public User createUser(User user) {
        return userRepository.save(user);
    }
}

// 数据访问层
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);
}

// 实体类
@Entity
@Table(name = "users")
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false)
    private String name;
    
    @Column(nullable = false, unique = true)
    private String email;
    
    @CreationTimestamp
    private LocalDateTime createdAt;
}

1.3 Spring Boot 自动配置原理

java 复制代码
// 自定义 Starter 示例
@Configuration
@ConditionalOnClass(UserService.class)
@EnableConfigurationProperties(UserProperties.class)
public class UserAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public UserService userService(UserProperties properties) {
        return new UserService(properties);
    }
}

// 配置属性类
@ConfigurationProperties(prefix = "app.user")
@Data
public class UserProperties {
    private String defaultName = "Default User";
    private int maxAttempts = 3;
}

// META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfigure.UserAutoConfiguration

1.4 Spring Boot 在项目中的架构位置

复制代码
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│    Client       │───▶│  Spring Boot     │───▶│   Database      │
│   (Browser/App) │    │   Application    │    │   (MySQL/PSQL)  │
└─────────────────┘    └──────────────────┘    └─────────────────┘
         │                       │                       │
         │                       ▼                       │
         │              ┌─────────────────┐             │
         └──────────────│   Thymeleaf     │─────────────┘
                        │   Templates     │
                        └─────────────────┘

二、Redis:高性能缓存与数据存储

2.1 Redis 的核心作用

Redis 是一个开源的内存数据结构存储,用作数据库、缓存和消息代理,其主要作用:

  • 缓存加速:减少数据库访问,提升应用性能
  • 会话存储:分布式会话管理
  • 消息队列:通过 Pub/Sub 和 Streams 实现消息传递
  • 实时数据处理:计数器、排行榜等实时功能

2.2 Redis 在 Spring Boot 中的集成

java 复制代码
// Redis 配置类
@Configuration
@EnableCaching
public class RedisConfig {
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        
        // 使用 Jackson2JsonRedisSerializer 序列化
        Jackson2JsonRedisSerializer<Object> serializer = 
            new Jackson2JsonRedisSerializer<>(Object.class);
        
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.activateDefaultTyping(
            mapper.getPolymorphicTypeValidator(),
            ObjectMapper.DefaultTyping.NON_FINAL
        );
        serializer.setObjectMapper(mapper);
        
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        
        return template;
    }
    
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(10))  // 设置缓存过期时间
            .disableCachingNullValues();       // 不缓存空值
        
        return RedisCacheManager.builder(factory)
            .cacheDefaults(config)
            .build();
    }
}

2.3 Redis 缓存使用示例

java 复制代码
// 缓存服务类
@Service
public class ProductService {
    
    @Autowired
    private ProductRepository productRepository;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    private static final String PRODUCT_CACHE_KEY = "product:";
    private static final String PRODUCT_LIST_CACHE_KEY = "products:all";
    
    // 使用 Spring Cache 注解
    @Cacheable(value = "products", key = "#id")
    public Product getProductById(Long id) {
        return productRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Product not found"));
    }
    
    // 手动缓存操作
    public List<Product> getAllProducts() {
        // 先从缓存获取
        List<Product> products = (List<Product>) redisTemplate.opsForValue()
                .get(PRODUCT_LIST_CACHE_KEY);
        
        if (products != null) {
            return products;
        }
        
        // 缓存未命中,查询数据库
        products = productRepository.findAll();
        
        // 写入缓存,设置过期时间
        redisTemplate.opsForValue().set(
            PRODUCT_LIST_CACHE_KEY, 
            products, 
            Duration.ofMinutes(30)
        );
        
        return products;
    }
    
    // 更新缓存
    @CachePut(value = "products", key = "#product.id")
    public Product updateProduct(Product product) {
        Product updated = productRepository.save(product);
        
        // 清除列表缓存
        redisTemplate.delete(PRODUCT_LIST_CACHE_KEY);
        
        return updated;
    }
    
    // 删除缓存
    @CacheEvict(value = "products", key = "#id")
    public void deleteProduct(Long id) {
        productRepository.deleteById(id);
        redisTemplate.delete(PRODUCT_LIST_CACHE_KEY);
    }
    
    // Redis 分布式锁示例
    public boolean purchaseProduct(Long productId, Integer quantity) {
        String lockKey = "lock:product:" + productId;
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 尝试获取分布式锁
            Boolean locked = redisTemplate.opsForValue().setIfAbsent(
                lockKey, requestId, Duration.ofSeconds(10)
            );
            
            if (Boolean.TRUE.equals(locked)) {
                // 获取锁成功,执行库存扣减
                Product product = getProductById(productId);
                if (product.getStock() >= quantity) {
                    product.setStock(product.getStock() - quantity);
                    updateProduct(product);
                    return true;
                }
                return false;
            } else {
                // 获取锁失败,稍后重试
                Thread.sleep(100);
                return purchaseProduct(productId, quantity);
            }
        } catch (Exception e) {
            throw new RuntimeException("Purchase failed", e);
        } finally {
            // 释放锁
            if (requestId.equals(redisTemplate.opsForValue().get(lockKey))) {
                redisTemplate.delete(lockKey);
            }
        }
    }
}

2.4 Redis 数据结构应用场景

java 复制代码
@Service
public class RedisDataStructureService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // String 类型:缓存、计数器
    public void stringOperations() {
        // 缓存对象
        User user = new User(1L, "John Doe", "john@example.com");
        redisTemplate.opsForValue().set("user:1", user);
        
        // 计数器
        redisTemplate.opsForValue().increment("page:view:home");
        Long views = redisTemplate.opsForValue().increment("user:1:login:count");
    }
    
    // Hash 类型:存储对象属性
    public void hashOperations() {
        redisTemplate.opsForHash().put("user:2", "name", "Jane Smith");
        redisTemplate.opsForHash().put("user:2", "email", "jane@example.com");
        redisTemplate.opsForHash().put("user:2", "age", "25");
        
        String name = (String) redisTemplate.opsForHash().get("user:2", "name");
    }
    
    // List 类型:消息队列、最新列表
    public void listOperations() {
        // 最新消息列表
        redisTemplate.opsForList().leftPush("recent:news", "News 1");
        redisTemplate.opsForList().leftPush("recent:news", "News 2");
        redisTemplate.opsForList().trim("recent:news", 0, 9); // 保持10条最新
        
        List<Object> recentNews = redisTemplate.opsForList().range("recent:news", 0, -1);
    }
    
    // Set 类型:标签、共同好友
    public void setOperations() {
        // 用户标签
        redisTemplate.opsForSet().add("user:1:tags", "vip", "active", "premium");
        redisTemplate.opsForSet().add("user:2:tags", "active", "new");
        
        // 共同标签
        Set<Object> commonTags = redisTemplate.opsForSet().intersect("user:1:tags", "user:2:tags");
    }
    
    // Sorted Set 类型:排行榜
    public void sortedSetOperations() {
        // 用户积分排行榜
        redisTemplate.opsForZSet().add("leaderboard", "user1", 1000);
        redisTemplate.opsForZSet().add("leaderboard", "user2", 1500);
        redisTemplate.opsForZSet().add("leaderboard", "user3", 1200);
        
        // 获取前10名
        Set<ZSetOperations.TypedTuple<Object>> topUsers = 
            redisTemplate.opsForZSet().reverseRangeWithScores("leaderboard", 0, 9);
    }
}

2.5 Redis 在系统架构中的位置

复制代码
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│  Spring Boot    │───▶│      Redis       │◀───│  Other Services │
│   Application   │    │                  │    │                 │
└─────────────────┘    └──────────────────┘    └─────────────────┘
         │                       │
         │                       │
         ▼                       ▼
┌─────────────────┐    ┌──────────────────┐
│   Database      │    │   Message Queue  │
│   (MySQL)       │    │   (RabbitMQ)     │
└─────────────────┘    └──────────────────┘

三、RabbitMQ:可靠的消息中间件

3.1 RabbitMQ 的核心作用

RabbitMQ 是一个开源的消息代理软件,实现了高级消息队列协议(AMQP),主要作用:

  • 应用解耦:分离系统组件,降低耦合度
  • 异步处理:提高系统响应速度
  • 流量削峰:应对突发流量,保护后端系统
  • 消息分发:实现发布/订阅模式

3.2 RabbitMQ 在 Spring Boot 中的配置

java 复制代码
// RabbitMQ 配置类
@Configuration
public class RabbitMQConfig {
    
    // 交换机
    public static final String EXCHANGE_ORDER = "order.exchange";
    public static final String EXCHANGE_NOTIFICATION = "notification.exchange";
    
    // 队列
    public static final String QUEUE_ORDER_CREATE = "order.create.queue";
    public static final String QUEUE_ORDER_CANCEL = "order.cancel.queue";
    public static final String QUEUE_NOTIFICATION_EMAIL = "notification.email.queue";
    public static final String QUEUE_NOTIFICATION_SMS = "notification.sms.queue";
    
    // 路由键
    public static final String ROUTING_KEY_ORDER_CREATE = "order.create";
    public static final String ROUTING_KEY_ORDER_CANCEL = "order.cancel";
    public static final String ROUTING_KEY_NOTIFICATION_ALL = "notification.#";
    
    // 订单交换机(Direct)
    @Bean
    public DirectExchange orderExchange() {
        return new DirectExchange(EXCHANGE_ORDER);
    }
    
    // 通知交换机(Topic)
    @Bean
    public TopicExchange notificationExchange() {
        return new TopicExchange(EXCHANGE_NOTIFICATION);
    }
    
    // 订单创建队列
    @Bean
    public Queue orderCreateQueue() {
        return new Queue(QUEUE_ORDER_CREATE, true); // durable=true
    }
    
    // 订单取消队列
    @Bean
    public Queue orderCancelQueue() {
        return new Queue(QUEUE_ORDER_CANCEL, true);
    }
    
    // 邮件通知队列
    @Bean
    public Queue emailNotificationQueue() {
        return new Queue(QUEUE_NOTIFICATION_EMAIL, true);
    }
    
    // 短信通知队列
    @Bean
    public Queue smsNotificationQueue() {
        return new Queue(QUEUE_NOTIFICATION_SMS, true);
    }
    
    // 绑定关系
    @Bean
    public Binding bindingOrderCreate(Queue orderCreateQueue, DirectExchange orderExchange) {
        return BindingBuilder.bind(orderCreateQueue)
                .to(orderExchange)
                .with(ROUTING_KEY_ORDER_CREATE);
    }
    
    @Bean
    public Binding bindingOrderCancel(Queue orderCancelQueue, DirectExchange orderExchange) {
        return BindingBuilder.bind(orderCancelQueue)
                .to(orderExchange)
                .with(ROUTING_KEY_ORDER_CANCEL);
    }
    
    @Bean
    public Binding bindingEmailNotification(Queue emailNotificationQueue, TopicExchange notificationExchange) {
        return BindingBuilder.bind(emailNotificationQueue)
                .to(notificationExchange)
                .with(ROUTING_KEY_NOTIFICATION_ALL);
    }
    
    @Bean
    public Binding bindingSmsNotification(Queue smsNotificationQueue, TopicExchange notificationExchange) {
        return BindingBuilder.bind(smsNotificationQueue)
                .to(notificationExchange)
                .with(ROUTING_KEY_NOTIFICATION_ALL);
    }
    
    // JSON 消息转换器
    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }
}

3.3 RabbitMQ 消息生产者

java 复制代码
@Service
public class OrderMessageProducer {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    // 发送订单创建消息
    public void sendOrderCreateMessage(Order order) {
        try {
            OrderMessage message = new OrderMessage(
                order.getId(),
                order.getUserId(),
                order.getTotalAmount(),
                order.getStatus(),
                LocalDateTime.now()
            );
            
            rabbitTemplate.convertAndSend(
                RabbitMQConfig.EXCHANGE_ORDER,
                RabbitMQConfig.ROUTING_KEY_ORDER_CREATE,
                message,
                new CorrelationData(order.getId().toString())
            );
            
            log.info("Order create message sent: {}", order.getId());
        } catch (Exception e) {
            log.error("Failed to send order create message", e);
            throw new MessageSendException("Failed to send order message");
        }
    }
    
    // 发送订单取消消息
    public void sendOrderCancelMessage(Long orderId, String reason) {
        OrderCancelMessage message = new OrderCancelMessage(orderId, reason, LocalDateTime.now());
        
        rabbitTemplate.convertAndSend(
            RabbitMQConfig.EXCHANGE_ORDER,
            RabbitMQConfig.ROUTING_KEY_ORDER_CANCEL,
            message
        );
        
        log.info("Order cancel message sent: {}", orderId);
    }
    
    // 发送通知消息
    public void sendNotification(Notification notification) {
        rabbitTemplate.convertAndSend(
            RabbitMQConfig.EXCHANGE_NOTIFICATION,
            "notification." + notification.getType(),
            notification
        );
    }
}

// 订单消息DTO
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderMessage {
    private Long orderId;
    private Long userId;
    private BigDecimal totalAmount;
    private String status;
    private LocalDateTime timestamp;
}

// 订单取消消息DTO
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderCancelMessage {
    private Long orderId;
    private String reason;
    private LocalDateTime timestamp;
}

3.4 RabbitMQ 消息消费者

java 复制代码
@Component
public class OrderMessageConsumer {
    
    @Autowired
    private InventoryService inventoryService;
    
    @Autowired
    private EmailService emailService;
    
    @Autowired
    private NotificationService notificationService;
    
    // 处理订单创建消息
    @RabbitListener(queues = RabbitMQConfig.QUEUE_ORDER_CREATE)
    public void handleOrderCreate(OrderMessage message) {
        try {
            log.info("Processing order create message: {}", message.getOrderId());
            
            // 扣减库存
            inventoryService.deductInventory(message.getOrderId());
            
            // 发送确认邮件
            emailService.sendOrderConfirmation(message.getOrderId());
            
            // 记录处理成功
            log.info("Order create message processed successfully: {}", message.getOrderId());
        } catch (Exception e) {
            log.error("Failed to process order create message: {}", message.getOrderId(), e);
            // 可以在这里实现重试逻辑或死信队列处理
            throw new AmqpRejectAndDontRequeueException("Processing failed");
        }
    }
    
    // 处理订单取消消息
    @RabbitListener(queues = RabbitMQConfig.QUEUE_ORDER_CANCEL)
    public void handleOrderCancel(OrderCancelMessage message) {
        log.info("Processing order cancel message: {}", message.getOrderId());
        
        // 恢复库存
        inventoryService.restoreInventory(message.getOrderId());
        
        // 发送取消通知
        notificationService.sendCancelNotification(message.getOrderId(), message.getReason());
    }
}

// 通知消息消费者
@Component
public class NotificationMessageConsumer {
    
    @Autowired
    private EmailService emailService;
    
    @Autowired
    private SmsService smsService;
    
    @RabbitListener(queues = RabbitMQConfig.QUEUE_NOTIFICATION_EMAIL)
    public void handleEmailNotification(Notification notification) {
        log.info("Processing email notification: {}", notification);
        emailService.sendNotification(notification);
    }
    
    @RabbitListener(queues = RabbitMQConfig.QUEUE_NOTIFICATION_SMS)
    public void handleSmsNotification(Notification notification) {
        log.info("Processing SMS notification: {}", notification);
        smsService.sendNotification(notification);
    }
}

3.5 RabbitMQ 高级特性配置

java 复制代码
@Configuration
public class RabbitMQAdvancedConfig {
    
    // 死信交换机配置
    public static final String DLX_EXCHANGE = "dlx.exchange";
    public static final String DLX_QUEUE = "dlx.queue";
    public static final String DLX_ROUTING_KEY = "dlx.routing.key";
    
    // 重试队列配置
    public static final String RETRY_QUEUE = "order.create.retry.queue";
    public static final int MAX_RETRY_COUNT = 3;
    
    @Bean
    public DirectExchange dlxExchange() {
        return new DirectExchange(DLX_EXCHANGE);
    }
    
    @Bean
    public Queue dlxQueue() {
        return new Queue(DLX_QUEUE, true);
    }
    
    @Bean
    public Binding dlxBinding() {
        return BindingBuilder.bind(dlxQueue())
                .to(dlxExchange())
                .with(DLX_ROUTING_KEY);
    }
    
    // 带死信队列的订单创建队列
    @Bean
    public Queue orderCreateQueueWithDLX() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", DLX_EXCHANGE);
        args.put("x-dead-letter-routing-key", DLX_ROUTING_KEY);
        args.put("x-message-ttl", 60000); // 1分钟TTL
        
        return new Queue(RabbitMQConfig.QUEUE_ORDER_CREATE, true, false, false, args);
    }
    
    // 消息确认回调
    @Bean
    public RabbitTemplate.ConfirmCallback confirmCallback() {
        return (correlationData, ack, cause) -> {
            if (ack) {
                log.info("Message confirmed with correlation data: {}", correlationData);
            } else {
                log.error("Message confirmation failed: {}, cause: {}", correlationData, cause);
            }
        };
    }
    
    // 消息返回回调
    @Bean
    public RabbitTemplate.ReturnsCallback returnsCallback() {
        return returned -> {
            log.error("Message returned: {}", returned);
        };
    }
}

3.6 RabbitMQ 在系统架构中的消息流

复制代码
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   Order Service │───▶│   RabbitMQ       │───▶│  Inventory      │
│                 │    │                  │    │   Service       │
└─────────────────┘    └──────────────────┘    └─────────────────┘
         │                       │                       │
         │                       │                       │
         │                       ▼                       │
         │              ┌─────────────────┐             │
         └─────────────▶│  Email Service  │─────────────┘
                        └─────────────────┘
                                │
                                │
                                ▼
                        ┌─────────────────┐
                        │   SMS Service   │
                        └─────────────────┘

四、三者在项目中的协同工作

4.1 完整电商订单处理流程

java 复制代码
@Service
@Transactional
public class OrderProcessingService {
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private OrderMessageProducer messageProducer;
    
    @Autowired
    private InventoryService inventoryService;
    
    // 创建订单的完整流程
    public Order createOrder(OrderRequest request) {
        String lockKey = "lock:user:" + request.getUserId() + ":order";
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 1. 获取分布式锁,防止重复提交
            Boolean locked = redisTemplate.opsForValue()
                    .setIfAbsent(lockKey, requestId, Duration.ofSeconds(5));
            
            if (!Boolean.TRUE.equals(locked)) {
                throw new BusinessException("请勿重复提交订单");
            }
            
            // 2. 检查库存(Redis 缓存)
            boolean inStock = inventoryService.checkStock(request.getProductId(), request.getQuantity());
            if (!inStock) {
                throw new BusinessException("库存不足");
            }
            
            // 3. 创建订单
            Order order = orderService.createOrder(request);
            
            // 4. 发送订单创建消息到 RabbitMQ
            messageProducer.sendOrderCreateMessage(order);
            
            // 5. 更新 Redis 中的用户订单缓存
            updateUserOrderCache(order.getUserId(), order);
            
            // 6. 记录订单创建日志到 Redis
            logOrderCreation(order);
            
            return order;
            
        } finally {
            // 释放分布式锁
            if (requestId.equals(redisTemplate.opsForValue().get(lockKey))) {
                redisTemplate.delete(lockKey);
            }
        }
    }
    
    private void updateUserOrderCache(Long userId, Order order) {
        String userOrdersKey = "user:" + userId + ":orders";
        
        // 使用 Redis List 存储用户最近订单
        redisTemplate.opsForList().leftPush(userOrdersKey, order);
        redisTemplate.opsForList().trim(userOrdersKey, 0, 49); // 保留最近50条订单
    }
    
    private void logOrderCreation(Order order) {
        String orderLogKey = "order:log:" + LocalDate.now().toString();
        
        Map<String, Object> logEntry = new HashMap<>();
        logEntry.put("orderId", order.getId());
        logEntry.put("userId", order.getUserId());
        logEntry.put("amount", order.getTotalAmount());
        logEntry.put("timestamp", LocalDateTime.now());
        
        redisTemplate.opsForHash().put(orderLogKey, order.getId().toString(), logEntry);
    }
}

4.2 系统架构图

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                     Client Layer                                │
│    ┌─────────────────┐    ┌─────────────────┐                  │
│    │   Web Browser   │    │  Mobile App     │                  │
│    └─────────────────┘    └─────────────────┘                  │
│            │                           │                       │
└────────────┼───────────────────────────┼───────────────────────┘
             │                           │
             ▼                           ▼
┌─────────────────────────────────────────────────────────────────┐
│                 Spring Boot Application                         │
│    ┌─────────────────┐    ┌─────────────────┐                  │
│    │   Controller    │───▶│    Service      │                  │
│    │    Layer        │    │     Layer       │                  │
│    └─────────────────┘    └─────────────────┘                  │
│            │                           │                       │
│            ▼                           ▼                       │
│    ┌─────────────────┐    ┌─────────────────┐                  │
│    │   Redis Cache   │    │  RabbitMQ       │                  │
│    │                 │    │  Producer       │                  │
│    └─────────────────┘    └─────────────────┘                  │
└────────────┼───────────────────────────┼───────────────────────┘
             │                           │
             ▼                           ▼
┌─────────────────────────────────────────────────────────────────┐
│                    Backend Services                             │
│    ┌─────────────────┐    ┌─────────────────┐                  │
│    │   Database      │    │  RabbitMQ       │                  │
│    │   (MySQL)       │    │  Consumer       │                  │
│    └─────────────────┘    └─────────────────┘                  │
│            │                           │                       │
│            │                           ▼                       │
│            │                  ┌─────────────────┐              │
│            │                  │   External      │              │
│            │                  │   Services      │              │
│            │                  │ (Email/SMS/...) │              │
│            │                  └─────────────────┘              │
│            │                                                   │
│            └───────────────────────────────────────────────────┘
│                                                                │
└─────────────────────────────────────────────────────────────────┘

4.3 性能优化配置

yaml 复制代码
# application.yml
spring:
  # Redis 配置
  redis:
    host: ${REDIS_HOST:localhost}
    port: ${REDIS_PORT:6379}
    password: ${REDIS_PASSWORD:}
    database: 0
    lettuce:
      pool:
        max-active: 20
        max-idle: 10
        min-idle: 5
        max-wait: 1000ms
      shutdown-timeout: 100ms
  
  # RabbitMQ 配置
  rabbitmq:
    host: ${RABBITMQ_HOST:localhost}
    port: ${RABBITMQ_PORT:5672}
    username: ${RABBITMQ_USERNAME:guest}
    password: ${RABBITMQ_PASSWORD:guest}
    virtual-host: /
    # 确认模式
    publisher-confirm-type: correlated
    publisher-returns: true
    # 消费者配置
    listener:
      simple:
        acknowledge-mode: manual
        prefetch: 10
        concurrency: 5
        max-concurrency: 10
        retry:
          enabled: true
          max-attempts: 3
          initial-interval: 1000ms
  
  # 数据源配置
  datasource:
    url: jdbc:mysql://${DB_HOST:localhost}:3306/ecommerce
    username: ${DB_USERNAME:root}
    password: ${DB_PASSWORD:password}
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000

# 自定义配置
app:
  cache:
    ttl: 30m
  order:
    timeout: 30m
  redis:
    key-prefix: "app:"

五、总结

通过本文的详细讲解,我们可以看到 Spring Boot、Redis 和 RabbitMQ 在现代分布式系统中各自扮演着重要角色:

  • Spring Boot 提供了快速开发的能力,通过自动配置和丰富的 Starter 简化了项目搭建和配置
  • Redis 作为高性能缓存和数据存储,显著提升了系统性能并提供了丰富的数据结构支持
  • RabbitMQ 实现了系统解耦和异步处理,提高了系统的可扩展性和可靠性

三者结合使用,可以构建出高性能、高可用、易扩展的现代分布式应用系统。在实际项目中,我们需要根据具体业务场景合理选择和使用这些技术,充分发挥它们的优势。

希望本文能够帮助大家更好地理解和使用 Spring Boot、Redis 和 RabbitMQ,在实际项目中构建出更加优秀的系统架构。

相关推荐
随风M记忆s10 小时前
Redis支持事务吗?了解Redis的持久化机制吗?
数据库·redis·bootstrap
独行侠影a21 小时前
APScheduler+Redis 分布式定时任务:解决多实例任务重复执行
数据库·redis·分布式
paopaokaka_luck1 天前
基于springboot3+vue3的智能文库平台(AI智能搜索、AI智能汇总、实时在线状态展示、多格式文档预览与富文本编辑、Echarts图形化分析)
前端·网络·spring boot·网络协议·echarts
zzzll11111 天前
Spring Boot 入门指南:从零开始构建 Java Web 应用
java·前端·spring boot
不在逃避q1 天前
Golang笔记之Redis
redis·笔记·golang
江晓鱼未暖1 天前
十七、Redis 核心原理与架构详解
大数据·数据库·数据仓库·redis·缓存·架构
红莲凪是1 天前
Redis有哪些部署方案?了解哨兵机制吗?
java·redis·eureka
小罗水1 天前
第13章 Redis 缓存、幂等锁与任务状态
数据库·redis·缓存
热心市民lcj1 天前
Spring Boot 整合 Caffeine 本地缓存实战
spring boot·后端·缓存
天丁o1 天前
Spring Boot + MyBatis Plus 考勤日报统计报表:打卡记录聚合、异常分类和明细下钻 Demo
spring boot·mybatis plus·企业数字化·考勤系统·报表统计