Foreach 函数给出 503 Service Unavailable

Posted

技术标签:

【中文标题】Foreach 函数给出 503 Service Unavailable【英文标题】:Foreach function gives 503 Service Unavailable 【发布时间】:2018-02-24 00:33:50 【问题描述】:

现在是凌晨 1 点,我挣扎了 3-4 个小时,看看我的脚本出了什么问题...

我的数据库有大约 400 封电子邮件。我将$ChunkSize 设置为循环的计数器,并计算下一个要处理的块。

我设置了一些echo() 来调试

echo "This is the " . $GLOBALS["ChunkSize"] . " chunk. <br>";

它应该输出当时处理了什么块。 如果我禁用 mail(),那么我不会得到 503 Service Unavailable,但每个 echo() 都会同时显示,而不是按处理顺序显示。

我还发现有一些电子邮件到达,但不是每个人都收到。此外,如果发送了一些电子邮件,这意味着foreach() 应该已经处理了至少一个块,这意味着它应该至少显示一个echo()

我已经设置了break 1;,所以每次它突破foreach()时,它应该显示echo()foreach()处理的块号,但它没有。

我做错了什么?

$connection = mysql_connect($hostname, $username, $password);
mysql_select_db($dbname, $connection);
$result = mysql_query("SHOW COLUMNS FROM `Emails`");
while($row = mysql_fetch_array($result))
$Addresses[] = $row['Field'];
$Subject = "Test";
$Message = "
Test
";
$Headers = array( EMPTY FOR SECURITY REASONS );
$Headers = implode( "\r\n" , $Headers );
$ChunkAddresses = 50;
$EmailChunkArray = array_chunk($Addresses, $ChunkAddresses);
$ArraySize = count ($EmailChunkArray);
$ChunkSize = 0;
ChunkLoop: 
    $EmailChunkArrayLoop = $GLOBALS["EmailChunkArray"];
    foreach ($EmailChunkArrayLoop[$GLOBALS["ChunkSize"]] as $ToChunkLoop) 
        if ($GLOBALS["ChunkSize"] <= $GLOBALS["ArraySize"]) 
            mail($ToChunkLoop,$GLOBALS["Subject"],$GLOBALS["Message"],$GLOBALS["Headers"]);
            echo "This is the " . $GLOBALS["ChunkSize"] . " chunk. <br>";
         else if ($GLOBALS["ChunkSize"] == $GLOBALS["ArraySize"])
            exit();
        $GLOBALS["ChunkSize"]++;
        break 1;

if ($GLOBALS["ChunkSize"] != $GLOBALS["ArraySize"])
    echo "Test. <br>";
    goto ChunkLoop;
 else 
    echo "Finished! <br>";

【问题讨论】:

@SumutiuMarius 我怀疑您在脚本中到达了max_execution_time(通常是 5 分钟,请检查您的 php 设置),也许可以考虑在命令行中运行它 没有人通过面向 Web 的脚本发送一批邮件。编写将检查某些操作队列并完成您的工作的 cli 脚本。发送邮件不是那么快的操作。 @SumutiuMarius 好的,您只有网络托管。所以解决方案很少:1. 使用mailgrid 服务 - 将您所有的邮件推送给他们,不要考虑复杂的事情,2. 使用mailchimp 服务 - 它是mail subscription system,您推送邮件文本并发送您的邮件给订阅者, 3. 有大量的服务可以为您的需要提供免费的专用服务器实例:DigitalOcean(优惠券代码:DROPLET10)、HerokuC9 以及更多,如果您搜索互联网。如果企业想要赚钱 - 企业必须将资金浪费在技术上。 @SumutiuMarius 请记住 - 开发人员的时间是昂贵的资源,而不是可以购买以加快进度的技术。你在这个问题上浪费了 1 到 2 天,而你可以浪费 1 小时来使用正确的服务/工具,这些服务/工具会被客户购买并迅速切换到另一个有利可图的任务。 @SumutiuMarius 在 DigitalOcean 中的最小液滴是 5 美元,使用优惠券代码 DROPLET10 您可以获得 10 美元的奖金,并有 2 个月的免费。还使用mailchimp、mailgrid——都提供免费的批量邮件发送、邮件订阅服务。我还可以告诉您以下内容:创建只会发送电子邮件并使用进程分叉技术在后台异步调用该脚本的 php 脚本 (electrictoolbox.com/article/php/process-forking) 或使用 pthreads (mullie.eu/parallel-processing-multi-tasking-php) 或使用 nohup (@ 987654323@) 【参考方案1】:

创建只会做一件事的脚本 - 发送邮件。

sendMail.php

<?php

// Get recipient from the argv array
$recipient = $_SERVER['argv'][1];

// Mail args
$subject = 'HELLOOOOOOO';
$message = 'BLablabla';
$headers = [...]; // optional or not

// Send it
mail($recipient, $subject, $message, $headers);

在你做的代码里面:

mail($ToChunkLoop,$GLOBALS["Subject"],$GLOBALS["Message"],$GLOBALS["Headers"]);

替换为:

$recipient = escapeshellarg($ToChunkLoop);
exec("php /path/to/sendMail.php ".$recipient." > /dev/null &"); // that will call mail script and will not wait when execution will end

随意调整我的代码示例,如你所愿 附言此解决方案适用于您不想为正常的批量邮件发送、邮件订阅或专用 vps 服务付费并且只有小型虚拟主机的情况。 (: P.S.. 这不是一个出色的解决方案,而是针对问题作者提供的要求完成的

【讨论】:

@SumutiuMarius 我很高兴它正在工作。但请记住要减少噪音 - 不要一次发送 50 个,最好在每次通话之间暂停 100 毫秒 sleep(100000)。否则邮件服务器可能会认为脚本是垃圾邮件等等。 一次不会发送 50 个。这是每个块中的电子邮件数量,但 foreach 为块中的每封电子邮件执行 SendMail.php,或者至少这是我所理解的。 我认为你的意思是usleep() 因为sleep(100000) 意味着27 小时:) 我可以通过exec()发送更多数组吗?例如:exec("php /SendMail.php ".$Receiver. , .$AnotherArray." &gt; /dev/null &amp;") 我进行了编辑。我想你能看看我修改了什么。我不是 PHP 专家,不确定我所做的是否好。我通过exec() 导出了整个电子邮件块,并在SendMail.php 文件中设置了foreach(),因此mail() 将为exec() 发送的块中的每个数组执行。

以上是关于Foreach 函数给出 503 Service Unavailable的主要内容,如果未能解决你的问题,请参考以下文章

Jetty 显示 http 错误消息 503 SERVICE_UNAVAILABLE

WSGISocketPrefix 无法解决 503 Service Temporarily Unavailable 错误

503 Service Temporarily Unavailable

(a)Smack 在 login() 处返回“service-unavailable (503)”错误

HTTP Error 503. The service is unavailable

PHP 工作但 Laravel 不工作,返回 503 Service Unavailable