利用Redis对含有分页参数的API接口做调用次数限制

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 利用Redis对含有分页参数的API接口做调用次数限制

 背景 - 限制接口调用次数:

       提供内部调用的全量拉取数据接口,以用户appid作为维度区分,一定时间段内(比如1小时),查询某一接口的appid和limit、offset等组合参数只能查询一次,多次查询相同组合参数则返回错误值。

思路:

       采用string类型,key就是模块名:api_limiter_xxx(根据需要自定义key名称),value就是当前可以访问的页数(每次访问成功都自增1)。第一次访问某接口时,若key不存在,那么就添加;若存在,则获取当前redis中对应key的"页数值",并与入参Limit和Offset计算后的页数结果进行比较,若相等则调用成功,反之调用失败。

其中,在设置key和value的时候也要设置"过期时间"。所以关键在于 SETNX 的使用,若存在,则匹配计算的页数与redis中的计数器页数是否相等,若不存在,则设置kv。

注意:其中每次set key的值的时候,过期时间的处理。这里在set之前先通过TTL获取key剩余的过期时间,然后set时再带入接下来剩余的时间即可,避免每次都重新设置固定的过期时间。

    1. 初始时,redisPageCnt = 1
    2. 首次调用接口时,Limit=10,Offset=0,calculateCnt = (Limit + Offset) / Limit = 1;redisPageCnt=1
    3. 此时 calculateCnt = redisPageCnt 相等,redisPageCnt++,redisPageCnt = 2
    4. 再次调用接口时,Limit=10,Offset=10,calculateCnt = (Limit + Offset) / Limit = 2;redisPageCnt=2
    5. 此时 calculateCnt = redisPageCnt 相等,redisPageCnt++,redisPageCnt = 3
    6. ...

           这样的话就可以按页数从前往后递增,每页在限制的超时时间内(1小时)访问一次。在key的超时时间内,访问过的页数也不能再次访问,除非redis中的key超时时间失效。

    请求示例:

    var req = TestReq{ Appid: 1256299843, Limit: 10, Offset: 20, }

    packagemainimport (
    "fmt""strconv""time""github.com/go-redis/redis")
    // 限流:针对含有分页参数的接口,对于不同"Limit和Offset"组合做限制,避免某个用户大量请求影响后台服务处理其他正常请求// 示例://  var req = TestReq{//      Appid:  1256299843,//      Limit:  10,//      Offset: 20,//  }typeTestReqstruct {
    Appiduint64LimitintOffsetint}
    funcAPILimiter(reqTestReq) (errerror) {
    ifreq.Limit!=10 { // 校验入参,暂时写死,根据情况修改fmt.Println("req.Limit format err: ")
    // return response ...return    }
    redisCli :=redis.NewClient(&redis.Options{
    Addr:     "xxx.xxx.xxx.xxx:3306", // ip:portPassword: "yundingyd",
    PoolSize: 10,
        })
    // pong, err := redisCli.Ping().Result()// 不存在 -> 初始化;存在 -> 不处理redisKey :="api_limiter_"+strconv.FormatUint(req.Appid, 10)
    isOk, err :=redisCli.SetNX(redisKey, 1, time.Hour).Result() // 限制超时1小时,Result()针对不同命令自动转换对应结果iferr!=nil&&err!=redis.Nil&&isOk==false {
    fmt.Println("APILimiter SetNX err: ", err)
    // return response ...return    }
    calculatePageCnt := (req.Limit+req.Offset) /req.LimitredisPageCnt, err :=redisCli.Get(redisKey).Int()
    iferr!=nil&&err!=redis.Nil&&isOk==false {
    fmt.Println("APILimiter redisCli.Get err: ", err)
    // return response ...return    }
    ifcalculatePageCnt!=redisPageCnt {
    fmt.Printf("接口调用失败:当前Limit和Offset对应的页数无效: limit=%d, offset=%d, calculateCnt=%d, redisPageCnt=%d\n", req.Limit, req.Offset, calculatePageCnt, redisPageCnt)
    // return response ...return    }
    deferfunc() {
    iferr==nil { // 具体的业务逻辑,期间可能会产生err,只有err为空时才执行以下逻辑~// 先查询当前key的剩余过期时间timeDuration, err :=redisCli.TTL(redisKey).Result()
    iferr!=nil&&err!=redis.Nil {
    fmt.Println("redisCli.TTL err: ", err)
    // return response ...return            }
    // 再设置当前key的剩余过期时间isOk, err :=redisCli.Set(redisKey, redisPageCnt+1, timeDuration).Result() // page + 1iferr!=nil&&err!=redis.Nil&&isOk!="OK" {
    fmt.Println("redisCli.Set err: ", err)
    // return response ...return            }
    fmt.Println("接口调用成功!!!")
            }
        }()
    // 具体的业务逻辑(期间可能会产生err,除非期间err为nil,否则defer函数不执行 page+1 等操作):// ...return}
    funcmain() {
    varreq=TestReq{
    Appid:  1256299843,
    Limit:  10,
    Offset: 20,
        }
    err :=APILimiter(req)
    iferr!=nil {
    fmt.Println("APILimiter err: ", err)
    return    }
    }

    image.gif


    相关实践学习
    基于Redis实现在线游戏积分排行榜
    本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
    云数据库 Redis 版使用教程
    云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
    目录
    相关文章
    |
    18天前
    |
    API PHP 开发者
    速卖通商品详情接口(速卖通API系列)
    速卖通(AliExpress)是阿里巴巴旗下的跨境电商平台,提供丰富的商品数据。通过速卖通开放平台(AliExpress Open API),开发者可获取商品详情、订单管理等数据。主要功能包括商品搜索、商品详情、订单管理和数据报告。商品详情接口aliexpress.affiliate.productdetail.get用于获取商品标题、价格、图片等详细信息。开发者需注册账号并创建应用以获取App Key和App Secret,使用PHP等语言调用API。该接口支持多种请求参数和返回字段,方便集成到各类电商应用中。
    |
    24天前
    |
    JSON API 数据格式
    微店商品列表接口(微店 API 系列)
    微店商品列表接口是微店API系列的一部分,帮助开发者获取店铺中的商品信息。首先需注册微店开发者账号并完成实名认证,选择合适的开发工具如PyCharm或VS Code,并确保熟悉HTTP协议和JSON格式。该接口支持GET/POST请求,主要参数包括店铺ID、页码、每页数量和商品状态等。响应数据为JSON格式,包含商品详细信息及状态码。Python示例代码展示了如何调用此接口。应用场景包括商品管理系统集成、数据分析、多平台数据同步及商品展示推广。
    |
    15天前
    |
    JSON 前端开发 API
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    48 5
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    |
    15天前
    |
    监控 供应链 搜索推荐
    亚马逊商品详情接口(亚马逊 API 系列)
    亚马逊作为全球最大的电商平台之一,提供了丰富的商品资源。开发者和电商从业者可通过亚马逊商品详情接口获取商品的描述、价格、评论、排名等数据,对市场分析、竞品研究、价格监控及业务优化具有重要价值。接口基于MWS服务,支持HTTP/HTTPS协议,需注册并获得API权限。Python示例展示了如何使用mws库调用接口获取商品详情。应用场景包括价格监控、市场调研、智能选品、用户推荐和库存管理等,助力电商运营和决策。
    78 23
    |
    16天前
    |
    JSON 数据挖掘 API
    lazada商品详情接口 (lazada API系列)
    Lazada 是东南亚知名电商平台,提供海量商品资源。通过其商品详情接口,开发者和商家可获取商品标题、价格、库存、描述、图片、用户评价等详细信息,助力市场竞争分析、商品优化及库存管理。接口采用 HTTP GET 请求,返回 JSON 格式的响应数据,支持 Python 等语言调用。应用场景包括竞品分析、价格趋势研究、用户评价分析及电商应用开发,为企业决策和用户体验提升提供有力支持。
    71 21
    |
    13天前
    |
    JSON API 数据格式
    eBay商品详情接口(ebay API系列)
    eBay 商品详情接口是电商从业者、开发者和数据分析师获取商品详细信息的重要工具,涵盖标题、价格、库存、卖家信息等。使用前需在 eBay 开发者平台注册并获取 API 凭证,通过 HTTP GET 请求调用接口,返回 JSON 格式数据。Python 示例代码展示了如何发送请求并解析响应,确保合法合规使用数据。
    49 12
    |
    12天前
    |
    JSON API 数据格式
    阿里巴巴商品详情接口(阿里巴巴 API 系列)
    在电商开发中,获取阿里巴巴商品详情信息对数据分析、竞品研究等至关重要。通过调用其商品详情接口,开发者可获取标题、价格、图片、描述等数据,满足多种业务需求。接口采用HTTPS协议,支持GET/POST请求,返回JSON格式数据。示例代码展示了如何使用Python的requests库进行接口请求,需传递商品ID和访问令牌。实际应用时,请依据官方文档调整参数并确保安全性。
    46 10
    |
    17天前
    |
    数据采集 JSON 监控
    速卖通商品列表接口(以 AliExpress Affiliate 商品查询 API 为例)
    以下是使用 Python 调用速卖通商品列表接口(以 AliExpress Affiliate 商品查询 API 为例)的代码示例。该示例包含准备基础参数、生成签名、发送请求和处理响应等关键步骤,并附有详细注释说明。代码展示了如何通过公共参数和业务参数构建请求,使用 HMAC-SHA256 加密生成签名,确保请求的安全性。最后,解析 JSON 响应并输出商品信息。此接口适用于商品监控、数据采集与分析及商品推荐等场景。注意需通过 OAuth2.0 获取 `access_token`,并根据官方文档调整参数和频率限制。
    |
    17天前
    |
    存储 搜索推荐 API
    淘宝拍立淘按图搜索API接口系列概述
    淘宝拍立淘按图搜索API接口允许用户通过上传图片或拍摄实物来搜索相似或相同的商品。这一功能主要依赖于图像识别技术,系统会对上传的图片进行分析和处理,提取出商品的特征信息,并在淘宝的商品数据库中进行匹配搜索,最终返回与上传图片相似或相同的商品列表。
    |
    17天前
    |
    JSON 监控 API
    速卖通商品列表接口(速卖通API系列)
    速卖通提供商品列表API,开发者可通过关键词、类目、价格范围等条件获取商品标题、价格、销量等基本信息。使用前需注册开发者账号、创建应用并授权获取access_token。Python示例代码展示了如何调用接口,返回JSON格式数据,包含商品列表、总数、页码等信息。应用场景包括商品监控、数据分析和个性化推荐。注意API会更新,请参考官方文档。