|
@@ -18,88 +18,88 @@ import java.util.concurrent.*;
|
|
|
/**
|
|
/**
|
|
|
* 50万高并发库存扣减测试
|
|
* 50万高并发库存扣减测试
|
|
|
*/
|
|
*/
|
|
|
-@RunWith(SpringRunner.class)
|
|
|
|
|
-@SpringBootTest(classes = FsUserAppApplication.class)
|
|
|
|
|
-@RequiredArgsConstructor
|
|
|
|
|
-@Slf4j
|
|
|
|
|
|
|
+//@RunWith(SpringRunner.class)
|
|
|
|
|
+//@SpringBootTest(classes = FsUserAppApplication.class)
|
|
|
|
|
+//@RequiredArgsConstructor
|
|
|
|
|
+//@Slf4j
|
|
|
public class StockDeductTest {
|
|
public class StockDeductTest {
|
|
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
- private StockDeductService stockDeductService;
|
|
|
|
|
-
|
|
|
|
|
- // 商品ID
|
|
|
|
|
- private static final Long PRODUCT_ID = 1001L;
|
|
|
|
|
- // 初始库存(模拟5万库存,应对50万并发扣减)
|
|
|
|
|
- private static final Integer INIT_STOCK = 5000;
|
|
|
|
|
- // 总请求数(50万)
|
|
|
|
|
- private static final int TOTAL_REQUESTS = 50000;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 模拟50万高并发库存扣减
|
|
|
|
|
- */
|
|
|
|
|
- @Test
|
|
|
|
|
- public void testHighConcurrencyDeduct() throws InterruptedException, ExecutionException {
|
|
|
|
|
- stockDeductService.initStock(PRODUCT_ID, 1L, INIT_STOCK);
|
|
|
|
|
- // Java 8 ExecutorService 线程池(固定线程池,适配高并发)
|
|
|
|
|
- ExecutorService executorService = createHighConcurrencyPool();
|
|
|
|
|
-
|
|
|
|
|
- // 存储所有异步任务结果
|
|
|
|
|
- List<CompletableFuture<Boolean>> futureList = new ArrayList<>();
|
|
|
|
|
-
|
|
|
|
|
- // 提交50万请求
|
|
|
|
|
- for (int i = 0; i < TOTAL_REQUESTS; i++) {
|
|
|
|
|
-// futureList.add(stockDeductService.deductStockAsync(PRODUCT_ID, 1L, (long) i));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 等待所有任务完成(Java 8 CompletableFuture 批量处理)
|
|
|
|
|
- CompletableFuture<Void> allFutures = CompletableFuture.allOf(
|
|
|
|
|
- futureList.toArray(new CompletableFuture[0])
|
|
|
|
|
- );
|
|
|
|
|
- allFutures.get();
|
|
|
|
|
-
|
|
|
|
|
- // 统计结果
|
|
|
|
|
- long successCount = futureList.stream()
|
|
|
|
|
- .map(future -> {
|
|
|
|
|
- try {
|
|
|
|
|
- return future.get();
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- .filter(Boolean::booleanValue)
|
|
|
|
|
- .count();
|
|
|
|
|
-
|
|
|
|
|
- // 打印结果
|
|
|
|
|
- System.out.println("======================================");
|
|
|
|
|
- System.out.println("50万高并发库存扣减测试完成");
|
|
|
|
|
- System.out.println("成功扣减次数:" + successCount);
|
|
|
|
|
- System.out.println("失败扣减次数:" + (TOTAL_REQUESTS - successCount));
|
|
|
|
|
- System.out.println("最终剩余库存:" + stockDeductService.redisTemplate.opsForValue().get(RedisConstant.STOCK_KEY_PREFIX + PRODUCT_ID));
|
|
|
|
|
- System.out.println("======================================");
|
|
|
|
|
-
|
|
|
|
|
- // 关闭线程池
|
|
|
|
|
- executorService.shutdown();
|
|
|
|
|
- executorService.awaitTermination(1, TimeUnit.MINUTES);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- private static ExecutorService createHighConcurrencyPool() {
|
|
|
|
|
- int corePoolSize = Runtime.getRuntime().availableProcessors() * 2; // CPU核心数*2
|
|
|
|
|
- int maximumPoolSize = 200; // 最大线程数,根据服务器配置调整
|
|
|
|
|
- long keepAliveTime = 60L;
|
|
|
|
|
- // 用SynchronousQueue,直接提交任务,避免队列积压
|
|
|
|
|
- BlockingQueue<Runnable> workQueue = new SynchronousQueue<>();
|
|
|
|
|
- // 拒绝策略:丢弃最老的任务,避免OOM
|
|
|
|
|
- RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
|
|
|
|
|
-
|
|
|
|
|
- return new ThreadPoolExecutor(
|
|
|
|
|
- corePoolSize,
|
|
|
|
|
- maximumPoolSize,
|
|
|
|
|
- keepAliveTime,
|
|
|
|
|
- TimeUnit.SECONDS,
|
|
|
|
|
- workQueue,
|
|
|
|
|
- new ThreadPoolExecutor.CallerRunsPolicy() // 兜底:主线程执行,避免任务丢失
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
+// @Autowired
|
|
|
|
|
+// private StockDeductService stockDeductService;
|
|
|
|
|
+//
|
|
|
|
|
+// // 商品ID
|
|
|
|
|
+// private static final Long PRODUCT_ID = 1001L;
|
|
|
|
|
+// // 初始库存(模拟5万库存,应对50万并发扣减)
|
|
|
|
|
+// private static final Integer INIT_STOCK = 5000;
|
|
|
|
|
+// // 总请求数(50万)
|
|
|
|
|
+// private static final int TOTAL_REQUESTS = 50000;
|
|
|
|
|
+//
|
|
|
|
|
+// /**
|
|
|
|
|
+// * 模拟50万高并发库存扣减
|
|
|
|
|
+// */
|
|
|
|
|
+// @Test
|
|
|
|
|
+// public void testHighConcurrencyDeduct() throws InterruptedException, ExecutionException {
|
|
|
|
|
+// stockDeductService.initStock(PRODUCT_ID, 1L, INIT_STOCK);
|
|
|
|
|
+// // Java 8 ExecutorService 线程池(固定线程池,适配高并发)
|
|
|
|
|
+// ExecutorService executorService = createHighConcurrencyPool();
|
|
|
|
|
+//
|
|
|
|
|
+// // 存储所有异步任务结果
|
|
|
|
|
+// List<CompletableFuture<Boolean>> futureList = new ArrayList<>();
|
|
|
|
|
+//
|
|
|
|
|
+// // 提交50万请求
|
|
|
|
|
+// for (int i = 0; i < TOTAL_REQUESTS; i++) {
|
|
|
|
|
+//// futureList.add(stockDeductService.deductStockAsync(PRODUCT_ID, 1L, (long) i));
|
|
|
|
|
+// }
|
|
|
|
|
+//
|
|
|
|
|
+// // 等待所有任务完成(Java 8 CompletableFuture 批量处理)
|
|
|
|
|
+// CompletableFuture<Void> allFutures = CompletableFuture.allOf(
|
|
|
|
|
+// futureList.toArray(new CompletableFuture[0])
|
|
|
|
|
+// );
|
|
|
|
|
+// allFutures.get();
|
|
|
|
|
+//
|
|
|
|
|
+// // 统计结果
|
|
|
|
|
+// long successCount = futureList.stream()
|
|
|
|
|
+// .map(future -> {
|
|
|
|
|
+// try {
|
|
|
|
|
+// return future.get();
|
|
|
|
|
+// } catch (Exception e) {
|
|
|
|
|
+// return false;
|
|
|
|
|
+// }
|
|
|
|
|
+// })
|
|
|
|
|
+// .filter(Boolean::booleanValue)
|
|
|
|
|
+// .count();
|
|
|
|
|
+//
|
|
|
|
|
+// // 打印结果
|
|
|
|
|
+// System.out.println("======================================");
|
|
|
|
|
+// System.out.println("50万高并发库存扣减测试完成");
|
|
|
|
|
+// System.out.println("成功扣减次数:" + successCount);
|
|
|
|
|
+// System.out.println("失败扣减次数:" + (TOTAL_REQUESTS - successCount));
|
|
|
|
|
+// System.out.println("最终剩余库存:" + stockDeductService.redisTemplate.opsForValue().get(RedisConstant.STOCK_KEY_PREFIX + PRODUCT_ID));
|
|
|
|
|
+// System.out.println("======================================");
|
|
|
|
|
+//
|
|
|
|
|
+// // 关闭线程池
|
|
|
|
|
+// executorService.shutdown();
|
|
|
|
|
+// executorService.awaitTermination(1, TimeUnit.MINUTES);
|
|
|
|
|
+// }
|
|
|
|
|
+//
|
|
|
|
|
+//
|
|
|
|
|
+//
|
|
|
|
|
+// private static ExecutorService createHighConcurrencyPool() {
|
|
|
|
|
+// int corePoolSize = Runtime.getRuntime().availableProcessors() * 2; // CPU核心数*2
|
|
|
|
|
+// int maximumPoolSize = 200; // 最大线程数,根据服务器配置调整
|
|
|
|
|
+// long keepAliveTime = 60L;
|
|
|
|
|
+// // 用SynchronousQueue,直接提交任务,避免队列积压
|
|
|
|
|
+// BlockingQueue<Runnable> workQueue = new SynchronousQueue<>();
|
|
|
|
|
+// // 拒绝策略:丢弃最老的任务,避免OOM
|
|
|
|
|
+// RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
|
|
|
|
|
+//
|
|
|
|
|
+// return new ThreadPoolExecutor(
|
|
|
|
|
+// corePoolSize,
|
|
|
|
|
+// maximumPoolSize,
|
|
|
|
|
+// keepAliveTime,
|
|
|
|
|
+// TimeUnit.SECONDS,
|
|
|
|
|
+// workQueue,
|
|
|
|
|
+// new ThreadPoolExecutor.CallerRunsPolicy() // 兜底:主线程执行,避免任务丢失
|
|
|
|
|
+// );
|
|
|
|
|
+// }
|
|
|
|
|
+}
|