在 Java + Dubbo 场景下,限流通常可以从 Dubbo 自身机制、SPI 过滤器、外部中间件 三个层面来实现。下面按常见方案从易到难说明。
executes 限流(并发数限流)限制 某个接口的并发执行线程数。
<dubbo:service interface="com.xxx.UserService" executes="10" />
或注解方式:
@DubboService(executes = 10)
public class UserServiceImpl implements UserService {
}
✅ 超过并发数直接抛 RpcException
❌ 不是 QPS 限流,是线程数限流
actives 限流(客户端/服务端)限制 消费者或提供者的最大活跃请求数。
<dubbo:reference interface="com.xxx.UserService" actives="5" />
或:
@DubboReference(actives = 5)
@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);
}
}
META-INF/dubbo/com.alibaba.dubbo.rpc.Filter
rateLimitFilter=com.xxx.RateLimitFilter
✅ 简单、可控
❌ 仅单机
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
if (redis.eval(script, keys, args) == 0) {
throw new RpcException("限流");
}
✅ 支持集群
✅ 精确 QPS
❌ 有网络开销
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-dubbo-adapter</artifactId>
</dependency>
@SentinelResource(value = "getUser", blockHandler = "blockHandler")
public User getUser(Long id) {
return userService.get(id);
}
public User blockHandler(Long id, BlockException e) {
throw new RpcException("被限流");
}
✅ 支持:
| 方案 | 类型 | 分布式 | 复杂度 |
|---|---|---|---|
| executes | 并发 | ❌ | ⭐ |
| Filter + Guava | QPS | ❌ | ⭐⭐ |
| Redis Lua | QPS | ✅ | ⭐⭐⭐ |
| Sentinel | 全功能 | ✅ | ⭐⭐⭐⭐ |
executes 或 Guava如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。