Andreas: 5000 Mails unterschlagen?

Hallo!
Habe mir ein neues Newsletterscript gebastelt. Das Script funktioniert so:
1. Ermittele ich die Startzeit und lege eine Endzeit die unter dem Timeout des Providers liegt fest
2. Schicke ich in einer schleife per mail() emails - zum testen alle an mich - bis die vorher bestimmte Endzeit erreicht ist.
3. Übergebe ich per fsockopen() die Nummer der letzten mail an ein zweites Script
4. beende ich das Script mit exit().
5. Das zweite Script übergibt ebenfalls die Nummer der letzten Mail an das ursprüngliche Script
6. alles geht von vorne los, mit dem Unterschied das nach der zuletzt gesendeten Mail weitergemacht wird

(ich versende zwar immer dieselbe mail, aber immer mit der eigenen Nummer im Subject)
Soweit funktionierte das recht gut, bis ich mal die mail mit Inhalt füllte und i9nsgesamt 10.000 emails versenden wollte.

Angeblich wurden 10.000 emails versendet, aber von den 10.000 sind nur 5.000 angekommen. Es fehlen immer zwischendurch ein paar mails! Die mailbox hatte 5 mal mehr Speicherplatz als alle mails zusammen haben könnten.
Ich habe ständig mails abgeholt! Der Versand hat alles in allem 30 minuten gedauert und knapp 30 Durchläufe beider Scripte.

Der Versuch mit 1.000 Mails hat ohne Probleme geklappt. jemand ne Idee in welcher Richtung so ein Fehler liegen könnte? Die Scripte sehen so aus:

SCRIPT 1:
<?
$fehler="";

// x ist die anzahl, wie oft das Script geöffnet wurde
if(!$x){
$x=1;}

// i wird bei jeder neuen Mail erhöht und immer mitgeschleppt
if(!$i){
$i=1;}

if(!$startzeit){
$startzeit=time();}

// siehe in den emails, war hinterher ganz interessant
$turn="Turn ".$x;

// Definition Wie lange dieses Script(die Schleife) laufen soll - max. 80
$ende=time()+60;

$file = "agbs.txt";
$data = fopen($file, "r");
$message = fread($data, filesize($file));
fclose($data);

while($zeit<$ende){
//Laufzeit des gesamten Newsletterversandes in Sekunden bis jetzt
$secs=time()-$startzeit;
$subject=$i." - ".$secs;

$gesendet=mail("akorthaus@knet-systems.de", "$subject", "$message", "From: akorthaus@knet-systems.de ($turn)");
if(!$gesendet){$fehler.=$subject."\n";}
$zeit=time();
$i++;
}

$file = "fehler.txt";
$data = fopen($file, "a+");
fwrite($data, $fehler);
fclose($data);

// solange noch kein 10000 mails versendet sind noch ein neuer Durchgang
if($i<10000){
$fp = fsockopen ("www.knet-systems.de",80);
@fputs ($fp,"HEAD /get.php?x=$x&i=$i&startzeit=$startzeit HTTP/1.1\nHost: www.knet-systems.de\n\n");
exit();}

?>

SCRIPT 2:
<?
$x++;
$fp = fsockopen ("www.knet-systems.de",80);
@fputs ($fp,"HEAD /aus.php?x=$x&i=$i&startzeit=$startzeit HTTP/1.1\nHost: www.knet-systems.de\n\n");
exit();
?>

