基于Java线程池实现每秒发送指定数量的API请求,并使用Hutool库进行请求发送,同时记录成功数量、失败数量和失败率。
引入依赖
<!-- Hutool HTTP工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>5.8.20</version>
</dependency>
实现思路
-
创建线程池: 使用
Executors.newScheduledThreadPool()
来创建一个调度线程池,并使用Executors.newFixedThreadPool()
来创建一个用于发送API请求的线程池。 -
调度任务: 使用
ScheduledExecutorService
来按固定速率调度任务。通过控制任务的频率,可以确保每秒发送指定数量的请求。 -
定义API请求任务: 定义一个实现
Runnable
接口的类,负责执行具体的API请求。 -
控制请求速率: 使用调度器每秒提交指定数量的任务到线程池中执行。
实现
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class ApiRequestScheduler {
// 定义线程池,用于并发发送API请求
private final ExecutorService requestExecutor;
// 定义调度线程池,用于定时调度请求任务
private final ScheduledExecutorService scheduler;
// 记录已发送的请求数量
private final AtomicInteger requestCounter;
// 记录成功的请求数量
private final AtomicInteger successCounter;
// 记录失败的请求数量
private final AtomicInteger failureCounter;
// 每秒发送的请求数量
private final int requestsPerSecond;
// API 请求的目标URL
private final String apiUrl;
// 构造函数,初始化线程池和调度器
public ApiRequestScheduler(int requestsPerSecond, String apiUrl) {
this.requestsPerSecond = requestsPerSecond;
this.requestExecutor = Executors.newFixedThreadPool(requestsPerSecond);
this.scheduler = Executors.newScheduledThreadPool(5);
this.requestCounter = new AtomicInteger(0);
this.successCounter = new AtomicInteger(0);
this.failureCounter = new AtomicInteger(0);
this.apiUrl = apiUrl;
}
// 开始调度API请求任务
public void start() {
// 每秒调度任务,按照每秒发送的请求数量来执行
scheduler.scheduleAtFixedRate(() -> {
for (int i = 0; i < requestsPerSecond; i++) {
requestExecutor.submit(this::sendApiRequest);
}
}, 0, 1, TimeUnit.SECONDS);
}
// 停止调度和关闭线程池
public void stop() {
scheduler.shutdown();
requestExecutor.shutdown();
try {
if (!scheduler.awaitTermination(1, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
if (!requestExecutor.awaitTermination(1, TimeUnit.SECONDS)) {
requestExecutor.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
requestExecutor.shutdownNow();
}
// 输出最终的统计结果
int totalRequests = requestCounter.get();
int successRequests = successCounter.get();
int failureRequests = failureCounter.get();
double failureRate = (double) failureRequests / totalRequests * 100;
System.out.println("Total Requests: " + totalRequests);
System.out.println("Successful Requests: " + successRequests);
System.out.println("Failed Requests: " + failureRequests);
System.out.println("Failure Rate: " + String.format("%.2f", failureRate) + "%");
}
// 使用Hutool发送API请求
private void sendApiRequest() {
int requestId = requestCounter.incrementAndGet();
System.out.println("Sending API request #" + requestId);
try {
// 使用Hutool发送GET请求
HttpResponse response = HttpRequest.get(apiUrl).execute();
// 判断请求是否成功
if (response.getStatus() == HttpStatus.HTTP_OK) {
successCounter.incrementAndGet();
System.out.println("Request #" + requestId + " succeeded with status: " + response.getStatus());
} else {
failureCounter.incrementAndGet();
System.err.println("Request #" + requestId + " failed with status: " + response.getStatus());
}
} catch (Exception e) {
failureCounter.incrementAndGet();
System.err.println("Request #" + requestId + " failed with exception: " + e.getMessage());
}
}
public static void main(String[] args) {
// 每秒发送5个API请求,目标URL
ApiRequestScheduler scheduler = new ApiRequestScheduler(5, "http://dzy.com/api");
// 启动调度器
scheduler.start();
// 运行10秒后停止调度器
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// 停止调度器并输出统计信息
scheduler.stop();
}
}
实现效果
每秒发送指定数量的API请求,使用hutool处理HTTP通信,并确保在多线程环境中正确管理资源。可以根据实际需求调整每秒请求数量、API URL、以及线程池大小。