简易电商订单处理策略 --Cursor工具根据描述自动生成

简易电商订单处理策略

正常情况:任务进入线程池队列处理
队列满时:优先存入Redis待处理队列
Redis异常时:降级到低优先级线程池
系统过载时:触发熔断保护机制

OrderTask实现订单任务包装
支持Redis持久化获取订单数据
采用组合拒绝策略实现多级处理
Redis持久化使用List结构存储待处理订单
熔断器基于令牌桶算法实现限流

自定义线程池 以及 拒绝策略

1. 拒绝策略 – 队列满时:优先存入Redis待处理队列

import com.orderhandler.model.OrderTask;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

public class RedisBackupPolicy implements RejectedExecutionHandler {
    private static final String PENDING_ORDERS_KEY = "order:pending";
    private final RedisTemplate<String, OrderTask> redisTemplate;
    
    public RedisBackupPolicy(RedisTemplate<String, OrderTask> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        if (r instanceof OrderTask) {
            OrderTask task = (OrderTask) r;
            try {
                // Store the task in Redis list
                redisTemplate.opsForList().rightPush(PENDING_ORDERS_KEY, task);
            } catch (Exception e) {
                // If Redis fails, propagate the exception to try next handler
                throw new RuntimeException("Failed to store task in Redis", e);
            }
        } else {
            throw new IllegalArgumentException("Task must be an OrderTask");
        }
    }
    
    // Method to retrieve pending tasks from Redis
    public OrderTask retrievePendingTask() {
        return redisTemplate.opsForList().leftPop(PENDING_ORDERS_KEY);
    }
    
    // Method to get pending tasks count
    public Long getPendingTasksCount() {
        return redisTemplate.opsForList().size(PENDING_ORDERS_KEY);
    }
} 
2. 拒绝策略 – Redis异常时:降级到低优先级线程池
//
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

public class TieredDegradePolicy implements RejectedExecutionHandler {
    private final ThreadPoolExecutor lowPriorityPool;
    
    public TieredDegradePolicy(ThreadPoolExecutor lowPriorityPool) {
        this.lowPriorityPool = lowPriorityPool;
    }
    
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        try {
            // Try to submit the task to low priority pool
            lowPriorityPool.execute(r);
        } catch (Exception e) {
            // If low priority pool also rejects, propagate the exception
            throw new RuntimeException("Failed to degrade task to low priority pool", e);
        }
    }
} 
3. 拒绝策略 – 系统过载时:触发熔断保护机制
// 熔断器基于令牌桶算法实现限流
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.TimeUnit;

public class CircuitBreakerPolicy implements RejectedExecutionHandler {
    private final TokenBucket tokenBucket;
    
    public CircuitBreakerPolicy(int capacity, int refillRate) {
        this.tokenBucket = new TokenBucket(capacity, refillRate);
    }
    
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        if (!tokenBucket.tryConsume()) {
            throw new RuntimeException("Circuit breaker triggered - system overloaded");
        }
        // If we got here, we have a token but nowhere to execute
        // Propagate rejection to trigger fallback mechanisms
        throw new RuntimeException("All processing capacity exhausted");
    }
    
    // Token Bucket implementation for rate limiting
    private static class TokenBucket {
        private final int capacity;
        private final int refillRate;
        private final AtomicInteger tokens;
        private long lastRefillTimestamp;
        
        public TokenBucket(int capacity, int refillRate) {
            this.capacity = capacity;
            this.refillRate = refillRate;
            this.tokens = new AtomicInteger(capacity);
            this.lastRefillTimestamp = System.nanoTime();
        }
        
        public synchronized boolean tryConsume() {
            refill();
            
            if (tokens.get() > 0) {
                tokens.decrementAndGet();
                return true;
            }
            return false;
        }
        
        private void refill() {
            long now = System.nanoTime();
            long duration = now - lastRefillTimestamp;
            
            // Calculate tokens to add based on time elapsed
            long newTokens = TimeUnit.NANOSECONDS.toSeconds(duration) * refillRate;
            
            if (newTokens > 0) {
                int currentTokens = Math.min(capacity, tokens.get() + (int)newTokens);
                tokens.set(currentTokens);
                lastRefillTimestamp = now;
            }
        }
    }
} 
4. 组合拒绝策略处理器
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.RejectedExecutionException;

public class CompositePolicy implements RejectedExecutionHandler {
    private final List<RejectedExecutionHandler> handlers = new ArrayList<>();
    
    public CompositePolicy addHandler(RejectedExecutionHandler handler) {
        handlers.add(handler);
        return this;
    }
    
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        for (RejectedExecutionHandler handler : handlers) {
            try {
                handler.rejectedExecution(r, executor);
                return; // If handler succeeds, return immediately
            } catch (Exception e) {
                // Continue to next handler if current one fails
                continue;
            }
        }
        // If all handlers fail, throw exception
        throw new RejectedExecutionException("All handlers failed to process task");
    }
} 
5. 自定义线程池 – 采取多个拒绝策略形成的组合策略
import com.orderhandler.model.OrderTask;
import com.orderhandler.thread.CircuitBreakerPolicy;
import com.orderhandler.thread.CompositePolicy;
import com.orderhandler.thread.RedisBackupPolicy;
import com.orderhandler.thread.TieredDegradePolicy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
public class ThreadPoolConfig {
    
