Newsletter an ~65K User, wie?

Maddin

dev.
ID: 234104
L
24 April 2006
2.951
215
Hallo,
ich brauche Hilfe, ich habe heute mit der Rmail Klasse versucht einen Newsletter an ca. 65.000 User zu senden, allerdings hab ich das Script, nachdem es ca. 10 Stunden gelaufen ist, beendet.

Es sind zwar einige Mails (ich denke fast alle eigentlich) raus, aber so lange kann das doch nicht dauern, was sollen dann Seiten mit 6,5 Mio Usern machen?

Folgender Code sollte eventuell Relevant sein:

PHP:
$result = $db->query("SELECT mail FROM users");
while($row = $db->fetch($result)) {
    $mailnow = $mail->send($row['mail']);
}

Denkt ihr das würde besser gehen:

PHP:
$result = $db->query("SELECT mail FROM users");
while($row = $db->fetch($result)) {
    $mailaddys[] = $row['mail']; // Array wird von Rmail unterstützt
    $mailnow = $mail->send($mailaddys); 
}

Oder sollte ich die E-Mail an die User mit der Blind-Carbon-Copy (= BCC) senden?

Oder aber ist Rmail einfach nicht dafür geeignet? Doch was soll ich dann nutzen? Oder brauche ich sogar einen extra Mailserver dafür oO

Ich will halt auch nicht auf den Spam Listen landen...aber vor allem soll es nicht 10 Stunden dauern -.-

Für jegliche Hilfe bin ich sehr Dankbar :)
 
Als erstes würde ich, wenn ich solche Spielchen treibe, loggen an wen schon eine Mail versendet wurde. Du weißt jetzt nämlich gar nicht, ob wirklich alle rausgingen und wenn nein, wer hat keine bekommen? Deswegen würde ich nach jedem Senden einer Mail speichern, dass die gesendet wurde. Das verlängert den Prozess zwar noch einmal gewaltig, macht aber schon Sinn.

Dann zu deinen Mails: Wie versendest du die denn? Über den lokalen Mailserver oder über einen externen SMTP Server? Bei zweiterem käme bei jedem Versenden noch ein Verbindungsaufbau dazu, der auch immer etwas braucht.
Aber 10 Stunden für 65k Mails finde ich auch nicht zuviel. Du musst bedenken, dass der Mailserver auch etwas braucht, um den Empfänger zu finden und die Mail zu versenden. Der kann ja auch nicht immer nur annehmen ohne etwas mit der Mail zu tun.
Ich bin mir grad nicht sicher, wie das mit der PHP mail() Funktion abläuft. Gibt die true zurück, sobald der Mailserver die Mail angenommen hat oder erst nach dem versenden? Bei zweiterem würde dies ja, wie schon gesagt, auch immer noch Zeit benötigen.

Große Seiten verschicken die Mails auch über längere Zeiträume verschickt. Twitter hat vor kurzem einen Newsletter verschickt. Da ich 2 Twitter-Accounts habe, habe ich die Mails auch 2x erhalten, aber mit einigen Tagen dazwischen.

Wenn du allerdings so viele Mails verschickst, würde ich sowieso mal darüber nachdenken, einen Externen Anbieter dafür einzusetzen. Die haben dann meistens auch den Trust bei den Mail-Providern, damit die Mails nicht sofort in den Spamlisten landen.
 
Ich danke euch beiden :)

@flaschenkind: Ein solches Tracking wollte ich auch erst einbauen, aber der Newsletter war jetzt nicht so sehr wichtig, als dass mir das nun in irgendeinster Weise etwas ausmachen würde, wenn z.B. 10K keinen Newsletter erhalten haben. Das war nur ein Newsletter, bei dem ich die User über bald folgende Neuigkeiten informieren wollte, jedoch werde ich, sobald die Neuigkeiten da sind, dann noch einmal einen Newsletter versenden. Dieser ist mir dann doch schon etwas wichtiger als der jetzige :D

@x3ntar: Danke, das schau ich mir direkt mal an.

Muss halt dazu sagen, dass ich bisher noch nie an so viele User einen Newsletter gesendet habe, aber irgendwann ist immer das erste mal :D
 
Also da hab ich noch ein paar Kleinigkeiten, die Sache mit der Connection is natürlich der beste Tipp und da is die Pear Mail Klasse genau das richtige. Eine weitere Sache is Speicher die Liste der Empfänger zwischen und lass deinem MySQL Server die Verbindung frei, musst ja nicht mehr resourcen als nötig an dich binden.

Dann stellt sich die Frage ob php die geeignete sprache dafuer is, ich hab mal ~10'000 Mails in weniger als 15 Minuten gequeued indem ich Python die smtp Befehle ausspucken lass und die dann mit eineminix socket in meine lokale postfix Instanz gepiped. Die Mails wurden dann in den folgenden 2 Stunden aufs Netz verteilt.
 
