切換語言為:簡體

基於Hutool工具包實現每秒精準API請求控制

  • 爱糖宝
  • 2024-08-23
  • 2079
  • 0
  • 0

基於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、以及執行緒池大小。


0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.