    @Bean
    public RedisTemplate<String, OrderTask> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, OrderTask> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new Jackson2JsonRedisSerializer<>(OrderTask.class));
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(OrderTask.class));
        return template;
    }
    
    @Bean
    public ThreadPoolExecutor lowPriorityPool() {
        return new ThreadPoolExecutor(
            2,                          // Core pool size
            5,                          // Maximum pool size
            60L,                        // Keep alive time
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(50) // Queue capacity
        );
    }
    
    @Bean
    public ThreadPoolExecutor orderExecutor(
            RedisTemplate<String, OrderTask> redisTemplate,
            ThreadPoolExecutor lowPriorityPool) {
            
        CircuitBreakerPolicy breaker = new CircuitBreakerPolicy(100, 10); // 100 tokens, 10 per second refill
        
        CompositePolicy rejectionPolicy = new CompositePolicy()
            .addHandler(new RedisBackupPolicy(redisTemplate))  // 优先持久化
            .addHandler(new TieredDegradePolicy(lowPriorityPool))  // 次选降级
            .addHandler(breaker);  // 最后熔断

        return new ThreadPoolExecutor(
                8,                          // Core pool size
                16,                         // Maximum pool size
                300L,                        // Keep alive time
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(200), // Queue capacity
                rejectionPolicy
        );
    }
} 

订单相关

1. 订单服务
import com.orderhandler.model.OrderTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@Service
public class OrderProcessingService {
    
    private final ThreadPoolExecutor orderExecutor;
    private final RedisTemplate<String, OrderTask> redisTemplate;
    private static final String PENDING_ORDERS_KEY = "order:pending";
    
    @Autowired
    public OrderProcessingService(
            ThreadPoolExecutor orderExecutor,
            RedisTemplate<String, OrderTask> redisTemplate) {
        this.orderExecutor = orderExecutor;
        this.redisTemplate = redisTemplate;
    }
    
    public void submitOrder(String orderId, String userId, Double amount) {
        OrderTask task = new OrderTask(orderId, userId, amount);
        try {
            orderExecutor.execute(() -> processOrder(task));
        } catch (Exception e) {
            log.error("Failed to submit order: {}", orderId, e);
            throw e;
        }
    }
    
    private void processOrder(OrderTask task) {
        try {
            log.info("Processing order: {}", task.getOrderId());
            task.markProcessing();
            
            // Simulate order processing
            Thread.sleep(1000);
            
            task.markCompleted();
            log.info("Order completed: {}", task.getOrderId());
            
        } catch (Exception e) {
            task.markFailed();
            log.error("Order processing failed: {}", task.getOrderId(), e);
        }
    }
    
    // Method to process orders from Redis backup queue
    public void processBackupOrders() {
        while (true) {
            OrderTask task = redisTemplate.opsForList().leftPop(PENDING_ORDERS_KEY);
            if (task == null) {
                break;
            }
            
            try {
                orderExecutor.execute(() -> processOrder(task));
            } catch (RejectedExecutionException e) {
                log.error("Failed to process backup order: {}", task.getOrderId(), e);
                // Put it back in the queue
                redisTemplate.opsForList().rightPush(PENDING_ORDERS_KEY, task);
                // Stop processing more orders since executor is full
                break;
            } catch (Exception e) {
                log.error("Unexpected error processing backup order: {}", task.getOrderId(), e);
                // Put it back in the queue for retry
                redisTemplate.opsForList().rightPush(PENDING_ORDERS_KEY, task);
                break;
            }
        }
    }
    
    // Get executor statistics
    public String getExecutorStats() {
        return String.format(
            "Pool size: %d, Active: %d, Queue size: %d, Completed: %d",
            orderExecutor.getPoolSize(),
            orderExecutor.getActiveCount(),
            orderExecutor.getQueue().size(),
            orderExecutor.getCompletedTaskCount()
        );
    }
} 
2. 订单任务包装类
//订单任务包装类
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;

@Data
public class OrderTask implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private String orderId;
    private String userId;
    private Double amount;
    private Integer priority;
    private LocalDateTime createTime;
    private OrderStatus status;
    
    public enum OrderStatus {
        PENDING,
        PROCESSING,
        COMPLETED,
        FAILED
    }
    
    // Constructor for creating a new order task
    public OrderTask(String orderId, String userId, Double amount) {
        this.orderId = orderId;
        this.userId = userId;
        this.amount = amount;
        this.createTime = LocalDateTime.now();
        this.status = OrderStatus.PENDING;
        this.priority = 0;
    }
    
    // Method to mark the task as processing
    public void markProcessing() {
        this.status = OrderStatus.PROCESSING;
    }
    
    // Method to mark the task as completed
    public void markCompleted() {
        this.status = OrderStatus.COMPLETED;
    }
    
    // Method to mark the task as failed
    public void markFailed() {
        this.status = OrderStatus.FAILED;
    }
} 

结尾 TIPS

AI工具 或许 成为 All-Factor Engineer 又一个得力助手,你会面临失业吗?😄 😂 🔔

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值