当前位置: 代码网 > it编程>编程语言>Java > Java线程池如何实现精准控制每秒API请求

Java线程池如何实现精准控制每秒API请求

2024年08月22日 Java 我要评论
java中基于线程池实现指定每秒发送一定数量的api请求,可以使用scheduledexecutorservice来调度任务,同时使用threadpoolexecutor来处理并发请求,可以根据实际需

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、以及线程池大小。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com