2017-10-19 204 views
0

UPDATE:安装测试 - 它的作品 - 但我的主网络不能处理600封电子邮件大约6秒 - 我有每个连接等待20秒,然后发送一个邮件 - 这些全部通过PHP多个POST请求

去我有一个包含600多封电子邮件的邮件列表 我有一个功能可以发出600多封电子邮件

不幸的是,执行时间(90秒)有一个限制 - 因此脚本在它之前被关闭完成了。我不能改变时间set_time_limit(0),因为它是由我的网络主机(不是在我可以更改的ini文件中)设置的

我的解决方案是从主文件发出请求到子文件每次发送大量100封邮件。但是,它们是否会立即发送 - 或者在发送下一个请求之前是否等待答案?

代码:

for($i=0;$i<$mails;$i+100) { 
    $url = 'http://www.bedsteforaeldreforasyl.dk/siteadmin/php/sender.php'; 
    $myvars = 'start=' . $i . '&emne=' . $emne . '&besked=' . $besked; 

    $ch = curl_init($url); 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $myvars); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
    curl_setopt($ch, CURLOPT_HEADER, 0); 
    curl_setopt($ch, CURLOPT_SAFE_UPLOAD, 0); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 1); 

    $response = curl_exec($ch); 
    curl_close($ch); 
} 

$mails是受助总人数
$start是开始行号i的SQL语句

请问这个(我希望)开始6个并行连接 - 或它会(正如我担心的那样)每次都开始6次处理?

在接收脚本我有:

<br> 
ignore_user_abort(true);<br> 
$q1 = "SELECT * FROM maillist LIMIT $start,100 ORDER BY navn"; 
+0

我不是100%肯定,但它看起来像它就要开始6个procesesses – Tomm

+0

每个将等待对方完成 - 还是会同步? –

+0

我不敢回答这个问题我不确定 – Tomm

回答

1

我会提供有关目标如何实现的一些想法。

  1. 第一个选项 - 使用curl_multi_*功能套件。它提供了非阻塞cURL请求。

    2。第二个选项 - 使用异步库,如amphpReactPHP。尽管它基本上可以提供与curl_multi_*,IIRC相同的好处。

  2. 使用pcntl_fork()创建单独的进程并在工作节点中分配作业。

  3. 使用pthreads扩展,它基本上提供了真正的多线程的用户级PHP实现。

我虽然警告你,最后两个选项应该是最后的手段,因为并行处理世界上来,可以证明是真的讨厌;-)一些怪异的情况。

我也可能会建议你,如果你打算扩展这种应用程序,这将是使用某些外部服务的最佳行动方案。

+0

PHP中的多任务不一定非常困难。如我的答案所示,PHP可以使用stream_socket_client()将多任务工作传递给操作系统。 – Misunderstood

+0

我从来没有说过这很困难。我所说的只是平行处理的领域和所有的互斥锁都是同一个。 :-) – Ikari

1

创建六个php脚本,每100个电子邮件一个(或将值(例如0-5)传递给单个脚本)。
创建一个主脚本来调用这六个子脚本。

使用stream_socket_client()来调用子脚本。

这六个脚本将同时运行。
您可以捕获子脚本回显的任何内容(例如状态)。

$timeout = 120; 
$buffer_size = 8192; 
$result = array(); 
$sockets = array(); 
$id = 0;  
header('Content-Type: text/plain; charset=utf-8'); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail1.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail2.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail3.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail4.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail5.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail6.php"); 
foreach($urls as $path){ 
    $host = $path['host']; 
    $path = $path['path']; 
    $http = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n"; 
    $stream = stream_socket_client("$host:80", $errno,$errstr, 120,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); 
    if ($stream) { 
    $sockets[] = $stream; // supports multiple sockets 
    fwrite($stream, $http); 
    } 
    else { 
    $err .= "$id Failed<br>\n"; 
    } 
} 
echo $err; 

while (count($sockets)) { 
    $read = $sockets; 
    stream_select($read, $write = NULL, $except = NULL, $timeout); 
    if (count($read)) { 
    foreach ($read as $r) { 
     $id = array_search($r, $sockets); 
     $data = fread($r, $buffer_size); 
     if (strlen($data) == 0) { 
    // echo "$id Closed: " . date('h:i:s') . "\n\n\n"; 
     $closed[$id] = microtime(true); 
     fclose($r); 
     unset($sockets[$id]); 
     } 
     else { 
     $result[$id] .= $data; 
     } 
    } 
    } 
    else { 
// echo 'Timeout: ' . date('h:i:s') . "\n\n\n"; 
    break; 
    } 
} 
var_export($result);