当前位置 : 主页 > 编程语言 > java >

java分布式限流的方式有哪些

来源:互联网 收集:自由互联 发布时间:2023-10-10
Java分布式限流的方式 1. 简介 分布式限流是指在分布式系统中对请求进行限制,以控制系统的负载和保护系统的稳定性。在Java开发中,常用的分布式限流方式有:令牌桶算法、漏桶算法

Java分布式限流的方式

1. 简介

分布式限流是指在分布式系统中对请求进行限制,以控制系统的负载和保护系统的稳定性。在Java开发中,常用的分布式限流方式有:令牌桶算法、漏桶算法和计数器算法。本文将介绍这三种常见的分布式限流方式,并提供相应的代码实例。

2. 限流流程

下面是实现Java分布式限流的一般流程:

flowchart TD
    A[获取请求] --> B[根据规则判断是否限流]
    B --> |未限流| C[执行请求]
    B --> |限流| D[返回限流提示]

3. 分布式限流实现方式

3.1 令牌桶算法

令牌桶算法是一种常见的限流算法。其原理是系统以恒定的速率往一个令牌桶中放入令牌,而处理请求前需要从令牌桶中获取令牌,如果获取不到令牌则表示限流。以下是令牌桶算法的Java实现示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class TokenBucket {
    private final int MAX_TOKENS;
    private final int tokensPerSecond;
    private double tokens;
    private long lastRefreshTime;

    public TokenBucket(int tokensPerSecond) {
        this.tokensPerSecond = tokensPerSecond;
        this.MAX_TOKENS = tokensPerSecond;
        this.tokens = MAX_TOKENS;
        this.lastRefreshTime = System.currentTimeMillis();
    }

    public synchronized boolean allowRequest(int tokens) {
        refresh();

        if (tokens <= this.tokens) {
            this.tokens -= tokens;
            return true;
        }

        return false;
    }

    private synchronized void refresh() {
        long currentTime = System.currentTimeMillis();
        double elapsedTime = (currentTime - lastRefreshTime) / 1000.0;
        double newTokens = elapsedTime * tokensPerSecond;
        this.tokens = Math.min(this.tokens + newTokens, MAX_TOKENS);
        this.lastRefreshTime = currentTime;
    }

    public static void main(String[] args) throws InterruptedException {
        TokenBucket tokenBucket = new TokenBucket(10);

        ExecutorService executorService = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 20; i++) {
            executorService.submit(() -> {
                try {
                    if (tokenBucket.allowRequest(1)) {
                        System.out.println("Request processed");
                    } else {
                        System.out.println("Request rejected");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });

            TimeUnit.MILLISECONDS.sleep(100);
        }

        executorService.shutdown();
    }
}

在上述代码中,TokenBucket类实现了令牌桶算法。其中,allowRequest方法用于判断是否允许请求通过,refresh方法用于刷新桶中的令牌数量。在main方法中,模拟了20个请求,每个请求需要获取1个令牌,如果获取到令牌则表示请求通过,否则请求被拒绝。

3.2 漏桶算法

漏桶算法是另一种常见的限流算法。其原理是系统以恒定的速率处理请求,并将多余的请求放入一个漏桶中,如果漏桶已满则表示限流。以下是漏桶算法的Java实现示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class LeakyBucket {
    private final int capacity;
    private final int rate;
    private int water;
    private long lastLeakTime;

    public LeakyBucket(int capacity, int rate) {
        this.capacity = capacity;
        this.rate = rate;
        this.water = 0;
        this.lastLeakTime = System.currentTimeMillis();
    }

    public synchronized boolean allowRequest() {
        leak();

        if (water < capacity) {
            water++;
            return true;
        }

        return false;
    }

    private synchronized void leak() {
        long currentTime = System.currentTimeMillis();
        long elapsedTime = currentTime - lastLeakTime;
        int leakedWater = (int) (elapsedTime / 1000.0 * rate);
        water = Math.max(0, water - leakedWater);
        lastLeakTime = currentTime;
    }

    public static void main(String[] args) throws InterruptedException {
        LeakyBucket leakyBucket = new
上一篇:java登录过期时间
下一篇:没有了
网友评论