java中基于线程池实现指定每秒发送一定数量的api请求,可以使用scheduledexecutorservice来调度任务,同时使用threadpoolexecutor来处理并发请求,可以根据实际需求调整每秒请求数量、执行时间、以及线程池大小。
实现思路
1.创建线程池
- 使用
executors.newscheduledthreadpool()来创建一个调度线程池 - 并使用
executors.newfixedthreadpool()来创建一个用于发送api请求的线程池
2.调度任务
- 使用
scheduledexecutorservice来按固定速率调度任务。 - 通过控制任务的频率,可以确保每秒发送指定数量的请求。
3.定义api请求任务
- 定义一个实现
runnable接口的类 - 负责执行具体的api请求
4.控制请求速率
- 使用调度器每秒提交指定数量的任务到线程池中执行。
引入依赖
<!-- apache httpclient -->
<dependency>
<groupid>org.apache.httpcomponents.client5</groupid>
<artifactid>httpclient5</artifactid>
<version>5.2</version>
</dependency>实现代码
import org.apache.hc.client5.http.classic.methods.httpget;
import org.apache.hc.client5.http.classic.methods.httpurirequestbase;
import org.apache.hc.client5.http.impl.classic.closeablehttpclient;
import org.apache.hc.client5.http.impl.classic.closeablehttpresponse;
import org.apache.hc.client5.http.impl.classic.httpclients;
import org.apache.hc.core5.http.parseexception;
import org.apache.hc.core5.http.io.entity.entityutils;
import java.io.ioexception;
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 int requestspersecond;
// apache httpclient 实例
private final closeablehttpclient httpclient;
// api 请求的目标url
private final string apiurl;
// 构造函数,初始化线程池和调度器
public apirequestscheduler(int requestspersecond, string apiurl) {
this.requestspersecond = requestspersecond;
this.requestexecutor = executors.newfixedthreadpool(requestspersecond);
this.scheduler = executors.newscheduledthreadpool(1);
this.requestcounter = new atomicinteger(0);
this.httpclient = httpclients.createdefault();
this.apiurl = apiurl;
}
// 开始调度api请求任务
public void start() {
// 每秒调度任务,按照每秒发送的请求数量来执行
scheduler.scheduleatfixedrate(() -> {
for (int i = 0; i < requestspersecond; i++) {
requestexecutor.submit(this::sendapirequest);
}
}, 0, 1, timeunit.seconds);
}
// 停止调度和关闭线程池及httpclient
public void stop() {
scheduler.shutdown();
requestexecutor.shutdown();
try {
if (!scheduler.awaittermination(1, timeunit.seconds)) {
scheduler.shutdownnow();
}
if (!requestexecutor.awaittermination(1, timeunit.seconds)) {
requestexecutor.shutdownnow();
}
httpclient.close();
} catch (interruptedexception | ioexception e) {
scheduler.shutdownnow();
requestexecutor.shutdownnow();
try {
httpclient.close();
} catch (ioexception ioexception) {
ioexception.printstacktrace();
}
}
}
// 使用apache httpclient发送api请求
private void sendapirequest() {
int requestid = requestcounter.incrementandget();
httpurirequestbase request = new httpget(apiurl);
system.out.println("sending api request #" + requestid);
try (closeablehttpresponse response = httpclient.execute(request)) {
string responsebody = entityutils.tostring(response.getentity());
system.out.println("request #" + requestid + " completed with status: " + response.getcode() +
", response: " + responsebody);
} catch (ioexception | parseexception e) {
system.err.println("request #" + requestid + " failed: " + e.getmessage());
}
}
public static void main(string[] args) {
// 每秒发送5个api请求,目标url为http://example.com/api
apirequestscheduler scheduler = new apirequestscheduler(5, "http://www.dzy.com/api");
// 启动调度器
scheduler.start();
// 运行10秒后停止调度器
try {
thread.sleep(10000);
} catch (interruptedexception e) {
thread.currentthread().interrupt();
}
// 停止调度器
scheduler.stop();
}
}实现效果
每秒发送指定数量的api请求,使用apache httpclient处理http通信,并确保在多线程环境中正确管理资源。
可以根据实际需求调整每秒请求数量、api url、以及线程池大小。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论