1、背景
主要是自己在项目中(中小型项目) 有支付下单业务(只是办理VIP,没有涉及到商品库存),目前用户量还没有上来,目前没有出现问题,但是想到如果用户量变大,下单并发量变大,可能会出现一系列的问题,趁着空闲时间,做了这个demo测试相关问题。
可能遇到的问题如下:
1.订单重复
2.高并发下,性能变慢
解决方式:ThreadPoolExecutor线程池 + Queue队列
2、springBoot的项目框架

3、业务测试流程涉及的类
类()
 class BusinessThread implements Runnable{
     String acceptStr;
    public BusinessThread(String acceptStr) {
        .acceptStr = acceptStr;
    }
    public String getAcceptStr() {
         acceptStr;
    }
    public void setAcceptStr(String acceptStr) {
        .acceptStr = acceptStr;
    }
    
    public void run() {
        
        System.out.println(+acceptStr);
        
        
    }
}类@Component
     {
    
     BeanFactory factory; 
    
     final   CORE_POOL_SIZE = ;
    
     final   MAX_POOL_SIZE = ;
    
     final   KEEP_ALIVE_TIME = ;
    
     final   WORK_QUEUE_SIZE = ;
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        factory = beanFactory;
    }
    
    Map<String, Object> cacheMap =  ConcurrentHashMap<>();
    
    Queue<Object> msgQueue =  LinkedBlockingQueue<Object>();
    
    final RejectedExecutionHandler handler =  RejectedExecutionHandler() {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            
            msgQueue.offer(((BusinessThread) r).getAcceptStr());
            System..println( + ((BusinessThread) r).getAcceptStr());
        }
    };
    
   final ThreadPoolExecutor threadPool =  ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,  ArrayBlockingQueue(WORK_QUEUE_SIZE), .handler);
    
    public void addOrders(String orderId){
        System..println( + orderId);
        
         (cacheMap.(orderId) == ) {
            cacheMap.put(orderId,  Object());
            BusinessThread businessThread =  BusinessThread(orderId);
            threadPool.execute(businessThread);
        }
    }
    
    final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool();
    
    final ScheduledFuture scheduledFuture = scheduler.scheduleAtFixedRate( Runnable() {
        @Override
        public void run() {
            
            (!msgQueue.isEmpty()){
                
                 (threadPool.getQueue().size() < WORK_QUEUE_SIZE) {
                    String orderId = (String) msgQueue.poll();
                    BusinessThread businessThread =  BusinessThread(orderId);
                    threadPool.execute(businessThread);
                    System..println(+orderId);
                }
            }
        }
    }, , , TimeUnit.SECONDS);
    
    public Queue<Object> getMsgQueue() {
         msgQueue;
    }
    
    public void shutdown() {
        
        System..println(+scheduledFuture.cancel());
        scheduler.shutdown();
        threadPool.shutdown();
    }
}类TestController {
    
    TestThreadPoolManager testThreadPoolManager;
    
    ()
      start( Long id) {
        
         orderNo = System.currentTimeMillis() + UUID.randomUUID().toString();
        testThreadPoolManager.addOrders(orderNo);
         ;
    }
    
    ()
      end( Long id) {
        testThreadPoolManager.shutdown();
        Queue q = testThreadPoolManager.getMsgQueue();
        System.out.println( + q.size());
         ;
    }
}4、使用JMeter模拟并发下单请求
(JMeter使用可自行百度)

5、打印日志
开始的订单直接执行插入到系统,当线程池的容量已经满了,则使用RejectedExecutionHandler方法把后面的订单添加到 Queue缓冲队列,使用ScheduledFuture方法定时(我这里是每秒一次)检查Queue队列,重新把队列里面的订单添加到线程池,执行后面的插入任务。部分日志如下

PS:防止找不到本篇文章,可以收藏点赞,方便翻阅查找哦。