Grüße
Andreas
PS: Was haltet Ihr von den Scripten?

  1. PS: Was haltet Ihr von den Scripten?

    Mal ganz blöd gefragt: wieso zwei? Das erste kann sich doch selbst aufrufen, sparst Dir den Aufwand mit zweimal fsockopen().

    1. Ich dachte das geht nicht?! Da erst das erste beendet sein muß, aber wie soll ich das dann wieder aufrufen? Scripte dürfen nur 90 Sekunden laufen.
      Grüße
      Andreas

  2. Hallo,

    1. alles geht von vorne los, mit dem Unterschied das nach der zuletzt gesendeten Mail weitergemacht wird

    Hast Du mal probiert, die Folgemails Cc bzw. Bcc zu senden? Das sollte die Effizienz steigern.

    MfG, Thomas

    1. Hi!

      Hast Du mal probiert, die Folgemails Cc bzw. Bcc zu senden? Das sollte die Effizienz steigern.

      Da wurde mir von abgeraten, da bei großen mengen wohl oft ohne erkennbaren Grund einige Mails verloren gehen :)
      Das komisch ist - es ist immer nur zwischendurch hier und da mal ein paar Mails, auch mitten in der "normalen" Schleife, dann mal eben 500 - ich habe auch die Versandzeit genau mitgespeichert, und z.B. bei einer großen Lücke ist auch zeitlich eine entsprechend große Lücke! Außerdem sollten Versand-Fehler ja geloggt werden(weiß aber nicht ob das so funktionierte, denn die fehler.txt wurde zuletzt _vor_ ausführung des Scriptes geändert.
      Wie gesagt ziehen sich die unterschiedlich großen Lücken über den gesamten Zeitraum(erste und letzte mail sind angekommen!!!), nur hinterher wurden die Lücken öfter und größer.
      Nur diesmal weiß ich gar nicht, wie ich das Problem angehen soll. Ich wollte das nochmal machen und diesmal so viel wie möglich in eine Logdatei schreiben. Hat jemand Ideen was alles interessant sein könnte?
      Dachte bis jetzt an:
      Nummer|Sekunden seit Start|mail()-Rückmeldung|Zeitpunkt|Anzahl Durchläufe

      was könnte man noch loggen, denn diese Daten habe ich ja im Prinzip, nur hätte ich dann die Bestätigung, ob alle 10.000 Mails weg gegangen sind! Wenn die Mailbox tatsächlich voll wäre - wie könnte man das herausbekommen - müßte ich dann nicht an die angegebene Absender Adresse eine Fehlermeldung erhalten?

      Oder kann es sein, dass Sendmail das zuviel war und immer ein paar Mails auf später verschiebt, wenn mehr Luft ist? Würde ein sleep() oder usleep() was nutzen?

      Wer hat Ideen wie ich den Fehler hier einkreisen könnte?
      Grüße
      Andreas

  3. Hallo!

    Soweit funktionierte das recht gut, bis ich mal die mail mit Inhalt füllte und i9nsgesamt 10.000 emails versenden wollte.

    Sollte man bei dieser Menge nicht schon zu einer Softwarelösung wechseln? Bietet Dein Provider keine Lösung an?

    Ich überlege gerade schon bei 500 Emailadressen, eine Softwarelösung zu verwenden.

    Ist das ein virtueller Host bei einem Provider, den Du verwendest? Wenn ja, lasse Dich nicht von Deinem Provider erwischen. Selbst wenn Du von Zuhause aus 10.000 Emails versendet, wird sich mit Sicherheit Dein Provider melden. Oder darfst Du soviel versenden?

    MfG, André Laugks

    1. Hi!

      Sollte man bei dieser Menge nicht schon zu einer Softwarelösung wechseln? Bietet Dein Provider keine Lösung an?

      Nun ja, aber was fü reine Softwarelösung, ich darf ja nicht einfach irgendwelche Programme auf dem Server installieren, und die Adressen... solen auf dem Server in MySQL gespeichert werden. Da bleiben nicht mehr so viele Möglichkeiten! Und da es da dann halt Lösungen mit PHP gibt, dachte ich ich kann auch selbst was abgespecktes machen! Und wie egesagt, mit 1000 kamen alle an!

      Ist das ein virtueller Host bei einem Provider, den Du verwendest? Wenn ja, lasse Dich nicht von Deinem Provider erwischen. Selbst wenn Du von Zuhause aus 10.000 Emails versendet, wird sich mit Sicherheit Dein Provider melden. Oder darfst Du soviel versenden?

      Ich denke schon das es ein virtueller host ist, aber Du glaubst es kaum, ich hatte mit dem Provider vorher über sowas gesprochen, und die sagten nur, wenn ich zuviele Recourcen verbrauche (Script über 90 Sekunden, 30 Sekunden CPU, 24MB RAM) wird das Script halt gekillt. Es sollte auch möglichst Nachts laufen, per Cronjob, was auch auch vorhabe. Ich habe soger einen etwas längeren Text reingeschrieben, und halt viel mehr mails als jemals notwendig werden - halt zum testen, was das Script so kann.
      Nochwas - von einem der ersten Tests(mit einem Script ohne Schleife - laso immer eine Mails pro durchlauf) sind heute morgen noch über 100 mails gekommen. Sowas vermute ich auch bi meinen 500, übrigens nicht ganz 5000, insgesamt müßten 10321 Mails kommen, es sind aber nur 5334 angekommen. Die ungerade Zahl kommt daher, das ich keine Schranke in die eigentliche Schleife eingebaut habe, sondern bei Anzahl mails > 10.000 keinen weiteren Durchlauf mit fsockopen() mehr mache.

      Grüße
      Andreas

  4. Hallo Andreas,

    exakt 5.000 ? oder eher etwa 5.000 ? mails die nicht durchgekommen sind?
    Bei exakt 5.000 würde ich auf 'nen Fehler in deinem Script tippen ;-) Bei mehr (eher weniger) als 5.000 würde ich auf ein mir auch schon aufgefallenes - allerdings nicht in diesen Dimensionen - Problem im Zusammenspiel Server <-> sendmail tippen.

    Rück mal noch paar Info's raus, auf welcher Konfiguratrion das passiert ist.

    Davon abgesehen, um 10.000 Mails an eine Liste zuschicken (oder solltest du dich bei der Entwicklung dieses php-scriptes gar mit dem Gedanken "spam" befassen?) gibt es mit Sicherheit andere gut funktionierende Möglichkeiten - natürlich auch wieder abhängig von deiner Serverumgebung.

    Gruß

    aus dem schönen Neckartal (*autsch* jetzt hat mich der ChSch-Virus auch erwischt)

    der_bernd

    1. Hi!

      exakt 5.000 ? oder eher etwa 5.000 ? mails die nicht durchgekommen sind?

      nein, nicht ganz 5000, insgesamt müßten 10321 Mails kommen, es sind aber nur 5334 angekommen. Die ungerade Zahl kommt daher, das ich keine Schranke in die eigentliche Schleife eingebaut habe, sondern bei Anzahl mails > 10.000 keinen weiteren Durchlauf mit fsockopen() mehr mache.

      Bei exakt 5.000 würde ich auf 'nen Fehler in deinem Script tippen ;-) Bei mehr (eher weniger) als 5.000 würde ich auf ein mir auch schon aufgefallenes - allerdings nicht in diesen Dimensionen - Problem im Zusammenspiel Server <-> sendmail tippen.

      Die erste und letzte sind aber da, immer zwischendurch fehlen mal mehr und mal weniger, gegen Ende eher mehr, aber von Anfang an.

      Rück mal noch paar Info's raus, auf welcher Konfiguratrion das passiert ist.

      In der phpinfo() steht zu Server Software:
      Apache/df-exts 1.2 (Unix) mod_ssl/2.8.7 OpenSSL/0.9.6c AuthPG/1.2, ist soweit ich weiß Linux, PHP 4.1.2, genaua Apache Version weiß ich nicht. Emails werden halt über sendmail verschickt, wie Du im Script siehst mache ich das mit mail()

      Das das Virtuelle Hosts sind, gehe ich jetzt einmal von aus, weiß es aber nicht sicher.

      Davon abgesehen, um 10.000 Mails an eine Liste zuschicken (oder solltest du dich bei der Entwicklung dieses php-scriptes gar mit dem Gedanken "spam" befassen?) gibt es mit Sicherheit andere gut funktionierende Möglichkeiten - natürlich auch wieder abhängig von deiner Serverumgebung.

      Nein doch kein SPAM!!!! Niemals!!! Ich wollte erstmal nur sehen, was ich in diese Richtung so hinbekomme. Das Script wird dann später für gewlhnliche Newsletter verwendet, die sehr viel weniger Adressen haben werden, und über ein eigenes kleines CMS der Seite zu bedienen sind. Im Prinzip ist das ja gar nicht so kompliziert - wenn die mails jetzt alle angekommen wären!!!

      Ich wollte halt wie gesagt mal einen kleinen Belastungstest machen, und immerhin, nichtmal 30 Minutern hat das alles gedauert, im Schnitt über 5 Mails pro Sekunde. Und wenn mails fehlten, war da auch eine dem entsprechend große zeitliche Lücke (!!!), daher gehe ich davon aus, das alle mails erfolgreich gesendet wurden! Bis jetzt jhatte ich es schon öfter, das eine mail, oder ein paar mehr erst Minuten/Stunden später ankamen! Sowas in einer sehr viel größeren Domension befürchte ich jetzt auch! Und vielleicht hat das jemand von Hand aussortiert, man weiß es nicht :)

      Ich bin Ratlos, habe mich auch schon an den Provider gewand, naja, mal schaun.

      Grüße
      Andreas

      Gruß

      aus dem schönen Neckartal (*autsch* jetzt hat mich der ChSch-Virus auch erwischt)

      der_bernd

  5. Hi!

    Hallo!
    Habe mir ein neues Newsletterscript gebastelt. Das Script

    Ich werde demnächst auch vor dem Problem stehen, daß ich regelmäßig eine Art Newsletter verschicken muß und befürchte, daß ich dann wahrscheinlich auch mit dem Timeout des Providers in Konflikt komme. Ich hab' da mal ein bißchen rumgestöbert und bin schon des öfteren auf den Hinweis gestoßen, daß mail() für den Versand einer größeren Anzahl von Mails nicht so gut geeignet ist, weil es für jede Mail erneut eine Verbindung zum SMTP aufbaut. Besser soll es sein, selber ein Verbindung aufzubauen und dann gleich eine ganze Portion Mails auf einmal zu übergeben. Vielleicht probierst du's mal auf diesem Weg. Es gibt da natürlich auch schon 'ne Menge fertige Skripte. Hab' mal auf die Schnelle zwei bei Zend 'rausgesucht:

    http://www.zend.com/codex.php?id=347&single=1
    http://www.zend.com/codex.php?id=708&single=1

    Vielleicht hilft's dir weiter.
    Würd' mich interessieren, wie du's letztlich lösen konntest.

    Grüße
    Andreas

    Gruß,
    (auch) Andreas

  6. Hallo,

    Habe mir ein neues Newsletterscript gebastelt. Das Script funktioniert so:

    Ich bekam auch eine Anfrage bezüglich eines Newsletter Scriptes für grössere Datenbestände und habe mir diesbezüglich einige Gedanken gemacht. Da ich vermutet habe das der Server bei vielen Mails nicht mehr mitkommt - wie es bei Dir der Fall ist - habe ich mir ein paar Gedanken dazu gemacht:

    Die e-Mail Adressen sind ja eh in einer Datenbank gespeichert. Die Tabelle könnte z.B. so aussehen

    id  |  adresse  |  gesendet (default 0)

    Nun lässt man per cronjob/scheduler (jede Minute?) ein paar e-Mails (etwa 50?) versenden. Die e-Mail Adressen holst Du Dir aus der Datenbank. Nach dem Versenden einer e-Mail setzt Du in der entsprechenden Zeile den Wert für gesendet auf 1. Die Spalte gesendet dient sozusagen als flag.

    Und schon geht es wieder von vorne los. Script wird per cron gestartet und holt sich ein paar e-Mail Adressen aus der Datenbank - und zwar nur diejenigen Adressen die noch nicht versendet wurden, d.h. gesendet = 0.

    Ob das eine optimale Idee ist kann ich Dir leider nicht sagen, da ich es in der Praxis noch nicht umgesetzt habe.
    Leider gibt es hierfür keine richtige Transaktionssicherheit und einen cronjob der jede Minute gestartet wird ist vielleicht auch nicht optimal.

    Viele Grüße
    Andreas