V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yanluya
V2EX  ›  PHP

PHP 异步通知(微信通知,短信通知,邮件通知)怎么做?如果全部等待返回结果会卡死

  •  2
     
  •   yanluya · 2019-04-02 09:48:26 +08:00 · 7080 次点击
    这是一个创建于 2091 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在做 php 客户订单通知的功能,加入了微信通知,短信通知,邮件通知。可是时间一长,客户提交订单很慢,而且有时候会请求超时,必须用异步通知来,大家有好的解决方法吗?

    37 条回复    2019-04-14 16:49:04 +08:00
    blackjar
        1
    blackjar  
       2019-04-02 09:53:49 +08:00
    队列
    zjsxwc
        2
    zjsxwc  
       2019-04-02 09:55:52 +08:00 via Android
    单独跑个进程处理啊,最简单可以用 Jenkins 一个 jar 包搞定
    klgd
        3
    klgd  
       2019-04-02 10:03:37 +08:00
    消息队列,我们现在就是把消息通知放到 rabbitmq 上发的
    rxzxf1993
        4
    rxzxf1993  
       2019-04-02 10:08:23 +08:00
    swoole
    iSecret
        5
    iSecret  
       2019-04-02 10:10:21 +08:00
    队列,通知一类耗时的任务全部丢到 redis 一类的介质里,后台搞个脚本去执行。
    fuxkcsdn
        6
    fuxkcsdn  
       2019-04-02 10:10:44 +08:00 via iPhone
    标准答案上队列
    无脑方案,fastcgi_finish_request
    Moker
        7
    Moker  
       2019-04-02 10:11:30 +08:00
    php-resque PHP 队列的一个实现 基于 Redis List 也可以自己实现
    Light3
        8
    Light3  
       2019-04-02 10:11:57 +08:00
    队列 阿里云就有 其实就 redis 搞个队列 然后放进去 单独开一个进程 一直跑
    tomczhen
        9
    tomczhen  
       2019-04-02 10:17:44 +08:00 via Android
    laravel queues
    RyanOne
        10
    RyanOne  
       2019-04-02 10:20:16 +08:00
    简单一点的 fsockopen
    gabezhao
        11
    gabezhao  
       2019-04-02 10:52:04 +08:00
    swoole
    phpcxy
        12
    phpcxy  
       2019-04-02 10:52:35 +08:00
    队列
    xnode
        13
    xnode  
       2019-04-02 11:00:31 +08:00
    简单 fsockopen 标准 队列 其他的 Guzzle
    yanluya
        14
    yanluya  
    OP
       2019-04-02 11:10:00 +08:00
    队列应该是处理并发量大的订单和秒杀一类的商品比较好,像下单频率很低,有时一天才 2 单这样的,用队列会不会大材小用?
    chinvo
        15
    chinvo  
       2019-04-02 11:10:50 +08:00
    laravel/think queue
    lcy630409
        16
    lcy630409  
       2019-04-02 11:17:44 +08:00
    - -
    建一个表,然后定时执行,处理表中的通知,发送....
    简单 好维护,不需要其他的成本
    m939594960
        17
    m939594960  
       2019-04-02 11:17:59 +08:00
    @yanluya #14 不会,耗时任务 php 不用 swoole 类的东西 只能用队列
    codebear01
        18
    codebear01  
       2019-04-02 11:20:08 +08:00
    插到队列表,跑脚本处理
    yanluya
        19
    yanluya  
    OP
       2019-04-02 11:24:41 +08:00
    php 没有异步程序吗?像 Java 那种开线程池,跑线程??
    xnode
        20
    xnode  
       2019-04-02 11:29:06 +08:00
    @yanluya php 没有线程 只有异步函数
    jason56
        21
    jason56  
       2019-04-02 11:34:32 +08:00
    swoole +1
    jadec0der
        22
    jadec0der  
       2019-04-02 11:46:35 +08:00
    @yanluya 如果你一定想异步的话可以用 pcntl ( https://www.php.net/manual/en/book.pcntl.php) 开进程,但是这不是 php 的 best practice
    Felldeadbird
        23
    Felldeadbird  
       2019-04-02 11:49:07 +08:00
    将通知拆分啊,然后交给前端去触发。这样就不怕延时了。
    qiyuey
        24
    qiyuey  
       2019-04-02 11:49:41 +08:00
    MQ 啊
    sujin190
        25
    sujin190  
       2019-04-02 11:55:34 +08:00
    另外弄个小发送服务呗,用 grpc、thrift 啥的弄个也很快了,几分钟就搞定,单量少,也就不需要考虑那么多了,加到 supervisor 进程管理里,很简单了

    或者更简单的,另外写个接口发送通知,再用 fscokopen 构造一个 http 请求,但是不等待返回就是了
    archersgz
        26
    archersgz  
       2019-04-02 12:56:46 +08:00
    swoole
    mmixxia
        27
    mmixxia  
       2019-04-02 13:47:08 +08:00
    队列,定时检查,超时重发
    dorothyREN
        28
    dorothyREN  
       2019-04-02 14:16:09 +08:00
    那么这位老哥 短信接口要不要了解一下
    Dogergo
        29
    Dogergo  
       2019-04-02 14:38:16 +08:00
    这种通知,当然一开始就要考虑异步吧,我们之前是 go 脚本+redis 队列搞的,一直跑
    xman99
        30
    xman99  
       2019-04-02 14:44:09 +08:00
    其实不用那么高超的技术的

    把任务写入 redis,php 定时任务去消费就好。

    感觉这些都不能满足业务需求, 可以考虑下 入坑 swoole,swoole 坑不小。 如果考虑其他语言,go 是不错选择
    ducklyl
        31
    ducklyl  
       2019-04-02 15:57:32 +08:00
    插到队列表,跑脚本处理
    askfilm
        32
    askfilm  
       2019-04-02 16:50:06 +08:00
    感觉这些都不能满足业务需求, 可以考虑下 入坑 go,go 坑不小。 如果考虑其他方式,swoole 是不错选择
    askfilm
        33
    askfilm  
       2019-04-02 16:50:55 +08:00
    说到底, swoole 坑不小到底是啥? :)
    jamblues
        34
    jamblues  
       2019-04-02 23:27:10 +08:00   ❤️ 1
    扯语言,远了~

    容易且不靠 swoole 实现的方案

    前台:

    task - push list - Redis 队列

    后台:
    启动 php 长驻进程,pop 原子操作,可以视任务开多个。

    nohup php deamon.php > deamon.log &

    do {
    // redis 取任务
    task.lpop();
    // do task

    // 重载条件 or 中止条件
    } while(true);

    当然,这个方案也不是这么简单,
    如果只是发个邮件简单的 http 请求够用了。
    但如果要复杂的话,
    还要考虑像 mysql redis 这种长时间保持连接
    以及业务大了以后的内存控制,锁,单例维护,扩展性和灵活性等等。
    qianbi6
        35
    qianbi6  
       2019-04-11 16:16:21 +08:00
    我们用 swoole 发的。
    lhfdeamon
        36
    lhfdeamon  
       2019-04-13 00:08:19 +08:00 via Android
    短连接了解一下
    qY3209HZitEb5Zty
        37
    qY3209HZitEb5Zty  
       2019-04-14 16:49:04 +08:00
    给个 token 让前端异步去调用
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   882 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:04 · PVG 04:04 · LAX 12:04 · JFK 15:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.