Um den Aufwand für den Indianer zu veringern (ich nehme mal an, dass Du den NL über eine Weboberfläche versenden willst) würde ich die zu versendenden Mails Paketieren (50-100 Mails pro Auftrag / x Aufträge für den gesamten Newsletter), und dann per Cron die Mails endgültig versenden. Die "Jobfiles" sind dann im Nu erstellt, und im Hintergrund bemüht sich der Server die Mails los zu werden. Schau Dir einfach mal vBulletin oder phpBB3 an, bei denen wird das genauso gemacht.

Diese Abwicklung kann dann durchaus auch php-cli übernehmen, ist ohne den Indianer auch gut unterwegs - wenn man weder Perl noch Python spricht.

Und, bzgl. des Performance-Problems, eine SMTP-Klasse würde ich ohnehin immer nehmen, wenn solch Mail-aufkommen zu erwarten ist, egal ob ein externer oder der lokale SMTP-Server für herhalten muss.

Es ist auch nicht verkehrt, jedem User seine eigene Mail zustellen zu lassen. Da hat zwar der Mailserver ordentlich was zu tun, aber die Addresszeile beinhaltet dann auch nur den Empfänger. Alle in BCC geht, aber ein "undisclosed-recipients" weißt schon auf eine Massen-Mail hin und kann gefiltert werden.

Gruß
 
Um den Aufwand für den Indianer zu veringern (ich nehme mal an, dass Du den NL über eine Weboberfläche versenden willst) würde ich die zu versendenden Mails Paketieren (50-100 Mails pro Auftrag / x Aufträge für den gesamten Newsletter), und dann per Cron die Mails endgültig versenden. Die "Jobfiles" sind dann im Nu erstellt, und im Hintergrund bemüht sich der Server die Mails los zu werden. Schau Dir einfach mal vBulletin oder phpBB3 an, bei denen wird das genauso gemacht.
[...]

So mache ich es auch immer und kann das nur empfehlen.

Beim "Senden" werden die Mailadressen in eine Tabelle in der DB übernommen und ihnen der entsprechende NL Key zugewiesen.
foo@bar.de | 45 | eintragszeit
...

Dann kann der Cron herkommen und die Teile paketweise abholen, versenden und aus der Warteschlange löschen, wenn mail () erfolgreich war. So hast du auch direkt noch die Möglichkeit Mails erneut zu versenden, da der Auftrage so lange in der Tabelle bleibt bis es klappt, oder du ihn manuell raushaust.

Dazu solltest du dir auch immer einen Überblick über deinen Inhalt verschaffen und bei Gelegenheit die alten Mails rauswerfen, ggf. den User bitten die Mail zu aktualisieren, oder oder oder.
 
So mache ich es auch immer und kann das nur empfehlen.

Beim "Senden" werden die Mailadressen in eine Tabelle in der DB übernommen und ihnen der entsprechende NL Key zugewiesen.
foo@bar.de | 45 | eintragszeit
...

Dann kann der Cron herkommen und die Teile paketweise abholen, versenden und aus der Warteschlange löschen, wenn mail () erfolgreich war. So hast du auch direkt noch die Möglichkeit Mails erneut zu versenden, da der Auftrage so lange in der Tabelle bleibt bis es klappt, oder du ihn manuell raushaust.

Dazu solltest du dir auch immer einen Überblick über deinen Inhalt verschaffen und bei Gelegenheit die alten Mails rauswerfen, ggf. den User bitten die Mail zu aktualisieren, oder oder oder.

Genau so :)
Mit dem Unterschied, dass ich diese Datensätze, samt dem Mailbody in Dateien packe, wodurch die DB in Ruhe gelassen wird. Allerdings geht damit die von Dir beschriebene Kontrolle flöten. Hat bei mir aber immer eine untergeordnete Rolle gespielt. Wer den NL will, kümmert sich auch darum, dass er eine aktuelle Adresse eingetragen hat...

Gruß
 
...

dass mir das nun in irgendeinster Weise etwas ausmachen würde, wenn z.B. 10K keinen Newsletter erhalten haben. Das war nur ein Newsletter, bei dem ich die User über bald folgende Neuigkeiten informieren wollte,

Und schon bist Du beim klammgeil-Problem, das einige User den NL erhalten, andere nicht. Gibt nur Beschwerde-Potential, von daher möglichst immer alle erreichen ;)

Aber Du suchst hier ja schon nach einer Möglichkeit - viel Erfolg.
 
Ja natürlich, es ging dabei um den besagten Newsletter, welcher nicht so wichtig war, aber da der nächste wichtige Infos enthalten wird, muss dieser auch ankommen :)

Edit: Es stellt sich mir aber noch eine Frage und zwar, ob ich die Mails, die zurückkommen (Mailer Daemon - Failure notice), irgendwie alle auslesen kann und auf die Blacklist setzten kann, damit ich beim nächsten mal keinen Newsletter mehr an diese E-Mails sende?
 
Zuletzt bearbeitet:
Edit: Es stellt sich mir aber noch eine Frage und zwar, ob ich die Mails, die zurückkommen (Mailer Daemon - Failure notice), irgendwie alle auslesen kann und auf die Blacklist setzten kann, damit ich beim nächsten mal keinen Newsletter mehr an diese E-Mails sende?

