V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
AZZERO
V2EX  ›  问与答

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

  •  
  •   AZZERO · 2019-04-22 09:19:52 +08:00 · 3156 次点击
    这是一个创建于 2076 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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


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

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