欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

群发短信和群发电邮的队列问题

程序员文章站 2022-03-31 22:12:38
...
最近要做群发短信和群发电邮的程序,因为某些限制,都是多次去请求响应的接口,达到群发的效果。

然后就出现了这样的问题:我需要给100个客户发电邮,接口的响应时间平均在2s,然后我的php需要对接口进行100次post操作,长达200s,然后页面就超时了……

在不改动PHP设置的前提下,如何解决这个问题?

我自己能想到两个方案:

  1. 每次post一个,然后页面跳转,就像国内某些开源程序生成静态页那样,每次只做一个小请求,比如10s可以完成五次post,然后跳转到新页面,传入start=10 start=15这样的参数,不断跳转跳转刷新刷新,最后完成这个任务。缺点是这样需要客户端一直守着浏览器……
  2. 把发送消息的任务存在数据库里,做一个send.php之类的文件,每次取一个或几个消息去发送,然后用crond或者计划任务每秒之行send.php检查有没有新任务,有的话就执行任务。

我想知道还有没有别的简单易行的方法,比如我曾经听说过rabbitMQ什么的,但是没弄明白。。。

回复内容:

最近要做群发短信和群发电邮的程序,因为某些限制,都是多次去请求响应的接口,达到群发的效果。

然后就出现了这样的问题:我需要给100个客户发电邮,接口的响应时间平均在2s,然后我的php需要对接口进行100次post操作,长达200s,然后页面就超时了……

在不改动PHP设置的前提下,如何解决这个问题?

我自己能想到两个方案:

  1. 每次post一个,然后页面跳转,就像国内某些开源程序生成静态页那样,每次只做一个小请求,比如10s可以完成五次post,然后跳转到新页面,传入start=10 start=15这样的参数,不断跳转跳转刷新刷新,最后完成这个任务。缺点是这样需要客户端一直守着浏览器……
  2. 把发送消息的任务存在数据库里,做一个send.php之类的文件,每次取一个或几个消息去发送,然后用crond或者计划任务每秒之行send.php检查有没有新任务,有的话就执行任务。

我想知道还有没有别的简单易行的方法,比如我曾经听说过rabbitMQ什么的,但是没弄明白。。。

放在后台任务执行是一个好办法,应该也是最好的方法,不需要rabbitMQ,这只会让问题复杂化。但实际上有个方法可以让你的php不超时,即使用户浏览器连接断开了,它也会继续执行下去,那就是在你的php文件最开始加上以下两行

ignore_user_abort(true);
set_time_limit(0);

rabbitMQ和你提供的第二种方案类似,唯一不同的就是,你的方案需要不断的扫描任务表,数据量大的情况下,负载会很高,效率比较低。
使用rabbitMQ的话就是有任务你就处理,就是常说的消息驱动。消息驱动这项技术在需要异步处理的程序中很常见。属于一种高效的方案。你可以独立出一个任务系统,专门来处理需要异步处理比较耗时的业务,像邮件的发送,文档、视频的转换,图片的处理等等。这个方案其实很清晰,很简单。
希望能给你带来参考。

我现在的做法是这样的。用其他语言,如:.NET写一个邮件队列服务。然后PHP用SOCKET的方式POST但是不等待。剩下的事情交给.NET那边来做。

需要考虑的因素是:
1. 对及时性要求高不高?
2. 什么情况下触发需要群发 EMAIL 的动作?

方案一: 先把请求收集入库, 每一个页面请求的时候处理一个请求, 分发式处理, 适合一般的 web 应用, 不清楚你的状况, 如果是每一个页面请求都需要触发群发 EMAIL 的动作的话 ... ;

方案二: 如果对及时性要求不高的话, 可以系统工具如 cron , 首先把请求收集起来入库, 写一个处理请求的脚本, 在凌晨的时候服务器负载不高的情况下利用 cron 执行此脚本.

在2的方案里面,如果量不大是没问题的,
如果量大了,还是得考虑基于消息队列(mq,redis),在后台多个消费程序同时消费(发送)
我们系统每天百万的短信发送基本就是这么做!