Könntest da irgendeine fertige Toolklasse für Bouncemails verwenden - ein Beispiel wäre https://phpmailer.worxware.com/index.php?pg=bmh (kenne es selbst allerdings nicht). Google ansonsten mal nach ähnlichen Scripten, findest bestimmt etwas :)
 
Hallo, hab grade das Thema gefunden und bevor ich eins neues aufmache, stell ich meine Frage mal direkt hier.

Unzwar möchte ich ca. ~ 400 - 500 Mails verschicken. Am liebsten wäre es mit mit einer Schleife und der Mail() funktion, wird das bei 400 mails laufen?

Meine mails sind wie folgt aufgebaut (email.txt)

Kundenmail@kunde.de, Kundenwert, name, vorname
Kundenmail@kunde.de, Kundenwert, name, vorname
Kundenmail@kunde.de, Kundenwert, name, vorname
Kundenmail@kunde.de, Kundenwert, name, vorname
...
 
Unzwar möchte ich ca. ~ 400 - 500 Mails verschicken. Am liebsten wäre es mit mit einer Schleife und der Mail() funktion, wird das bei 400 mails laufen?

Wie gesagt, sehr ineffizient, schau dir dazu doch mal die Doku zu mail() an ... bei jedem Aufruf wird die Verbindung zum SMTP-Server neu aufgebaut und wieder geschlossen. Nimm lieber das Pear-Mail-Package zusammen mit Mail_Queue.
 
Ich danke euch beiden :)

@flaschenkind: Ein solches Tracking wollte ich auch erst einbauen, aber der Newsletter war jetzt nicht so sehr wichtig, als dass mir das nun in irgendeinster Weise etwas ausmachen würde, wenn z.B. 10K keinen Newsletter erhalten haben. Das war nur ein Newsletter, bei dem ich die User über bald folgende Neuigkeiten informieren wollte, jedoch werde ich, sobald die Neuigkeiten da sind, dann noch einmal einen Newsletter versenden. Dieser ist mir dann doch schon etwas wichtiger als der jetzige :D

@x3ntar: Danke, das schau ich mir direkt mal an.

Muss halt dazu sagen, dass ich bisher noch nie an so viele User einen Newsletter gesendet habe, aber irgendwann ist immer das erste mal :D

Newsletter sollten eigentlich kurz gehalten werden, um den Traffic und die Zeit beim Transfer so gering wie möglich zu halten.
Wer 65k. Nutzern etwas zukommen lassen will, sollte entweder ein Blog oder die alte Methode ein Forum wählen. Wer von den Usern wirklich aktiv ist, liest nicht nur den Newsletter.
Alternativ kann man auch über RSS informieren, welches wie ein Newsletter funktioniert, nur nicht ganz so.
Denn beim RSS, wenn nicht bekannt, wird der der den "Newsfeed via RSS" holt, nur dann in Kenntniss gesetzt.
Wenn 65k user nen RSS Feed abrufen, glaub ich geht das schneller als 10 Stunden E-Mails versenden !

Naja nur eine Impression von mir
 
Thread ist zwar schon ne Woche verlassen, aber ich stand genau vor dem selben Problem. Und zwar mit Paidmails.

Lösung ist eigentlich einfach:
1) Tabelle 1: Userdaten
2) Tabelle 2: Newsletter-Daten
3) Tabelle 3: Daten für Cronjob
4) Aufruf Cron jede Minute (Versendet 200 Mails), Eintrag in Cron-Tabelle bis zu welcher Position.
5) Wiederholung Schritt 4) von Pox x bis Pos x + 100

Berechnung: 65000 / 200 = 325 Minuten = ~ 5,5 Stunden
Man sollte aber bedenken das bei Multiweb-Hostings die Serverlast darunter leiden kann.

PS: Ich nutze z.B. kein PEAR sondern PHPMailer.

Bei Bedarf kann ich die nen Beispiel schicken.
 
PS: Ich nutze z.B. kein PEAR sondern PHPMailer.
Mit PHPMailer kann man ne super Sache machen:
Eine Instanz dieser Klasse kann man serialisiert direkt in der Datenbank in ein BLOB-Attribut speichern :idea: So spart man sich das separate Speichern von Text, Empfänger und weiteren Mail-Headern.
 
Mit PHPMailer kann man ne super Sache machen:
Eine Instanz dieser Klasse kann man serialisiert direkt in der Datenbank in ein BLOB-Attribut speichern :idea: So spart man sich das separate Speichern von Text, Empfänger und weiteren Mail-Headern.
Alternativ koennte man auch einen File schreiben, z.B. mit Cache_Lite [1] oder serialize [2]. Is mir immer noch lieber als alles in die DB zu schmeissen, die behalte ich lieber fuer wirklich persistente Daten :mrgreen:

[1] https://pear.php.net/package/Cache_Lite
[2] https://php.net/manual/en/function.serialize.php