上一篇
上周公司搞周年庆秒杀活动,技术部的小王信心满满地部署了服务,结果活动开始3秒后,系统直接崩溃 💥 —— 每秒10万的请求像洪水一样冲垮了服务器,事后复盘时,CTO拍着桌子说:"下次必须做好限流!"
这时候,Redis的信号量(Semaphore)限流方案就派上用场了,今天我们就来聊聊如何用Redis模拟信号量,给系统装上"流量阀门"。
信号量就像游乐场的入场券 🎟️ —— 假设我们只有100张票,发完即止,对应到系统:
def acquire_semaphore(conn, semname, limit, timeout=10): # 生成唯一标识 identifier = str(uuid.uuid4()) now = time.time() # 开启事务 pipeline = conn.pipeline(True) # 移除过期的信号量持有者 pipeline.zremrangebyscore(semname, '-inf', now - timeout) pipeline.zadd(semname, {identifier: now}) pipeline.zrank(semname, identifier) # 如果排名在限制范围内则获取成功 if pipeline.execute()[-1] < limit: return identifier # 获取失败则清理 conn.zrem(semname, identifier) return None
使用场景:适合简单的限流需求,比如API调用频次控制。
-- KEYS[1]: 信号量key -- ARGV[1]: 当前时间戳 -- ARGV[2]: 超时时间 -- ARGV[3]: 限制数量 -- ARGV[4]: 客户端唯一ID -- 清理过期成员 redis.call('zremrangebyscore', KEYS[1], '-inf', ARGV[1] - ARGV[2]) -- 添加新成员 redis.call('zadd', KEYS[1], ARGV[1], ARGV[4]) -- 获取排名 local rank = redis.call('zrank', KEYS[1], ARGV[4]) -- 判断是否获取成功 if rank and rank < tonumber(ARGV[3]) then return 1 else redis.call('zrem', KEYS[1], ARGV[4]) return 0 end
优势:
Java项目可以直接使用Redisson的RSemaphore:
RSemaphore semaphore = redisson.getSemaphore("orderLimit"); semaphore.trySetPermits(100); // 设置总量 if(semaphore.tryAcquire()) { try { // 处理业务逻辑 } finally { semaphore.release(); } } else { throw new RuntimeException("系统繁忙,请稍后再试"); }
假设我们的订单系统最高承受500QPS:
def order_limit_middleware(request): semaphore_key = "order:semaphore" client_id = request.headers.get("X-Request-ID") # 尝试获取信号量(500个并发) if not acquire_semaphore(redis_conn, semaphore_key, 500, 30, client_id): return JsonResponse({"code": 429, "msg": "当前请求过多,请稍后重试"}, status=429) try: # 处理订单业务 return real_order_handler(request) finally: # 释放信号量 redis_conn.zrem(semaphore_key, client_id)
优化技巧:
方案 | 特点 | 适用场景 |
---|---|---|
信号量 | 严格限制并发数 | 秒杀、数据库连接池 |
令牌桶 | 允许突发流量,平滑限流 | API网关、接口调用限制 |
漏桶 | 严格控制处理速率 | 流量整形、匀速处理 |
通过Redis实现信号量限流,就像给狂奔的野马套上缰绳 🐎,当双11、618等大促来临时,你的系统可以优雅地说:"客官请排队~",而不是直接崩溃躺平。
下次设计高并发系统时,不妨在架构图的入口处画个小小的信号量标志 —— 这是工程师对系统稳定性最浪漫的承诺 ❤️。
(本文技术方案测试环境:Redis 7.2,Python 3.10,压测工具Locust)
本文由 侨丽雅 于2025-08-03发表在【云服务器提供商】,文中图片由(侨丽雅)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/522575.html
发表评论