2014-05-23 4 views
2

Недавно я решил использовать Mandrill для отправки писем. Мне нужно будет отправить около 30 000 электронных писем сразу, и я думал, что пакетная отправка с Mandrill может позаботиться об этом, однако, когда я проверяю журналы API на сайте Mandrill, каждое отправленное письмо отображается как отдельный вызов API (время вызова в 200 мс). Статус результата для каждого отправленного сообщения равно «отправлен».Отправка писем с помощью Mandrill. Async не работает

Из того, что я мог собрать, когда есть более 10 получателей, он должен работать асинхронно, а статус должен быть «поставлен в очередь».

Я отправляю около 600 электронных писем прямо сейчас, а скрипт CRON занимает около 7 минут для выполнения. Это слишком долго.

Вот код:

public function getSendEmails() 
{ 
    \Log::info('get-send-emails (start)'); 
    $tasks = $this->task->where('published_at', '>', date('Y-m-d', time()))->whereNotNull('published_at')->get(); 
    foreach ($tasks as $task) 
    { 
     $users = $this->user->where('task_id', $task->id) 
      ->where('allow_emails', 1) 
      ->where('activated', 1) 
      ->get(); 
     $users_array = array(); 
     foreach ($users as $user) 
     { 
      $users_array[] = array(
       'email' => $user->email, 
       'name' => $user->first_name . ' ' . $user->last_name, 
       'type' => 'to' 
      ); 
     } 
     if (!empty($users_array)) 
     { 
      $html = View::make('emails.notifications.task')->with('task', $task)->render(); 
      $batches = array_chunk($users_array, ceil($users->count()/1000.0)); 
      foreach($batches as $batch) 
      { 
       try 
       { 
        $mandrill = new \Mandrill('some API key'); 
        $message = array(
         'html' => $html, 
         'subject' => 'Some Subject!', 
         'from_email' => '[email protected]', 
         'from_name' => 'Some Name', 
         'to' => $batch, 
         'preserve_recipients' => false 
        ); 
        $async = true; 
        $result = $mandrill->messages->send($message, $async); 
       } 
       catch(\Mandrill_Error $e) 
       { 
        echo 'A mandrill error occurred: ' . get_class($e) . ' - ' . $e->getMessage(); 
        throw $e; 
       } 
      } 
     } 
    } 
    \Log::info('get-send-emails (end)'); 
} 

Может сказать, у меня, если я делаю что-то неправильно или это, как долго он должен взять?

+0

Ваш код выглядит хорошо. Что я могу вам посоветовать, нужно активировать отладку (внутри отладки Mandrill.php отложить до истины), а затем проверить внутри вашего журнала php_error, чтобы узнать, сколько времени занимает каждый запрос. По возвращении вы можете связаться с Mandrill для получения дополнительной информации. – yvan

ответ

3

Похоже, вы разбиваете массив на куски очень немногих получателей. Если предположить, что у вас есть 10 пользователей (так $users->count() 10), вы устанавливаете пакетные размеры в 1 с этой линией, так как ceil(10/1000.0) возвращает 1:

$batches = array_chunk($users_array, ceil($users->count()/1000.0)); 

Даже с 30K получателей, вы бы настройки каждой партии для 30 получателей (так еще относительно небольшие партии). Вероятно, вы хотите изменить это на что-то подобное, чтобы каждая из партий получала 1000 получателей:

$batches = array_chunk($users_array, 1000); 
+0

Да, я только что понял это несколько минут назад. Благодаря! :) – seawhale

+0

Привет, просто быстрый вопрос, сделав это так, и скажем, что у вас было 30k получателей, разбитых на партии по 1000. С сохранением получателей установлено значение false и синхронизация установлена ​​в true, будет ли она отправлять 30 писем с 1000 получателей скрытых друг другу или отправит 30 000 индивидуальных писем? –

Смежные вопросы