Реализация уведомления по электронной почте
У меня есть веб-приложение, в котором пользователи могут создавать темы, а также комментировать другие темы (аналогично тому, что мы имеем здесь в stackru). Я хочу иметь возможность отправлять уведомления участвующим пользователям обсуждения.
Я знаю, что самый простой способ сделать это - подключить уведомление к сценарию, выполняемому, когда пользователь взаимодействует с обсуждением. Хотя это кажется очень простым, я считаю, что это не самый подходящий способ, поскольку пользователю нужно будет ждать, пока все электронные письма-уведомления (скрипт уведомлений завершает выполнение), пока он не получит статус своего действия.
Другая известная мне альтернатива - это планирование выполнения скрипта уведомлений с помощью cronjob. Чтобы уведомление было релевантным, сценарий будет выполняться каждые 3–7 минут, чтобы пользователи могли получать уведомления в разумные сроки.
Теперь я обеспокоен тем, потребует ли настройка cronjob запуска скрипта каждые 3 минуты разумный системный ресурс, учитывая, что мое приложение все еще работает на платформе общего хостинга?
Кроме того, я думаю, возможно ли иметь сценарий, в котором сценарий комментария будет запускать или уведомлять сценарий уведомления для отправки уведомлений на указанные адреса электронной почты, в то время как сценарий комментария продолжает выполняться, не дожидаясь завершения сценария уведомления. Если это может быть достигнуто, то я думаю, что это будет лучшим выбором для меня.
Большое спасибо за уделенное время.
3 ответа
Если ваш сценарий уведомлений не требует значительных ресурсов и отправляет десятки или сотни сообщений при каждом запуске, я бы не стал беспокоиться о его планировании каждые 3-7 минут на общем хосте. Действительно, если вы запланировали это на 3 минуты и обнаружили снижение производительности на своем сайте, то увеличьте его до 4 минут для сокращения ресурсов на 25%. Это вряд ли проблема, хотя.
Что касается запуска фонового процесса, вы можете достичь этого с помощью системного вызова exec()
, Я бы направил вас на этот вопрос за отличный ответ.
IMO, добавляющий "крючок" к каждому "взаимодействию обсуждений", безусловно, является самым чистым подходом, и один из способов избежать ожидания пользователей - это отправить заголовок Content-Length в ответе HTTP. HTTP-клиенты с хорошим поведением должны считывать указанное число октетов и затем закрывать соединение, поэтому, если вы отправите обратно свой ответ "status" с соответствующим HTTP-заголовком Content-Length (и установите ignore_user_abort), тогда конечный пользователь не будет обратите внимание, что ваш серверный скрипт на самом деле продолжает свой веселый путь, генерируя уведомления по электронной почте (возможно, даже в течение нескольких минут) перед выходом.
Я не уверен, что согласен с подходом, согласно которому отправка электронных писем в том же процессе, который обслуживает запрос, - это путь. Как правило, лучше сохранять простоту; обслуживайте запрос как можно быстрее, и пусть фоновые процессы выполнят всю тяжелую работу. Когда трафик увеличивается, а ваши серверы загружаются, этот подход сокращает время ожидания и делает пользователей счастливее. Это также поможет отделить ваши проблемы, которые помогут вам исправить ошибки и рефакторинг позже.
Лично я бы создал скрипт, который периодически запускается в фоновом режиме и проверяет все потоки на наличие новых действий. Если у потока есть новое действие, то сценарий может отправлять уведомления по электронной почте всем участникам. Это отделяет вашу логику отправки электронных писем от логики, используемой для обслуживания запросов, а также физически разделяет их - например, если ваш SMTP-сервер внезапно начинает отвечать на запросы, это не окажет сдерживающего влияния на время ответа на ваш запрос. Кроме того, если в часы пиковой нагрузки ваш сервер слишком загружен, вы можете просто прекратить запуск этого сценария и позволить серверу сосредоточиться на обслуживании запросов.
Чтобы запустить этот скрипт, вы, конечно, можете просто использовать CRON, и, как предлагается, запускать его каждые 4 минуты. Однако что делать, если сценарий занимает больше 4 минут? В конечном итоге вы получите два сценария, выполняющихся одновременно, что может привести к тому, что некоторые пользователи отправят одно и то же письмо дважды. Одним из решений этой проблемы было бы использование Fat Controller - демона, который я написал на C, который может периодически запускать любой скрипт (PHP, Python, что угодно) - это в основном демонизатор для всего. Важно отметить, что он может запустить новый экземпляр через x секунд после завершения предыдущего экземпляра, поэтому вам никогда не придется беспокоиться о нескольких экземплярах.
Fat Controller очень настраиваемый и может работать во всех режимах и даже обрабатывать несколько параллельных процессов. Вы можете прочитать больше об этом и некоторых случаях использования на веб-сайте: