使用 Upstash 实现请求和令牌的限流

在现代应用程序中,限流是一种关键技术,可以防止系统过载并控制API的使用量。在这篇文章中,我们将学习如何使用 Upstash 的 RatelimitHandler 来实现基于请求数量或令牌数量的限流。这一工具借助 Upstash 提供的 Redis 实现,确保每次调用 limit 方法时,都能通过 HTTP 请求更新用户的剩余请求或令牌,并根据剩余数量来判断是否继续执行诸如调用大型语言模型(LLM)或者查询向量存储等昂贵操作。

技术背景介绍

Upstash 是一种托管的 Redis 云服务,提供了强大而简单的 API 接口,适合现代应用对 Redis 的使用场景。通过 Upstash 的 ratelimit 库,可以轻松实现请求或令牌的限流。

核心原理解析

限流的核心在于通过 Redis 的存储能力对用户请求进行计数。当用户的请求超过了预设的限额时,系统会停止用户的后续操作,从而避免系统负载过高。限流策略通常包括固定窗口、滑动窗口等,本文中我们将使用固定窗口策略(FixedWindow)。

代码实现演示

开始之前,请确保你已经注册并创建了 Upstash Redis 数据库,并设置好必要的环境变量:

export UPSTASH_REDIS_REST_URL='your-redis-url'
export UPSTASH_REDIS_REST_TOKEN='your-redis-token'

然后安装必要的 Python 库:

pip install upstash-ratelimit upstash-redis

每请求限流

假设我们希望每分钟允许用户最多进行 10 次请求,下面是实现该功能的代码示例:

import os

# 设置环境变量
os.environ["UPSTASH_REDIS_REST_URL"] = "your-redis-url"
os.environ["UPSTASH_REDIS_REST_TOKEN"] = "your-redis-token"

from langchain_community.callbacks import UpstashRatelimitError, UpstashRatelimitHandler
from langchain_core.runnables import RunnableLambda
from upstash_ratelimit import FixedWindow, Ratelimit
from upstash_redis import Redis

# 创建限流器
ratelimit = Ratelimit(
    redis=Redis.from_env(),
    # 每60秒最多10次请求
    limiter=FixedWindow(max_requests=10, window=60),
)

# 创建处理器
user_id = "user_id"  # 获取用户ID的方法
handler = UpstashRatelimitHandler(identifier=user_id, request_ratelimit=ratelimit)

# 创建一个模拟链
chain = RunnableLambda(str)

# 使用处理器调用链
try:
    result = chain.invoke("Hello world!", config={"callbacks": [handler]})
except UpstashRatelimitError as e:
    print("Handling ratelimit.", e)

每令牌限流

除了对请求进行限流,也可以根据令牌数量进行限流,这在使用 LLM 场景中特别有效。以下是实现动态令牌限流的代码:

import os

# 设置环境变量
os.environ["UPSTASH_REDIS_REST_URL"] = "your-redis-url"
os.environ["UPSTASH_REDIS_REST_TOKEN"] = "your-redis-token"
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"

from langchain_community.callbacks import UpstashRatelimitError, UpstashRatelimitHandler
from langchain_core.runnables import RunnableLambda
from langchain_openai import ChatOpenAI
from upstash_ratelimit import FixedWindow, Ratelimit
from upstash_redis import Redis

# 创建限流器
ratelimit = Ratelimit(
    redis=Redis.from_env(),
    # 每60秒最多500个令牌
    limiter=FixedWindow(max_requests=500, window=60),
)

# 创建处理器
user_id = "user_id"  # 获取用户ID的方法
handler = UpstashRatelimitHandler(identifier=user_id, token_ratelimit=ratelimit)

# 创建一个包含 LLM 的链
as_str = RunnableLambda(str)
model = ChatOpenAI()

chain = as_str | model

# 使用处理器调用链
try:
    result = chain.invoke("Hello world!", config={"callbacks": [handler]})
except UpstashRatelimitError as e:
    print("Handling ratelimit.", e)

应用场景分析

这种限流机制特别适合像 API 网关、微服务架构中可能遇到的限流需求,并能有效防止恶意用户的滥用。

实践建议

  1. 确保你的 Redis 实例有足够的性能来处理限流请求。
  2. 选择适合你业务需求的限流策略,例如固定窗口或滑动窗口。
  3. 定期监控和调整限流参数,以适应不断变化的流量模式。

如果遇到问题欢迎在评论区交流。

—END—

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值