cron是在php中编写基于提醒的应用程序的最佳方式吗?

时间:2018-02-18 19:55:49

标签: php laravel cron

假设我有这样的数据库。

void AES_CBC_encrypt_buffer(struct AES_ctx *ctx,uint8_t* buf, uint32_t length)
{
  uintptr_t i;
  uint8_t *Iv = ctx->Iv;
  for (i = 0; i < length; i += AES_BLOCKLEN)
  {
    XorWithIv(buf, Iv);
    Cipher((state_t*)buf, ctx->RoundKey);
    Iv = buf;
    buf += AES_BLOCKLEN;
    //printf("Step %d - %d", i/16, i);
  }
  /* store Iv in ctx for next call */
  memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
}

我希望用户在用户请求时(或者可能在一小时前)向用户发送提醒通知,并在触发提醒通知的特定时间执行其他一些代码块。 / p>

我正在考虑写一个像这样的cron工作

| task | time | |---------------------------|---------------------------| | Remind me to water plants | 2018-02-18T19:32:10.486Z | | English Test | 2018-10-8T09:30:00.000Z | | Math Test | 2018-10-8T10:30:00.000Z |

如laravel文档(https://laravel.com/docs/5.6/scheduling)中所述。

在该脚本中,我将在下一小时内循环播放当前时间提醒和提醒并执行操作。

这是一个好习惯吗?不会增加PHP和数据库之间的流量吗?如果我在同一时间内有很多提醒,循环到那个并执行代码块foreach提醒会是一个好主意怎么办?

请提出建议

2 个答案:

答案 0 :(得分:4)

使用task scheduler是解决此问题的正确方法。如果您要处理大量提醒,则建议将其设置为以queued jobs执行,这是推荐的方法。这样,服务器上的负载就会最小化,并且不会阻碍系统进行用户流量。

您可能希望创建一个console command来处理处理逻辑并创建作业。 Chunking这些工作也会有所帮助,因为这将错开特定批次中处理的工作数量。

答案 1 :(得分:0)

很久以前我对SMS(文本)消息系统有同样的问题,我选择在cron使用我自己的cron脚本时间表。 在我的PHP脚本中,我阻止它被浏览器调用,我在follow shell脚本中添加了我想要的PHP服务数量。 为了保证一切安全,每个PHP服务都需要一个小令牌才能运行,所以,只有在您有权访问源代码时才会注意到。

#!/bin/sh
#
# (c) 2016 por Marcello Fontolan
#
PATH=$PATH:/sbin:/usr/sbin
export PATH
LOCKFILE=/tmp/${0##*/}.lock

if [ ! -e $LOCKFILE ]
then
        touch $LOCKFILE
        cd ${0%/*}
        php movimentocopia.php token
        php pedidocopia.php token
        rm $LOCKFILE -f
else
        echo lock file detected.
fi
exit

此刻我处理了一个不同的问题。 提供程序连接和响应时间会减慢文本消息的数量,因此我创建了一个PID Queued Spool。

这样的事情:

function execThis($c, $m) {
    $cmd = "nohup nice -n 10 /usr/bin/php -f execenvio.php {$c} {$m} >> /tmp/execenvio.log 2>&1 & echo $!";
    return intval(shell_exec($cmd));
}

while (count($pid) > NUMTASKS) {
    foreach ($pid as $kpid => $vpid) {
        $processState = NULL;
        exec('ps ' . $vpid, $processState);
        if (count($processState) < 2)
            unset($pid[$kpid]);
    }
}
$pid[] = execThis($vcliente->id, $vmensagem->id);

嗯,上面的代码是我当前系统的一部分,所以你只需要弄清楚如何适应你的需求。

问候