秒杀系统关于限流的思考

        在秒杀业务场景中,限流是保障系统稳定性的重要手段。

限流一般分为:

        1.用户限流--限制用户一秒内最多发送多少请求

        2.ip限流--和用户同理

        3.接口限流

        用户限流与IP限流其实都是为了放别人脚本疯狂发请求,但是别人通过一些技术手段可以绕开。所以需要整个接口限流防止服务挂掉,以下讨论的都是接口限流。

以下是几种常见的限流方式及其适用场景。
1.使用 Sentinel

Sentinel 是一个强大的流量控制组件,支持并发线程数、QPS、响应时间等多维度的流量控制。

支持在运行时动态配置限流规则,不需要重启应用。

结合 Spring Cloud Alibaba,支持微服务架构中的分布式限流。

内置支持熔断、降级、系统保护等功能,扩展性强。

// 定义资源
Entry entry = null;
try {
    entry = SphU.entry("seckillResource");
    // 你的业务逻辑
} catch (BlockException ex) {
    // 被限流的处理逻辑
} finally {
    if (entry != null) {
        entry.exit();
    }
}
2.Guava RateLimiter(令牌桶算法)

实现简单,Guava 的 RateLimiter 提供了简单的限流实现。(Guava也提供其它的各种实用工具)

适合单个应用实例进行限流,不依赖外部服务。

RateLimiter rateLimiter = RateLimiter.create(1000); // 每秒生成 1000 个令牌
if (rateLimiter.tryAcquire()) {
    // 获取到令牌,继续处理
} else {
    // 被限流,返回提示
}
3. Redis 分布式限流

通过 Redis 实现分布式限流,可以有效解决单点问题,适用于分布式系统。常用的实现方式有:

1.计数器:基于时间窗口统计请求次数,适合简单场景。

2.令牌桶:利用 Redis 的原子操作模拟令牌桶。允许一定的突发流量。

3.漏桶:控制请求的平滑流出,避免突发流量。

-- Lua 脚本
local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local refill_time = tonumber(ARGV[2])
local current_time = tonumber(ARGV[3])
local token_rate = tonumber(ARGV[4])

-- 获取当前令牌数
local tokens = redis.call('get', key)
if tokens == false then
    tokens = capacity
else
    tokens = tonumber(tokens)
end

-- 计算新令牌数
local elapsed_time = current_time - redis.call('time')[1]
tokens = math.min(capacity, tokens + elapsed_time * token_rate)

-- 是否可以通过
if tokens < 1 then
    return 0 -- 限流
else
    redis.call('setex', key, refill_time, tokens - 1)
    return 1 -- 通过
end
4.Nginx 限流

通过 Nginx 自带的限流模块,在网关层实现限流,减少应用压力。

http {
    limit_req_zone $binary_remote_addr zone=seckill:10m rate=100r/s;

    server {
        location /seckill {
            limit_req zone=seckill burst=10 nodelay;
            proxy_pass http://backend;
        }
    }
}
总结:

1.如果业务是微服务架构,建议使用 Sentinel,它不仅限流,还能结合降级与熔断保护系统。

2.如果业务是单机部署且限流规则简单,可以优先考虑 Guava RateLimiter

3.如果需要分布式限流,且想自己实现灵活的方案,建议使用 Redis

4.如果需要在流量入口就限制,可以使用 Nginx 限流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值