首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >SpringBoot中实现限流和熔断功能

SpringBoot中实现限流和熔断功能

原创
作者头像
JQ实验室
发布于 2025-07-30 14:28:57
发布于 2025-07-30 14:28:57
7870
举报

我们将使用Java的ScheduledExecutorService来实现一个简单的令牌桶算法(Token Bucket Algorithm),并结合一个自定义的服务类来处理第三方API调用。

1. 创建限流器

首先,创建一个简单的限流器类:

代码语言:java
复制
import java.util.concurrent.*;

public class SimpleRateLimiter {
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private Semaphore semaphore;
    private final int permits;
    private final long refillTimeMs;

    public SimpleRateLimiter(int permits, long refillTimeMs) {
        this.permits = permits;
        this.refillTimeMs = refillTimeMs;
        semaphore = new Semaphore(permits);
        scheduleRefill();
    }

    private void scheduleRefill() {
        scheduler.scheduleAtFixedRate(() -> {
            semaphore.release(permits - semaphore.availablePermits());
        }, refillTimeMs, refillTimeMs, TimeUnit.MILLISECONDS);
    }

    public boolean tryAcquire() {
        return semaphore.tryAcquire();
    }
}

这个限流器每refillTimeMs毫秒会补充一定数量的许可(permits),从而控制请求速率。

2. 创建服务类

接下来,创建一个服务类来模拟对第三方API的调用,并集成限流器:

代码语言:java
复制
import org.springframework.stereotype.Service;

@Service
public class ThirdPartyService {

    private final SimpleRateLimiter rateLimiter;

    public ThirdPartyService() {
        // 每分钟最多10次请求
        this.rateLimiter = new SimpleRateLimiter(10, 60_000);
    }

    public String fetchData() {
        if (rateLimiter.tryAcquire()) {
            // 模拟调用第三方API
            return "Data from third-party API";
        } else {
            return "Rate limit exceeded, please try again later.";
        }
    }
}
3. 控制器中调用服务

最后,在你的控制器中调用这个服务:

代码语言:java
复制
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ThirdPartyController {

    @Autowired
    private ThirdPartyService thirdPartyService;

    @GetMapping("/fetchData")
    public String fetchData() {
        return thirdPartyService.fetchData();
    }
}

手动实现熔断器

为了实现简单的熔断器逻辑,我们可以维护一个状态变量来跟踪失败次数,并根据一定的条件决定是否触发熔断。

1. 修改服务类以支持熔断

修改之前的ThirdPartyService类,增加熔断逻辑:

代码语言:java
复制
import org.springframework.stereotype.Service;

@Service
public class ThirdPartyService {

    private final SimpleRateLimiter rateLimiter;
    private volatile boolean circuitOpen = false;
    private int failureCount = 0;
    private static final int FAILURE_THRESHOLD = 5; // 失败阈值
    private static final long CIRCUIT_OPEN_TIME_MS = 10_000; // 熔断打开时间

    public ThirdPartyService() {
        this.rateLimiter = new SimpleRateLimiter(10, 60_000);
    }

    public String fetchData() {
        if (circuitOpen) {
            return "Circuit is open, fallback response.";
        }

        if (!rateLimiter.tryAcquire()) {
            return "Rate limit exceeded, please try again later.";
        }

        try {
            // 模拟调用第三方API可能会抛出异常
            if (Math.random() > 0.8) {
                throw new RuntimeException("Third-party service is down");
            }
            resetFailureCount();
            return "Data from third-party API";
        } catch (Exception e) {
            incrementFailureCount();
            return handleFailure(e);
        }
    }

    private void incrementFailureCount() {
        failureCount++;
        if (failureCount >= FAILURE_THRESHOLD) {
            openCircuit();
        }
    }

    private void resetFailureCount() {
        failureCount = 0;
    }

    private void openCircuit() {
        circuitOpen = true;
        new Thread(() -> {
            try {
                Thread.sleep(CIRCUIT_OPEN_TIME_MS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            circuitOpen = false;
        }).start();
    }

    private String handleFailure(Exception e) {
        return "Fallback data due to service unavailability: " + e.getMessage();
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 1. 创建限流器
  • 2. 创建服务类
  • 3. 控制器中调用服务
  • 手动实现熔断器
    • 1. 修改服务类以支持熔断
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档