wp почта очень медленная


У меня есть вопрос о функции 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)!? Что я здесь делаю не так?

Спасибо за помощь меня вон!

Author: Tom J Nowell, 2013-05-29

2 answers

Что я здесь делаю не так?

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

AJAX API

Во-первых, вы не используете 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 в конце документа. Приведенный выше фрагмент кода делает это, и после этого в нем появляется новый пробел для разрыва строки, что может вызвать проблемы.

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

Похоже, что, хотя вы выполняете инструкцию prepare, вы ни разу не проверяете, действительно ли пользователю разрешено это делать.

Например, я могу затопить всех ваших подписчиков и вывести ваш сервер из строя с помощью следующего 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-сервером и провести переговоры, а любые удаленные запросы потребуют времени.

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

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

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

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

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

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

 5
Author: Tom J Nowell, 2013-05-29 12:26:20

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

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

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

 4
Author: Billy Fisher, 2014-09-03 05:37:09