如何限制 PHP 每秒只执行一次? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yitalin
V2EX    PHP

如何限制 PHP 每秒只执行一次?

  •  
  •   yitalin 2022 年 7 月 16 日 4949 次点击
    这是一个创建于 1303 天前的主题,其中的信息可能已经有所发展或是发生改变。
    a.php 实际上每秒有 10 个 ip 同时访问,如何实现每秒只执行一个 ip 的请求,同一秒剩余 9 个的请求实际上代码是不执行的?
    想了半天找不到解题思路
    28 条回复    2022-07-18 13:28:52 +08:00
    em70
        1
    em70  
       2022 年 7 月 16 日
    修改 nginx 配置文件,把最大并发 IP 设为 1

    limit_conn perip 1
    ersic
        2
    ersic  
       2022 年 7 月 16 日 via Android   2
    换个思路,让每个执行都持续一秒。
    dangyuluo
        3
    dangyuluo  
       2022 年 7 月 16 日
    加锁和队列?
    xiangyuecn
        4
    xiangyuecn  
       2022 年 7 月 16 日
    @em70 #1 @ersic #2 严禁掩耳盗铃
    realpg
        5
    realpg  
    PRO
       2022 年 7 月 16 日
    这还用思路?

    首先,多个请求,他们得有一个协商的地方,就是得有个公共的地方能存储状态
    数据库,redis,memcache,或者 shmem
    然后按秒做标志,考虑好锁存机制
    或者利用关系数据库的一些特性去做,比如利用 mysql 的 unique 索引实现天然锁
    zjsxwc
        6
    zjsxwc  
       2022 年 7 月 16 日 via Android
    用 mode 为 x 的 fopen 方式打开文件名为秒级时间戳的文件,
    这样再某一秒中只有第一个 fopen 能成功,

    https://www.php.net/manual/zh/function.fopen.php
    realpg
        7
    realpg  
    PRO
       2022 年 7 月 16 日
    @zjsxwc #6
    然后第一个打开成功,30ms 后 PHP 执行退出了,下一个又打开了?
    imdong
        8
    imdong  
       2022 年 7 月 16 日 via iPhone   1
    伪代码:
    if(!Redis::set(time())) return;
    zjsxwc
        9
    zjsxwc  
       2022 年 7 月 16 日 via Android
    @realpg
    执行完 sleep 1 秒,
    嘿嘿
    treblex
        10
    treblex  
       2022 年 7 月 16 日 via iPhone
    存一个时间戳,没过期之前都返回缓存结果,过期执行实际代码更新缓存
    ersic
        11
    ersic  
       2022 年 7 月 16 日
    redis 存一个 1s 过期的 key ,存在就不执行,不存在就执行,执行完继续存这个 key 。
    k9982874
        12
    k9982874  
       2022 年 7 月 16 日 via Android
    起消息队列,消费者一秒只处理一个
    vovov
        13
    vovov  
       2022 年 7 月 16 日
    php 的话可以用 laravel 的原子锁

    use Illuminate\Support\Facades\Cache;

    $lock = Cache::lock('foo', 1);

    if ($lock->get()) {
    // 锁定 1 秒...
    }
    GGGG430
        14
    GGGG430  
       2022 年 7 月 16 日
    public static function lock($key, $ttl)
    {
    return apcu_add($key, 1, $ttl);
    }
    misaka19000
        15
    misaka19000  
       2022 年 7 月 16 日
    漏桶算法

    想要简单点可以直接用 apisix 网关管理
    wonderfulcxm
        16
    wonderfulcxm  
       2022 年 7 月 16 日 via iPhone
    那不在这一秒执行的其他请求怎么处理,是直接返回 503 还是进入队列等待下一秒?
    cpstar
        17
    cpstar  
       2022 年 7 月 16 日
    我觉得 LZ 没想清楚的事情是,不是一秒钟内执行一个,而是每一秒钟怎么调配给不同的请求,是时间分配给请求,而不是请求来抢占时间。
    keepeye
        18
    keepeye  
       2022 年 7 月 16 日
    redis setnx ,过期时间设为 1 秒 setnx 返回 1 的那个执行,其他的不执行
    sutra
        19
    sutra  
       2022 年 7 月 16 日
    搜“限流”,有算法,也有解决方案。
    pengtdyd
        20
    pengtdyd  
       2022 年 7 月 16 日
    rxjs 可以做到,不过嘛这玩意学起来很难
    cszchen
        21
    cszchen  
       2022 年 7 月 16 日 via iPhone
    是期望“每秒”只有一个请求,还是同一个时间点只有一个请求。区别很大,解决的思路很简单。
    装个 redis ,获取原子锁,没有群的要等
    liyunlong5
        22
    liyunlong5  
       2022 年 7 月 17 日 via Android   1
    @em70 这个只是限制一个连接,真正限制请求要加上 limit req 1r/s
    rb6221
        23
    rb6221  
       2022 年 7 月 17 日
    加一层缓存就行了呗,一秒内的请求都走缓存
    hoopan
        24
    hoopan  
       2022 年 7 月 18 日
    php 进程池只开一个呢,为啥会有这种奇怪的需求,原始需求是啥?如果是防止并发出错,可以加锁。
    junwind
        25
    junwind  
       2022 年 7 月 18 日
    第一个 ip 访问进来写一个 session ,第一个进来,如果有这个值就 return ,没试过,不知道能否实现你的要求
    xuelu520
        26
    xuelu520  
       2022 年 7 月 18 日
    加锁就行了
    wolfie
        27
    wolfie  
       2022 年 7 月 18 日
    java 思路
    请求扔队列,根据 ip 分组。
    所有请求共用互斥锁,定义个守护线程循环 wait 、notify.
    tianyou666shen
        28
    tianyou666shen  
       2022 年 7 月 18 日
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1919 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 06:17 PVG 14:17 LAX 22:17 JFK 01:17
    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