V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
AZZERO
V2EX  ›  问与答

请问 PHP 里 sleep 能不能 sleep 5min?

  •  
  •   AZZERO · Apr 22, 2019 · 3817 views
    This topic created in 2571 days ago, the information mentioned may be changed or developed.

    我现在想实现一个功能,功能是这样的:

    用户在关注微信服务号 5 分钟后 ,判断他有没有在服务号的 h5 网页里付款, 如果没有付款,就在服务号里自动发送一条客服提醒消息给这个用户,催促他行动

    现在有一个 php 库叫 easywechat,当用户在服务号触发各种行为的时候,很容易去实时自动回复,

    但我如果想五分钟后回复,是不是用 php 的 sleep 5min 来暂缓执行发送客服消息的命令吗 但这样如果多个用户同时进来,会不会服务器内存爆掉,

    还是说要把用户的 openid 存到数据库里,再做,但是这样太复杂了,作为计算机二级代码水平的我来说,有点困难


    easywechat 文档: https://www.easywechat.com/docs/4.1/official-account/messages

    24 replies    2019-04-22 14:47:59 +08:00
    agdhole
        1
    agdhole  
       Apr 22, 2019
    放到队列
    xh520630
        2
    xh520630  
       Apr 22, 2019
    sleep(300) 应该可以吧 但是用在这种地方还是觉得怪怪的...
    PHPJit
        3
    PHPJit  
       Apr 22, 2019
    延时队列
    zy445566
        4
    zy445566  
       Apr 22, 2019
    不行,你的 work 池很快就会被占满,你自己 ab 下就知道了。node 就可以,就是 sleep 可能会有几秒钟偏差
    AZZERO
        5
    AZZERO  
    OP
       Apr 22, 2019
    @agdhole 谢谢解答 队列对我来说还是太复杂了,
    如果不判断付款,仅仅在新用户关注 5min 后推送一条客服消息,有没有更简单的方式呢
    guyujiezi
        6
    guyujiezi  
       Apr 22, 2019
    Takahashi
        7
    Takahashi  
       Apr 22, 2019
    swoole 对你来说应该还是比较难上手的。。你可以考虑再写个脚本做一个 crontab 来检查是否付款,sleep5 分钟会炸
    C603H6r18Q1mSP9N
        8
    C603H6r18Q1mSP9N  
       Apr 22, 2019
    放到数据库,然后每 10s 跑下
    triptipstop
        9
    triptipstop  
       Apr 22, 2019
    PHP 里 或者说 Web 里 所有不能秒级完成的事情 都要放队列里跑 你这个需求延时队列是最适合的方案
    wuqingdzx
        10
    wuqingdzx  
       Apr 22, 2019
    看你的提问,队列显然对你难度过高。
    1.写个 php 脚本通过 supervisor 常驻后台( supervisor 相当容易)
    2.写个 php 脚本加入 crontab 每分钟执行一次
    以上都需要你把用户信息写入数据库。
    web 服务 sleep 5min 早 down 掉本次 request 了
    graetdk
        11
    graetdk  
       Apr 22, 2019
    把用户关注时间和付款否放在数据库里,然后写个脚本定时查询一下数据库,5 分钟前未付款的发一次通知即可,记得发完通知了标记一下状态
    miao666
        12
    miao666  
       Apr 22, 2019 via iPhone
    定时任务,每分钟执行一次判断代码。
    Sor
        13
    Sor  
       Apr 22, 2019
    如果你使用了 Laravel 框架 可以使用事件去处理这件事情,如果没有可以参考其中的实现思路,异步队列是最好的解决办法
    loveCoding
        14
    loveCoding  
       Apr 22, 2019
    不如存到数据库里面 , 比如 10s 刷一次任务.
    sun019
        15
    sun019  
       Apr 22, 2019
    计划任务或者队列
    mscb
        16
    mscb  
       Apr 22, 2019 via Android
    你或许可以设置一下你的服务器,实现 5S 响应而不超时,但是没法保证微信读的时候能请求的时候,5S 不判断为读超时啊。所以还是放到队列里,自己轮询主动推送消息吧。队列不会的话,用数据库也可以曲线救国
    Vegetable
        17
    Vegetable  
       Apr 22, 2019
    两个问题.
    第一,睡眠 5 分钟会消耗大量的资源.
    第二,公众号自动回复有超时,只有几秒钟.你不回复就会出现该公众号当前无法提供服务的提示给用户,会话会断掉.
    liujan
        18
    liujan  
       Apr 22, 2019
    wengjin456123
        19
    wengjin456123  
       Apr 22, 2019 via Android
    使用队列去操作这个比较好吧
    echoZero
        20
    echoZero  
       Apr 22, 2019
    延迟队列吧 beanstalk 延迟 5 分钟然后处理 可以不用存储到数据库
    ferock
        21
    ferock  
    PRO
       Apr 22, 2019 via iPhone
    5 分钟以后给用户公众号里推送消息本身就不允许… 除非用户和你主动交互
    keepeye
        22
    keepeye  
       Apr 22, 2019
    1. 你直接在请求中 sleep,等于这个请求一直无法结束直到超时。
    2. php 是多进程处理请求,一个请求进来到结束过程中一直独占一个进程,那么很快所有进程都被 sleep 阻塞导致无法处理新的请求。
    3. web 中不要用 sleep,你可以把这个用户 openid 随便记到文件、redis 或者数据库中,另外单独写一个脚本用 cli 模式去轮询处理,cli 下你随便 sleep
    phpcxy
        23
    phpcxy  
       Apr 22, 2019
    延时队列,5 分钟后用客服消息接口发消息给用户。
    ashin
        24
    ashin  
       Apr 22, 2019
    队列复杂就用 crontab 扫啊
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   908 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 79ms · UTC 21:53 · PVG 05:53 · LAX 14:53 · JFK 17:53
    ♥ Do have faith in what you're doing.