0
点赞
收藏
分享

微信扫一扫

SpringBoot 引入线程池+Queue缓冲队列实现高并发下单业务

 

1、背景


主要是自己在项目中(中小型项目) 有支付下单业务(只是办理VIP,没有涉及到商品库存),目前用户量还没有上来,目前没有出现问题,但是想到如果用户量变大,下单并发量变大,可能会出现一系列的问题,趁着空闲时间,做了这个demo测试相关问题。


可能遇到的问题如下:


 1.订单重复

 2.高并发下,性能变慢


解决方式:ThreadPoolExecutor线程池 + Queue队列



2、springBoot的项目框架


SpringBoot 引入线程池+Queue缓冲队列实现高并发下单业务_ide



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使用可自行百度)


SpringBoot 引入线程池+Queue缓冲队列实现高并发下单业务_spring_02



5、打印日志


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


SpringBoot 引入线程池+Queue缓冲队列实现高并发下单业务_线程池_03


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

举报

相关推荐

并发队列-Queue

0 条评论