wp_mail очень медленно

У меня вопрос о функции wp_mail (). Прямо сейчас у меня есть следующая кнопка для отправки электронной почты:

echo '<input type="submit" name="send_button" value="verzenden" id="'.$post_id.'" class="send_post">'; 

который запускает запрос jQuery:

 jQuery(document).ready(function() { jQuery(".send_post").click(function() { var post_id = $(this).attr('id'); jQuery.ajax({ async: false, type: 'get', url: nieuwsbrief.sendmail_url, data: 'postid=' + post_id, success: function(data) { alert(data); return false; } }); }); }); 

jQuery отправляет запрос sendmail.php . Что включает в себя следующее:

 <?php include_once $_SERVER['DOCUMENT_ROOT'] . '/www/wordpress/wp-config.php'; include_once $_SERVER['DOCUMENT_ROOT'] . '/www/wordpress/wp-load.php'; include_once $_SERVER['DOCUMENT_ROOT'] . '/www/wordpress/wp-includes/wp-db.php'; global $wpdb; $subscribers = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM wp_nwsbrf_subscribers INNER JOIN wp_nwsbrf_couple INNER JOIN wp_nwsbrf_categories INNER JOIN wp_posts WHERE wp_nwsbrf_subscribers.category_id = wp_nwsbrf_categories.category_id AND wp_nwsbrf_couple.category_id = wp_nwsbrf_categories.category_id AND wp_nwsbrf_subscribers.category_id = wp_nwsbrf_couple.category_id AND wp_posts.ID = wp_nwsbrf_couple.ID AND wp_nwsbrf_couple.ID = %d", $_GET['postid']) ); foreach ($subscribers as $subscriber) { $to = $subscriber->subscriber_mail.","; $title = $subscriber->post_title; $message = $subscriber->post_content; wp_mail($to, $title, $message); } ?> 

Как вы можете видеть, почта должна быть отправлена ​​в sendmail.php (url: nieuwsbrief.sendmail_url ). Но когда я нажимаю на send_button, для отправки электронной почты требуется несколько минут (3 или 4) !? Что я здесь делаю неправильно?

Спасибо, что помогли мне!

Solutions Collecting From Web of "wp_mail очень медленно"

Что я здесь делаю неправильно?

Многие, многие вещи, не все связанные с производительностью. Давайте начнем с критических частей, затем сделаем вывод о ваших проблемах с производительностью и о том, что можно сделать для смягчения и помощи

API AJAX

Во-первых, вы не используете API AJAX и не изобретаете колесо. Это довольно просто:

JS:

 $.post( do_mail_sending.ajaxurl, { action: 'do_mail_sending', post_id: post_id }, function(response) { alert( response ); }); 

PHP:

 wp_localize_script( 'do_mail_sending', 'do_mail_sending', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); add_action( 'wp_ajax_do_mail_sending', 'do_mail_sending' ); add_action( 'wp_ajax_nopriv_do_mail_sending', 'do_mail_sending' ); // and for logged out users function do_mail_sending() { $post_id = $_POST['post_id']; die( 'response data' ); } 

Закрытие тега PHP и трейлинг-пространства

PHP можно использовать как язык сценариев, но вы ввернулись в разработку приложений, поэтому я бы рекомендовал не иметь закрывающий тег PHP в конце документа. Ваш фрагмент кода выше делает это, и после этого у него появляется новое пространство разрыва строки, что может вызвать проблемы.

Безопасность

Казалось бы, хотя вы выполняете инструкцию подготовки, ни разу не проверяете, действительно ли пользователю разрешено это делать.

Например, я могу нагрузить всех ваших подписчиков и сбить ваш сервер с помощью следующего фрагмента javascript:

 while ( true ) { jQuery.ajax({ async: false, type: 'get', url: nieuwsbrief.sendmail_url, data: 'postid=' + post_id, success: function(data) { return false; } }); } 

Вы не проверяете это:

  • пользователь вошел в систему
  • пользователь имеет необходимые роли и возможности
  • что запрос пришел с вашего сайта
  • что запрос пришел со страницы с формой отправки электронной почты
  • использовать nonces
  • убедитесь, что сама почта существует

Представление

Ваши беды в производительности – результат того, что вы делаете. А именно:

  • Дорогие SQL-запросы, включая несколько соединений
  • Отправка сообщения электронной почты

И то, и другое по своей сути дорого, и последнее, что вы делаете много. Сама по себе электронная почта является дорогостоящей для отправки по серверу, поскольку она должна обращаться к SMTP-серверу и вести переговоры, а любые удаленные запросы потребуют времени.

Этого мало можно сделать, чтобы избежать этих расходов, поскольку основные части, которые делают это, по своей сути являются дорогостоящими.

Но все в порядке. Вы не первый человек, который должен сделать что-то дорогое, поэтому ваша цель должна быть смягчением и редизайном. Вы не можете снизить стоимость процесса, но вы можете изменить процесс, чтобы он быстро появлялся для пользовательского интерфейса, и все еще делается. Банки решили это в первые дни, выполняя жесткое число хруст в ночное время, в то время как филиал закрывался в сериях.

Вот несколько способов смягчения этого:

  • Разделите процесс на несколько этапов, вместо одного запроса AJAX, выполните несколько, 1, чтобы подсчитать, сколько писем нужно отправить, а затем несколько раз, используя технику стиля поискового вызова, чтобы отправить их партиями по 10 или 20 в зависимости от ваших серверов время отклика.
  • Не отправляйте электронные письма вообще, вместо этого подсчитайте, какая работа должна быть выполнена, а затем сохраните ее в базе данных как задачу, которая должна выполняться. Затем выполните задание cron с регулярным интервалом, который отправляет электронные письма в фоновом режиме.
  • Добавьте заметки в очередь сообщений электронной почты, которые нужно отправить, и отправьте их по одному, удалив элемент из очереди. Ваш информационный бюллетень не может быть отправлен сразу, но он будет отправлен, и он не принесет ваш сервер, пока это произойдет. Он также позволяет вам создать страницу состояния, показывающую ход рассылки в реальном времени.

Примечание к данным

То, что вам нужен оператор SQL, как это заставляет меня задаться вопросом, если ваша таблица категорий и запрос не могут быть заменены пользовательской таксономией и вызовом WP_Query . Таким образом, вы можете воспользоваться встроенным кэшем объектов и запросов

В моем случае wp_mail () занял более 90 секунд в рассылке по электронной почте, приведя мой сайт к обходу. Полностью забыл исправить конфигурацию / etc / hosts для моего сайта, в соответствии с приведенными ниже инструкциями, теперь sendmail составляет <3 секунды.

https://www.digitalocean.com/community/questions/sendmail-is-slow-to-send-mail

Если вы проверите свой /var/log/mail.log, вы, скорее всего, найдете что-то вроде этого: Неизвестное имя хоста (localhost); спать для повторных попыток. Это связано с тем, что для sendmail требуется «имя хоста» как полное доменное имя. обновите файл «/ etc / hosts»: nano / etc / hosts выглядят следующим образом: 127.0.0.1 localhost.localdomain localhost yourhostname boom, fast sendmail.