2012-11-24 2 views
4

더 빠르고 가벼운 HTTP 응답을 위해 비동기 적으로 전자 메일을 보내려고하지만 많은 새로운 개념으로 어려움을 겪고 있습니다.전자 메일을 비동기 적으로 보내기 : 스풀, 대기열 및 cronjob/데몬

예를 들어, 설명서에서는 spool에 대해 설명합니다. 그것은 파일로 스풀을 사용하고, 명령으로 이메일을 보내야한다고 말합니다. 하지만 어떻게 그 명령을 실행해야합니까? 1 분마다 해당 명령을 실행하도록 cronjob을 설정하면 (최소 cron에서 사용 가능), 사용자는 전자 메일을 보내기 위해 평균 30 초 동안 기다려야합니다 (예 : 등록 전자 메일).

그래서 대기열을 대신 사용하려고 생각했습니다. 이미지 처리 (예 : 축소판 만들기)에 이미 RabbitMQBundle을 사용하고 있습니다. 하지만 이건 주기적으로 만 사용하기 때문에 cronjob에서 소모됩니다.

아마도 새 메시지가 전자 메일 대기열에 도착하여 최대한 빨리 배달되기를 기다리는 daemon을 만들어야합니까?

+0

30 초 지연의 문제점은 무엇입니까? 그것은 당신이 말한 것과 정확히 같습니다 : cron 작업은 1 분마다 명령을 실행하고, 명령 자체가 대기열을 정교하게 만들 것입니다. – gremo

+0

@Gremo 문제는 서버에로드가 많지 않으면 등록 이메일을 즉시 보낼 수 있어야한다는 것입니다. 이미지 처리에서도 마찬가지입니다. 사용자의 이미지 업로드를 수락한다고 상상해보십시오. 각 제출에 대해 30 초 (1 분은 말할 것도 없음) 기다리는 것이 사용자 경험을 해칩니다. – ChocoDeveloper

+0

그럼 내가 생각하는 악마는 필요 없어. PHP 자체에서 즉시 비동기 적으로 명령을 스풀링하고 실행할 수 있습니다. – gremo

답변

2

해결 방법은 모든 전자 메일을 대기열로 보낸 다음 해당 대기열을 서비스와 함께 사용하는 것입니다. 내 서비스는 매우 간단합니다. 각 항목이 from, to, body 등의 배열 인 대기열에서 항목을 가져 와서 해당 전자 메일을 보냅니다. 나는 토끼를 사용하기 쉽게 만드는 Thumper를 사용하고 있습니다 : github.com/videlalvaro/Thumper. 그리고 나는 서비스가 항상 'sv'(Runit)를 사용하고 있는지 확인합니다 : smarden.org/runit/sv.8.html. 원하는 다른 서비스 나 데몬 관리자를 사용할 수 있습니다.

0

메시지를 스풀링하고 인스턴트 이메일을 보내려면 2 개의 서비스가 필요합니다. 확인 this

+0

감사하지만 이것은 내가 원하는 것이 아닙니다. 모든 메일을 스풀링하거나 대기열에 넣고, 이메일 전송을 트리거하는 모든 요청에 ​​switfmailer (매우 무겁습니다)를 주입하지 않도록하고 싶습니다. 이상적인 해결책은 Rabbit 메시지 큐에 메시지를 추가하는 것이고 데몬은 전자 메일을 보내는 일을 담당한다고 생각합니다. 이 방법으로 매 5 초마다 1 개의 이메일 요청 만하면 대기열이 매우 빠르게 작동하여 즉시 이메일을 전송합니다. 갑자기 1 초 만에 999 건의 이메일 요청이 발생하면 서버에 문제가 발생하지 않습니다. 즉, 사용자는 이메일을 기다려야하지만 http 응답은 여전히 ​​빠른 속도입니다. – ChocoDeveloper

1

나는 당신과 똑같은 문제가있다. 어떻게 마침내 당신의 문제를 해결 했습니까?

<?php 
include('/var/www/vendor/symfony/symfony/src/Symfony/Component/Filesystem/LockHandler.php'); 
use Symfony\Component\Filesystem\LockHandler; 

$lock = new LockHandler('mailer:loop'); 
if ($lock->lock()) { 
    system('cd /var/www && php app/console swiftmailer:spool:send'); 
    sleep(1); 
    $lock->release(); 
    shell_exec('cd /var/www && php LoopMailer.php > /dev/null 2>/dev/null &'); 
} 

그것은 매우 깨끗은 아니지만 자신의 작업을 수행합니다 순간

나는 루프에서 실행하려면 crontab을에 약간의 스크립트를 실행합니다.

+0

예 앞서 언급 한 Rabbit 메시지 큐를 사용하여 해결했습니다. 비동기적인 것은 cronjob 또는 데몬 (리눅스 프로그램 "sv"로 관리)에 의해 소비되는 대기열로 보내집니다. – ChocoDeveloper

+0

제 경우에는 RabbitMQ를 사용할 이유가 없습니다. 그것을 사용하는 목적은 무엇입니까, 데이터베이스가 충분하지 않습니까? RabbitMQ가 1 분 문제를 해결하는 것과 관련이 있는지도 모르겠습니까? – Alexandre

+0

RabbitMQ를 사용하면 이메일이 1 분마다가 아닌 대기열에서 사용 되 자마자 전송됩니다. – ChocoDeveloper

관련 문제