Newsletterversand mit phpmailer

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Newsletterversand mit phpmailer

    Hallo,

    ich plane ein Newsletter-Tool zu erstellen. Während der ganzen Recherchen wie man das am besten angeht konnte ich bisher herauslesen, dass der Versand via <?php mail(); ?> wohl die Last-intensivste Methode wär - also um hier schneller und Resourcenschonender zu arbeiten versendet man wohl besser über SMTP oder nutzt sendmail. Korrigiert mich, wenn ich mich hier falsch informiert hab.

    Da man das Rad ja nicht von Grund auf neu erfinden muss, hab ich mich nach einer Klasse umgeschaut, die den eigentlichen Versand vornimmt - hier gefällt mir phpmailer (download bei Sourceforge) eigentlich vom blosen drüberschauen ganz gut.

    Allerdings bin ich mir noch nicht ganz im klaren darüber, welche der gebotenen Möglichkeiten zum Versenden man am besten nimmt.

    Gibt es Unterschiede in der Performance wenn man SMTP benutzt oder sendmail? Es ist schlicht und einfach die Server-schonendste und schnellste Möglichkeit gefragt, da manche User hier durchaus in Größenordnungen von > 10.000 Mails versenden möchten. Den Versand würde ich ohnehin in die Nachtstunden verlegen, trotzdem will man natürlich auch in dieser Zeit nicht seine Server lahmlegen.

    Dann frage ich mich noch, ob es besser ist alle Empfänger gleich über $mail->AddBCC(); einzubinden oder ob es sinnvoller ist für jeden Empfänger $mail->addAdress(); dann $mail->Send(); und dann $mail->clearAdresses(); auszuführen? <- man muss ja dann nicht jedesmal komplett von vorn Anfangen denk ich mal, also Objekt instanzieren usw....

    Bei der zweiten Möglichkeit wird wohl jedesmal wieder die komplette Mail an den SMTP oder an sendmail gestreamt oder versteh ich da was falsch? Wäre das auch der Fall, wenn man gleich alle Empfänger in BCC reinschreibt und dann nur einmal $mail->Send(); ausführt?

    Oder eher das berühmte "Häppchenweise" versenden?

    Ich lese jetzt schon fast den ganzen Nachmittag durch diverse Threads usw. und irgendwie werden die Fragen weniger statt mehr

    Vielleicht kann ja hier jemand aus Erfahrung sprechen.
    Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
    Schön - etwas Geschichte kann ja nicht schaden.
    Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

  • #2
    Um wie viele Empfänger geht es?
    Alles im dreistelligen Bereich würde ich jetzt spontan per mail() "lösen"...

    Mal abgesehen davon, dass ich jetzt nicht der Meinung bin, dass die direkte Implementation von SMTP in einem Skript deutlich schneller ist als mail(), wenn man es richtig konfiguriert, aber naja...


    BCC würde ich nicht machen, das wirkt einfach doof.

    Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

    bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
    Wie man Fragen richtig stellt

    Kommentar


    • #3
      Original geschrieben von ghostgambler
      BCC würde ich nicht machen, das wirkt einfach doof.
      Warum? Bei BCC sollten ja keiner die anderen Empfänger sehen können, oder?
      Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
      Schön - etwas Geschichte kann ja nicht schaden.
      Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

      Kommentar


      • #4
        Original geschrieben von Quetschi
        Warum? Bei BCC sollten ja keiner die anderen Empfänger sehen können, oder?
        Ja, aber einen Empfänger musst du angeben (denke ich), dementsprechend wird das wohl so eine info@-irgendwas-Adresse sein und wenn man dann liest "Empfänger info@irgendwas" und sonst nichts (der BCC-Header wird afaik nämlich heraus editiert), wirkt das halt doof.

        Kannst ja mal ausprobieren.

        Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

        bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
        Wie man Fragen richtig stellt

        Kommentar


        • #5
          Hier würde ich die Adresse des Absenders setzen.

          Weil du noch gefragt hast um wieviele Empänger es sich drehen würde - wie gesagt, es wären je nach Kunde mal mehr als 10.000 - bei anderen wiederum vielleicht "nur" zwischen 300 bis 400 - recht unterschiedlich also, aber es soll ja auch im worst-case vernünftig laufen.

          Ich weiß halt auch nicht wirklich wie das alles genau abläuft - bei Einzelversand wird halt vermutlich jede Mail einzeln von PHP nach SMTP bzw. sendmail "gestreamt" oder wie man das in diesem Fall nennt - per BCC könnt ich mir vorstellen, dass nur einmal die Mail von PHP an SMTP/sendmail geht und dort dann eben alles rausgeschickt wird.

          Und wenn man zwischen SMTP und sendmail wählen kann, was nimmt man? Gibt es gute Gründe das eine oder andere zu nehmen, oder Gründe das eine oder andere nicht zu nehmen? Oder bleibt es - wie wir hier in Bayern sagen "ghupft wia gsprunga?" - also eher egal?


          Wir haben durchaus vernünftige Hardware am Laufen - wie zum Beispiel hier ein Auszug aus top:

          Tasks: 23 total, 1 running, 22 sleeping, 0 stopped, 0 zombie
          Cpu0 : 5.0% us, 3.0% sy, 0.0% ni, 84.0% id, 8.0% wa, 0.0% hi, 0.0% si
          Cpu1 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si
          Cpu2 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si
          Cpu3 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si
          Cpu4 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si
          Cpu5 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si
          Cpu6 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si
          Cpu7 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si

          Wir haben ein paar Maschinen in entsprechender Konfiguration - ich denke prinzipiell bringt man keinen davon mit ein paar Mails sonderlich aus der Ruhe, aber wenn ich was mache, dann solls halt Hand und Fuß haben.
          Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
          Schön - etwas Geschichte kann ja nicht schaden.
          Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

          Kommentar


          • #6
            Bei Newslettern darf man die Last für den Mailserver wirklich nicht unterschätzen. Ich habe eine Liste, die dieses Jahr ihr Zehnjähriges feiert. Die Subscribtions werden leidlich gepflegt. So kommt es, dass viele Empfänger seit Jahren gar nicht mehr erreichbar sind - mailbox full oder unknown account. Automatisiertes Austragen ist nicht gewünscht, der Kunde protzt lieber mit der Abonnentenzahl. Für den Mailserver siehts also so aus: Ein Newsletter mit 10.000 Abonnenten sind ...
            10.000 SMTP-Dialoge
            davon werden 1.000 mit 5xx quittiert
            6.000 (!) werden mit 4xx zurückgewiesen
            die restlichen 4.000 gehen sauber raus.

            Und jetzt kommt der Teil, den man nicht unterschätzen darf: Die 6.000 temporary failures versucht der Mailserver natürlich nochmal und zwar im 5 Minuten Intervall bis zu 16 Mal. Da die meisten wegen Greylisting abgelehnt wurden, gehen sie gleich beim ersten Resend raus. Manche brauchen aber auch bis zu 10 Anläufe.

            Und während der Server noch fleißig am Senden ist, laufen schon zu tausenden die Bounces ein. Die wollen maschinell verarbeitet werden und wenn das nicht reicht, auch noch auf Spam geprüft.


            Es ist auf jeden Fall ratsam, die Last ordentlich über die Zeit zu verteilen. Etwa mit Cronjobs, die alle 5 Minuten zwischen 100 und 1.000 Mails generieren je nach Kunde/Newsletter oder am besten in Abhängigkeit von der System-/Netzlast.
            Es kann auch einen spürbaren Unterschied machen, wenn man alle Abonnenten eines Providers wie GMX in einem Rutsch beschickt. Auf diese Weise sind weniger SMTP handshakes nötig. ... Kann phpMailer überhaupt eine SMTP-Session für mehrere Mails verwenden?

            Kommentar


            • #7
              Original geschrieben von onemorenerd
              Kann phpMailer überhaupt eine SMTP-Session für mehrere Mails verwenden?
              Das sind Dinge die ich mir da noch zu Gemüte führen muss.

              Aber du scheinst Erfahrung mit der Materie zu haben - nimmst du ein fertiges Tool, oder hast du dir das selbst programmiert?

              Ich frage, weil ich aus deinem Post so einiges rauslesen konnte, was da alles gemacht werden muss - so ein Teil muss schließlich auch mit den Meldungen vom "gegnerischen" SMTP entsprechend umgehen können. Viele Dinge die gehandlet werden müssen und bis das alles möglichst ohne irgendwelche Bugs läuft dürfte ne Weile vergehen - darum frage ich mich doch, ob ich eher auf ne fertige Lösung zurückgreifen sollte die durchaus auch was kosten darf.

              Ich habe unsere Kunden in einem Punkt soweit ganz gut im Griff, dass automatisches Austragen kein Thema wäre - um eine möglichst hohe Abonnentenzahl in der DB gehts sicher keinem, hier hätte ich freie Hand wie mit nicht mehr erreichbaren Verfahren wird.

              Wie gesagt würde ich den Versand sowieso nur in den Nachtstunden ablaufen lassen - hier idlen die Server teilweise doch ganz gemütlich vor sich hin. 10.000 Mails könnten z.B. verteilt über 3 Stunden von 1 Uhr morgens bis 4 Uhr verschickt werden, was nicht mal eine Mail pro Sekunde bedeuten würde. Um 4 Uhr den Versand stoppen, dann sind noch ca. 3 std. Zeit für die Rückläufer, die sicherlich Last erzeugen könnten bevor die Last durch den "Norm"-Betrieb allmählich wieder hochgeht.

              Dein Aspekt mit dem gebündelten Versand zu den Großanbieter wegen der SMTP-Handshakes ist auch sehr interessant - darauf wäre ich wohl von selbst nie gekommen.
              Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
              Schön - etwas Geschichte kann ja nicht schaden.
              Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

              Kommentar


              • #8
                Ich benutze eine Eigententwicklung. Aus Sicht des Anwenders kann die auch gar nichts besonderes.
                - Benutzer anlegen/bearbeiten/löschen
                - Listen anlegen
                - Newslettervorlagen (mit Platzhaltern) anlegen/bearbeiten/löschen
                - Platzhalter anlegen/bearbeiten (Name des Empfängers, unsubscribe-Link, andere Links)
                - Abonnenten importieren/exportieren
                - Abonnenten eintragen/sperren/austragen
                - Formulare für Subscribe/Unsubscribe ausgeben (um sie auf Kundenseiten einzubetten)
                - Testversand eines Newsletters an einzelne Adressen
                - Newsletter versenden
                Ich denke, das bietet auch jedes bessere Newsletterscript von der Stange.

                Der Versandt erfolgt bei mir wie gesagt per Cron. Der Mailserver teilt dem Newslettertool alle permanenten SMTP-Fehler mit. Außerdem hat jede Liste hat ihre eigene Absenderadresse. Dort eintreffende Bounces werden geparst. Da es kein Standardformat für Bounces gibt, muß ich da immer wieder ran. Die Verzahnung von Tool und Mailserver erlaubt es mir, dem Kunden eine sehr präzise Sendestatistik zu liefern. Desweiteren kann der Kunde für einzelne Listen "nach X Fehlern automatisch austragen" stellen. Wenn dann ein Empfänger x Mal nicht beschickt werden konnte, wird er gesperrt und belastet den Mailserver beim nächsten Versandt nicht mehr.
                Dem Kunden ist die Mailserverlast i.d.R. egal. Aber er versteht, dass dieses Feature den AGB der Großprovider entspricht. Bei vielen ist es nämlich so, dass ein Account verfällt, wenn man ihn eine gewisse Zeit nicht benutzt. Nach einer Sperrfrist wird der Account zur erneuten Registrierung freigegeben. Dann hat also u.U. ein Fremder diese Mailadresse und der möchte sicher nicht die Newsletter seines Vorgängers bekommen.

                Kommentar


                • #9
                  @onemorenerd

                  ich hab gestern mal einige Kurztests mit 100 Mails laufen lassen - jeweils direkt über den mail()-Befehl, einmal über phpMailer via SMTP (davon einmal mit SMTP-KeepAlive und einmal ohne) und über phpMailer via sendmail.

                  Die schnellste Methode war via SMTP mit KeepAlive, allerdings waren die Unterschiede insgesamt marginal - negativ hat sich lediglich die Methode via sendmail hervorgetan.

                  Was mich aber eher verwundert ist das Tempo, mit dem die Mails rausgehen - ich hab in der Schleife keine Bremse eingebaut sondern wollt einfach sehen, was theoretisch gehen würde - das waren ca. 32 Sekunden für 100 HTML-Mails mit ca. 30KB und ca. 28 für 100 reine Textmails mit ca. 4KB.

                  Also grob gesagt irgendwas um die 3 Mails pro Sekunde - ehrlich gesagt erscheint mir das etwas zäh, hab aber keine wirklichen Erfahrungen damit. Ich hätt mir aber vorgestellt, dass da mehr pro Sekunde rausgehen, wenn man das Skript ungebremst laufen lässt.

                  Die Maschine fertigt halt nicht nur Mails ab, sondern es ist eben auch noch der Webserver und der MySql-Server drauf - kann es sein, dass hier evtl. an anderer Stelle runtergebremst wird, damit die anderen Dienste nicht beeinträchtigt werden, falls der Mailserver zuviel zu tun bekommt?

                  Nur interessehalber - wieviele Mails pro Sekunde bekommst du raus (bei angenommenden 30-50Kb pro Mail)? Mir ist klar, dass das nicht vergleichsfähig ist wg. Hardware-Konfiguration usw. - aber trotzdem nur mal rein interessehalber.

                  Gerne dürfen natürlich auch andere ihre Erfahrungen/Werte posten.


                  Gruss
                  Quetschi
                  Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                  Schön - etwas Geschichte kann ja nicht schaden.
                  Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                  Kommentar


                  • #10
                    Ich sende zw. 100 und 1000 mit einem 5 Minuten-Cron. Der Server muss also 0,3 bis 3,3 Mails pro Sekunde schaffen. Da es keine Staus gibt, muss die tatsächliche Sendeleistung etwas darüber liegen. Deine 3/s kann ich also bestätigen.
                    Die 1000 in 5 Minuten mache ich allerdings nur bei "Kurzmitteilungen im Intrant" - superkleine Mails an geschlossene Liste. Bei öffentlichen Newslettern kann man nicht so aggressiv sein. Da kommen schließlich jede Menge temporäre Fehler (Resend nötig) und Bounces, die parallel verarbeitet werden müssen.

                    Bei 3/s braucht man für 10.000 Abonnenten etwa eine Stunde. Falls das zu langsam ist - heute ist eine News nach einer Stunde ja schon alt, weil zigmal verbloggt und bei N-TV - dann stell dir mehrere SMTP-Server hin und lasse parallel senden.


                    Wie mißt du denn, wieviele Mails du pro Sekunde rausballern kannst? Einfach mal 100 in einer Schleife senden und die Zeit messen? Das ist nicht besonders aussagekräftig. Diesen Test müßte man schon mehrmals wiederholen, mit ausgewählten Adressen, zu anderer Tageszeit, in anderen Mengen etc.

                    Die Bremse ist nicht der eigene SMTP-Server oder gar der Webserver auf dem selben Host. Die Zeit geht für Lookups und Analysen auf dem entfernten SMTP drauf.

                    Wie gehst du bei deinen Tests mit Greylisting und SMTP-Fehlern um, wenn du direkt per SMTP versendest?

                    Kommentar


                    • #11
                      Ich hab schon mehrere Testläufe über den Tag verteilt gemacht, relevante Unterschiede konnte ich nicht ausmachen - es blieb immer bei den genannten Werten mit max einer Sekunde Unterschied.

                      Empfänger waren bis jetzt natürlich nur eigene Test-Adressen auf ein paar unserer anderen Server. Wie das alles erstmal aussieht, wenn Adressen großer Anbieter beschickt usw. hab ich noch nicht ausgetestet - mir ist klar, das mein Testlauf hier noch gar nicht aussagekräftig ist - ich wollt nur erstmal ne grobe Hausnummer haben - ich möchte mich da einfach Schritt für Schritt rantasten.

                      Es kommen ja noch andere Dinge hinzu, wie Schreibzugriffe auf die DB um Abonnent x mit Newsletter y beschickt zu markieren usw.

                      Insgesamt reicht mir aber die Geschwindigkeit wohl schon aus - es handelt sich nicht um "News" sondern um Angebote usw. die nicht gleich wieder alt sind, sondern es wäre hier auch egal, wenn der Versand z.B. nicht in einer "Nachtschicht" fertig wird, sondern sich das z.B. zur Not auch über 3-4 Tage in jeweils 3-stündigen Nachtschichten hinzieht.

                      Der Umgang mit SMTP-Fehlern wird mitunter das nächste sein, dass ich mir ansehen möchte.
                      Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                      Schön - etwas Geschichte kann ja nicht schaden.
                      Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                      Kommentar


                      • #12
                        Als Hausnummer für den Live-Betrieb mit allem was dranhängt (Sende-Applikation mit DB-Read/Write, Fehlerbehandlung, Bounce-Analyse) würde ich wie gesagt 2 bis 3 Mails pro Sekunde pro SMTP-Server nennen. 3 ist schon ein guter Wert!

                        Die theoretische Obergrenze wird durch die Netzwerkanbindung vorgegeben, z.B. 12 Mails à 10kB pro Sekunde über eine 1GBit-Leitung.
                        Im Idealfall gehen alle Mails an den selben Empfänger, so dass nur ein DNS-Lookup und ein SMTP-Connect notwendig ist. Aber pro Mail wandern mindestens 8 IP-Pakete über die Leitung. Bei 10ms RTT sind das 40ms pro Mail. Dadurch reduziert sich die Senderate auf etwa 8 Mails pro Sekunde.
                        Hinzu kommen die Verzögerungen, der auf beiden Seiten zwischen Empfang eines Pakets und Senden des nächsten Pakets entstehen; sicherlich um 100ms. Jetzt sind wir bei 4 Mails pro Sekunde. Und das ohne DNS-Lookup, also fern von der Realität!

                        Im Netz findet man Aussagen, wonach Leute >50.000 Mails pro Stunde senden. Das wären >13 Mails pro Sekunde. Solche Aussagen beziehen sich also keinesfalls auf einen einzelnen Server mit einer 1GBit-Leitung. Da steckt eine Serverfarm dahinter. Oder ein Botnet.
                        Zuletzt geändert von onemorenerd; 26.11.2008, 15:27.

                        Kommentar


                        • #13
                          Also heute ist der Server doch besser im Futter - der Test mit HTML-Mail mit ca. 30KB, 100 Durchläufe geht heute in 14 Sekunden (ca. 7 pro Sek) via SMTP mit KeepAlive. Mit sendmail dauerts heute fast 40 Sekunden.

                          Komisch - gestern waren die Unterschiede weitaus geringer. Werd nachher nochmal SMTP ohne KeepAlive probieren nur um zu sehen ob sich da heute auch stärkere Unterscheide auftun.

                          Hab auch das doDebug von PHPMailer eingeschaltet und da alles mal mitzubekommen was überhaupt passiert.
                          Hab dann auch mal an eMail-Adressen gesendet die nicht existieren. Beim Durchlauf bekomm ich dann erstmal '250 2.1.5 ... Recipient ok' zurück - bekomm aber ne Returned Mail ins Postfach rein wo dann eben die Meldung aus dem Dialog 'reason: 550 5.1.1 <fake@meinedomain.de>... User unknown' drinsteht.

                          Hätte gedacht das könnte ich schon über die Klasse zurückbekommen und dort gleich entsprechend reagieren, da dort eine Methode bereitsteht, die - soweit ich es verstanden habe - eben genau darauf prüft. Irgendwie lieg ich da wohl noch falsch.
                          Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                          Schön - etwas Geschichte kann ja nicht schaden.
                          Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                          Kommentar


                          • #14
                            Eigentlich solltest du auf RCPT TO eine negative Antwort bekommen. Aber bei großen Providern ist es manchmal nicht möglich, den Empfänger schnell genug zu validieren. Außerdem würde man so den Spammern in die Hände spielen. Sie könnten alle möglichen Adressen einmal probieren und wüßten dann genau, welche existieren und welche nicht. Solche "geprüften Listen" würden viel Geld bringen.

                            Kommentar


                            • #15
                              Hmm - also ich hab 2 verschiedene "Fehlerquellen" mal eben getestet

                              - einmal eine eMail-Adresse, bei der zwar die Domain existiert, aber nicht der Alias
                              - einmal eine eMail-Adresse, bei der schon die Domain gar nicht existiert

                              In beiden Fällen bekomm ich beim versenden erstmal ein '250 2.1.5 ... Recipient ok' - im Postfach landet aber eben umgehend eine Mail mit User bzw. Host unknown.

                              Selbst wenn ich an eine syntaktisch fehlerhalfte eMail-Adresse sende möchte bekomm ich vom Smtp das ok zurück

                              Dann kann ich mir allmählich eh alle Mühen sparen beim Versand schon entsprechend zu reagieren und mich darauf beschränken die Rückläufer im Postfach zu analysieren.
                              Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                              Schön - etwas Geschichte kann ja nicht schaden.
                              Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                              Kommentar

                              Lädt...
                              X