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,在实际项目中构建出更加优秀的系统架构。

相关推荐
a123560mh2 小时前
国产信创操作系统银河麒麟常见软件适配(MongoDB、 Redis、Nginx、Tomcat)
linux·redis·nginx·mongodb·tomcat·kylin
vx_bisheyuange2 小时前
基于SpringBoot的宠物商城网站的设计与实现
spring boot·后端·宠物
Elias不吃糖2 小时前
总结我的小项目里现在用到的Redis
c++·redis·学习
⑩-4 小时前
缓存穿透,击穿,雪崩
java·redis
稚辉君.MCA_P8_Java5 小时前
DeepSeek 使用Kubernetes部署Redisson
大数据·人工智能·redis·后端·kubernetes
玄妙之门5 小时前
项目实战中redis和数据库结合提升缓存效率
数据库·redis·缓存
元Y亨H5 小时前
Spring Boot 路由踩坑:当“通配符”吞掉了你的“固定路径”
spring boot
得物技术6 小时前
一文解析得物自建 Redis 最新技术演进
数据库·redis·云计算
q***65696 小时前
使用 java -jar 命令启动 Spring Boot 应用时,指定特定的配置文件的几种实现方式
java·spring boot·jar