温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java dubbo怎么实现限流

发布时间:2026-11-03 18:20:48 来源:亿速云 阅读:93 作者:小樊 栏目:编程语言

在 Java + Dubbo 场景下,限流通常可以从 Dubbo 自身机制、SPI 过滤器、外部中间件 三个层面来实现。下面按常见方案从易到难说明。


一、Dubbo 自带限流(最简单)

1. executes 限流(并发数限流)

限制 某个接口的并发执行线程数。

<dubbo:service interface="com.xxx.UserService" executes="10" />

或注解方式:

@DubboService(executes = 10)
public class UserServiceImpl implements UserService {
}

✅ 超过并发数直接抛 RpcException
❌ 不是 QPS 限流,是线程数限流


2. actives 限流(客户端/服务端)

限制 消费者或提供者的最大活跃请求数。

<dubbo:reference interface="com.xxx.UserService" actives="5" />

或:

@DubboReference(actives = 5)

二、使用 Dubbo Filter 自己实现限流(推荐)

1. 基于 Guava RateLimiter(单机 QPS)

自定义 Filter

@Activate(group = Constants.PROVIDER)
public class RateLimitFilter implements Filter {

    private final RateLimiter rateLimiter = RateLimiter.create(100); // 100 QPS

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) {
        if (!rateLimiter.tryAcquire()) {
            throw new RpcException("请求被限流");
        }
        return invoker.invoke(invocation);
    }
}

SPI 配置

META-INF/dubbo/com.alibaba.dubbo.rpc.Filter

rateLimitFilter=com.xxx.RateLimitFilter

✅ 简单、可控
❌ 仅单机


三、Redis + Lua(分布式限流)

1. 令牌桶 Lua 脚本

local key = KEYS[1]
local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])

local fill_time = capacity / rate
local ttl = math.floor(fill_time * 2)

local last_tokens = tonumber(redis.call("get", key) or capacity)
local last_refreshed = tonumber(redis.call("hget", key .. ":ts", "ts") or now)

local delta = math.min(capacity, (now - last_refreshed) * rate)
local tokens = last_tokens + delta

local allowed = tokens >= requested
if allowed then
    tokens = tokens - requested
end

redis.call("set", key, tokens)
redis.call("hset", key .. ":ts", "ts", now)
redis.call("expire", key, ttl)

return allowed and 1 or 0

2. Dubbo Filter 中调用 Redis

if (redis.eval(script, keys, args) == 0) {
    throw new RpcException("限流");
}

✅ 支持集群
✅ 精确 QPS
❌ 有网络开销


四、使用 Sentinel(最推荐生产方案)

1. 引入依赖

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-dubbo-adapter</artifactId>
</dependency>

2. 配置资源限流

@SentinelResource(value = "getUser", blockHandler = "blockHandler")
public User getUser(Long id) {
    return userService.get(id);
}

public User blockHandler(Long id, BlockException e) {
    throw new RpcException("被限流");
}

✅ 支持:

  • QPS
  • 线程数
  • 熔断降级
  • 动态规则(Nacos / Apollo)

五、方案对比

方案 类型 分布式 复杂度
executes 并发 ❌ ⭐
Filter + Guava QPS ❌ ⭐⭐
Redis Lua QPS ✅ ⭐⭐⭐
Sentinel 全功能 ✅ ⭐⭐⭐⭐

六、建议

  • 本地测试 / 小流量:executes 或 Guava
  • 生产环境:✅ Sentinel
  • 多实例集群:Redis / Sentinel

如果你愿意,我可以:

  • 给你一个 完整 Demo
  • 或按 Dubbo 2.x / 3.x 分别写示例
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手