一秒内的重复请求如何处理 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
twogoods
V2EX    程序员

一秒内的重复请求如何处理

  •  
  •   twogoods 2016-1207 09:30:02 +08:00 13278 次点击
    这是一个创建于 3278 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一个接口部署了三台机器, Nginx 做负载均衡,重复请求怎么处理,上 zookeeper , redis 吗?
    第 1 条附言    2016-12-07 12:40:54 +08:00
    业务是 insert 一条数据比如说订单这样的,重复可能就是前端点得太快造成的,所以基本就是几秒钟时间左右的幂等
    30 条回复    2016-12-09 06:13:26 +08:00
    9hills
        1
    9hills  
       2016-12-07 09:46:23 +08:00 via iPhone
    简单但是有很大局限性的方法

    负载均衡改成源地址 Hash ,保证同一来源的请求落到一个后端

    其他的都需要有个
    9hills
        2
    9hills  
       2016-12-07 09:47:42 +08:00 via iPhone
    接上

    其他的基本都需要类锁服务,但是局限性也少了很多。 Redis 就不错,大部分场景也能 Hold 。
    moorlop
        3
    moorlop  
       2016-12-07 09:54:02 +08:00 via iPhone
    requestID
    xjp
        4
    xjp  
       2016-12-07 09:59:11 +08:00 via iPhone
    我们是用用 redis 做锁的 获取到锁的请求才正常处理 其他的请求直接返回错误
    lhbc
        5
    lhbc  
       2016-12-07 10:29:53 +08:00 via iPhone
    接口所有操作都是幂等的吗?
    幂等的话多次请求并没有关系。
    mengskysama
        6
    mengskysama  
       2016-12-07 10:45:20 +08:00 via iPhone   2
    我觉得 lz 没有表达清楚这个问题,这个请求业务逻辑是什么样的。

    如果是重复的 get 请求最高效的做法是在 nginx 上做合并回源,确保请求同一个资源只有一个请求打到后端,其他请求都要 pending 这个请求的结果
        7
    sciooga  
       2016-12-07 10:50:48 +08:00
    关键词 惊群问题
    sciooga
    twogoods
        8
    twogoods  
    OP
       2016-12-07 12:30:39 +08:00
    @lhbc 如果业务是 insert 一条数据,那幂等应该怎么处理?最直白就是一秒的相同请求只执行一个其他都丢弃
    phpman
        9
    phpman  
       2016-12-07 12:33:25 +08:00
    重复请求有问题么?一秒内重复请求和一分钟内重复请求有什么区别呢?楼主还是要把业务逻辑表述清楚
    ihuotui
        10
    ihuotui  
       2016-12-07 12:56:29 +08:00
    nginx session sticky 保持会话
    iphash 负载策略
    requestToken 过滤重复提交
    Infernalzero
        11
    Infernalzero  
       2016-12-07 13:00:59 +08:00
    session 里加 token
    具体可以搜 session 重复提交
    jwdstefanie
        12
    jwdstefanie  
       2016-12-07 13:55:27 +08:00
    重复提交 前台通过 ajax 提交的时候就可以过滤了 jquery 的 ajax 方法有个 gobal 属性建议看看
    honam
        13
    honam  
       2016-12-07 14:10:18 +08:00
    @xjp +1 ,锁的 key 根据请求参数来定,你有什么特别的实现相互交流交流
    twogoods
        14
    twogoods  
    OP
       2016-12-07 14:16:02 +08:00
    @ihuotui requestToken 过滤重复提交 能否给一个详细的思路
    tofishes
        15
    tofishes  
       2016-12-07 14:54:39 +08:00
    @jwdstefanie 数据完整性、安全性等不要依赖前端,必须后端解决。
    EthanLiao
        16
    EthanLiao  
       2016-12-07 17:28:07 +08:00
    @honam @xjp 具体的实现过程是怎样的,可否分享一下。
    tinyproxy
        17
    tinyproxy  
       2016-12-07 18:04:28 +08:00   3
    hoythan
        18
    hoythan  
       2016-12-07 18:22:11 +08:00
    requestID 年月日时分秒毫秒微妙纳秒+8 位随机数。
    frankerzeng
        19
    frankerzeng  
       2016-12-07 18:55:23 +08:00
    superrz
        20
    superrz  
       2016-12-07 18:59:13 +08:00
    从前端开始处理掉这个问题吧
    amey9270
        21
    amey9270  
       2016-12-07 19:08:17 +08:00
    这是一个 csrf 的问题啊
    iMouseWu
        22
    iMouseWu  
       2016-12-07 19:22:46 +08:00
    赞同 @phpman 观点,这个需要看业务场景。
    如果是重试的重复请求,可以通过一个业务 /逻辑唯一 Id 来避免重复提交
    还有一种是明显按钮已经灰显了,但是用户通过自己拼的 URL 来强行提交,就把它当做一次正常请求
    ihuotui
        23
    ihuotui  
       2016-12-07 20:42:05 +08:00 via Android
    @twogoods 先分析这个过程,因为网络原因,然后前端或者 app 的请求重复了,但是内容一样,所以在请求中增加一个唯一的请求码,然后后台对于记录这个用户的上一次请求码,然后对比,一样就抛弃。先分析原因,再思考解决,然后验证。
    rtx3
        24
    rtx3  
       2016-12-07 21:00:39 +08:00
    请求带有状态码?能将 session 独立出去在服务器端重新取得状态吗
    rtx3
        25
    rtx3  
       2016-12-07 21:02:24 +08:00
    弄错了 这个貌似要前段处理
    slixurd
        26
    slixurd  
       2016-12-07 21:29:44 +08:00   1
    这种不都是前端控制一下就完事的事情么...
    就拿创建订单来说,这个还能加锁?
    一个正常的流程就是:用户在购物车点击下单,那么前端应该就把按钮置灰,发送请求,如果请求超时 /失败,就重置按钮状态允许重新下单.
    没听说过要在后端做这个请求的去重的...
    也没办法判断这个请求是否重复....
    ElmerZhang
        27
    ElmerZhang  
       2016-12-08 09:47:17 +08:00
    前端在给后端 POST 数据之前,先到后端请求一个 uniqid , POST 数据时带上这个 uniqid ,后端对于 uniqid 相同的请求只处理一次。
    这个机制也可以用来防跨站、防刷
    KoleHank
        28
    KoleHank  
       2016-12-08 13:46:39 +08:00
    前端处理下就好了, underscore 都有类似的工具类方法提供,多长时间内的只执行一次的这种
    billowqiu
        29
    billowqiu  
       2016-12-08 23:31:50 +08:00
    避免重复请,貌似只能通过请求 ID 来区分了。
    如果是前端的重复点击,那么就要保证前端每次传递同一个请求 ID ;
    如果用户不走前端页面请求,直接发 URL 改变对应的 ID ,那么只能从后端处理,后端必须验证该 ID 是否有效。
    总结:
    最保险的就是请求 ID 由后端产生,后端收到请求时验证一下 ID 是否合法,是否重复。
    hobbyliu
        30
    hobbyliu  
       2016-12-09 06:13:26 +08:00 via Android
    @ElmerZhang +1 ,我们做过一个开放平台,用户下单的流程是: 1 、请求获取订单 id 接口。 2 、带上第一步的订单 id,请求下单接口,
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1383 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 55ms UTC 16:50 PVG 00:50 LAX 08:50 JFK 11:50
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86