PHP-Script verursacht Apache-Absturz

Alles, was PHP betrifft, kann hier besprochen werden.

PHP-Script verursacht Apache-Absturz

Postby kschroeder » 15. May 2007 14:29

Hallo,

ich hab ein schwerwiegendes Problem mit einem bestimmten PHP-Script.
Dieses Script greift über die COM-Schnittstelle auf eine ziemlich große Lotus-Notes-Datenbank zu, um Statistikwerte zu ermitteln und anzuzeigen.

Das Script wird derzeit alle 10 Minuten aufgerufen, soll aber eigentlich sogar häufiger laufen.

Das Problem ist, dass es irgendwann, nach einer Weile und zahlreichen erfolgreichen Aufrufen, mal kürzer, mal länger, zu einem Speicherproblem kommt, d.h. ich erhalte die Fehlermeldung: Fatal error: Failed to allocate memory ...
Alle anderen Seiten haben dann auch das Problem und ich muss den Server manuell stoppen und neustarten.

Ich dachte, ich wäre das Problem eventuell los, nachdem ich PHP auf Version 5.2.2 gehoben hatte. Ansonsten läuft MySQl in Version 5.0.41 und Apache 2.2.4.

Offenbar scheint es ein Speicherproblem zu geben, wo PHP den Speicher nicht sauber freigibt. Ich hab aber keine Idee, wie ich PHP eventuell am Ende des Scripts oder sonstwo beibringen kann, überflüssigen Speicher wieder freizugeben. Oder das Script sonstwie zu optimieren.

Anbei ist der PHP-Teil des Scripts, im HTML-Teil wird lediglich noch eine Tabelle mit den Werten ausgegeben.

Code: Select all
$session = new COM( "Lotus.NotesSession" );
if (!$session) {
   echo "Konnte Com-Objekt nicht erzeugen!!!<br>";
   exit;
}
$session->Initialize('kennwort');

//echo "Current user: " . $session->UserName . "<br><br>\n\n";

$db = $session->getDatabase( "192.168.1.1", "Spam.nsf", false );

if (!$db) {
   echo "Konnte Datenbank nicht öffnen!!!<br>";
   exit;
}

$view = $db->getView( "Spam Statistics" );
if (!$view) {
   echo "Konnte View aus der DB nicht öffnen!!!<br>";
   exit;
}

$entry = $view->GetFirstDocument();
if (!$entry) {
   echo "Konnte Zeiger nicht auf den ersten Satz stellen!!!<br>";
   exit;
}

$aktdatum = date("d.m.Y");
$aktjahr = date("Y");
$aktmonat = date("m");

$nmonat = $aktmonat * 1;
$amonat = array("Dummy","Januar","Februar","M&auml;rz","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember");
$textmonat = $amonat[$nmonat];


$j_inbound = 0;
$j_blocked = 0;
$j_prozent = 0;
$m_inbound = 0;
$m_blocked = 0;
$m_prozent = 0;
$d_inbound = 0;
$d_blocked = 0;
$d_prozent = 0;
while (is_object($entry)) {

   $field = $entry->GetFirstItem( "LogDate" );
   $created = $field->text;
   $datum = substr($created,0,10);
   $jahr = substr($created,6,4);
   $monat = substr($created,3,2);

   if ($jahr == $aktjahr) {
      $field = $entry->GetFirstItem( "InboundMessages" );
      $allemails = $field->text;
      $field = $entry->GetFirstItem( "BlockedSpamCop" );
      $feld1 = $field->text;
      $field = $entry->GetFirstItem( "BlockedSpamnet" );
      $feld2 = $field->text;
      $field = $entry->GetFirstItem( "BlockedDomains" );
      $feld3 = $field->text;
      $field = $entry->GetFirstItem( "BlockedWords" );
      $feld4 = $field->text;
      $field = $entry->GetFirstItem( "BlockedSubjects" );
      $feld5 = $field->text;
      $field = $entry->GetFirstItem( "BlockedRecipients" );
      $feld6 = $field->text;
      $field = $entry->GetFirstItem( "BlockedInvalidRecipients" );
      $feld7 = $field->text;
      $geblockt = $feld1+$feld2+$feld3+$feld4+$feld5+$feld6+$feld7;

      $j_inbound += $allemails;
      $j_blocked += $geblockt;
      if ($monat == $aktmonat) {
         $m_inbound += $allemails;
         $m_blocked += $geblockt;
      }
      if ($datum == $aktdatum) {
         $d_inbound = $allemails;
         $d_blocked = $geblockt;
      }
   }
   $entry = $view->getNextDocument($entry);
}
$session = null;
unset($session);

if ($d_inbound > 0) {
   $d_prozent = round($d_blocked * 100 / $d_inbound, 2);
}
if ($m_inbound > 0) {
   $m_prozent = round($m_blocked * 100 / $m_inbound, 2);
}
if ($j_inbound > 0) {
   $j_prozent = round($j_blocked * 100 / $j_inbound, 2);
}
$d_inbound = number_format($d_inbound,0,"",".");
$d_blocked = number_format($d_blocked,0,"",".");
$m_inbound = number_format($m_inbound,0,"",".");
$m_blocked = number_format($m_blocked,0,"",".");
$j_inbound = number_format($j_inbound,0,"",".");
$j_blocked = number_format($j_blocked,0,"",".");
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33

Postby KingCrunch » 15. May 2007 21:15

Hinter "Fatal Error..." steht bestimmt noch eine Zeilennummer. Wär schön noch die passende Zeile zu bekommen.
Nicht jeder Fehler ist ein Bug ...
KingCrunch
 
Posts: 1724
Joined: 26. November 2005 19:25

Postby kschroeder » 16. May 2007 05:52

Sorry, hab's vergessen zu erwähnen:
Der Fehler wird direkt für die erste Zeile des Scripts ausgegeben:

Code: Select all
$session = new COM( "Lotus.NotesSession" );
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33

Postby Mätes » 16. May 2007 07:54

ich kann dir nur berichten, das ich vor mehreren Jahren
spaßenshalber per PHP eine Excel-Datei auslesen wollte,
auch über COM-Schnittstellen.

Nach dem zigsten Absturz und keinen Lösungsvorschlägen aus
foren, sondern eher negativen Erfahrungen anderer, und
diversen 'keine Garantie'-Hinweisen in Manuals, habe
ich es dann gecancelt.

wünsche dir mehr glück.
ma
User avatar
Mätes
 
Posts: 142
Joined: 13. April 2006 09:34
Location: kölle

Postby kschroeder » 16. May 2007 09:22

Tatsache ist, dass das Script vor der Serverumstellung einwandfrei lief. Das heisst, der Server lief absolut stabil. Ich hab den Server innerhalb von zwei Jahren vielleicht zwei oder drei Mal neugestartet.
Mittlerweile geniesst der Server aber immer mehr Traffic und daher hab ich einen neuen Server angeschafft. --> Performance
Und wo ich schonmal dabei war, hab ich auch gleich die Versionen alle aktualisiert. Also Apache neu, PHP neu, MySQL neu.
Das hat mir gerade auf MySQL-Seite ziemlich viel Arbeit eingebracht, da der Sprung von der alten DB zur neuen doch ziemlich groß war (kannte vorher noch keine Kollation etc.)

Seit dem läuft der Server nicht mehr sauber und ich hab letztendlich das Script dafür verantwortlich machen können, denn ohne diesem Script läuft der Server auch stabil.

Damit die Com-Schnittstelle funktioniert, muss ich ja den Notes-Client auf dem Server installieren, damit die erforderlichen Dlls vorhanden sind...
Ich befürchte, dass diese nicht sauber mit PHP5 arbeiten und daher die Speicherprobleme verursachen.

Ich möchte aber nahc Möglichkeit vermeiden auf PHP4 zurückzugehen, denn eigentlich sollte eine Version 5.2.2 mittlerweile ausgereift stabil laufen, oder?
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33

Postby KingCrunch » 16. May 2007 16:34

Aussm Bauch raus würde ich sagen, dass der Garbage Collector von PHP und/oder Lotus nicht sauber (zusammen?!) arbeiten. Es handelt sich ja irgendwie um eine Session-Verwaltung, soweit ließ sich dem Variablen entnehmen. Wie das nun genau per COM-Schnittstelle abläuft, hab ich leider keine Ahnung, aber offensichtlich läuft der Speicher ja nach einiger Zeit voll. Is diese Lotus-Session-Geschichte Speicher- oder Datei-Basiert?
Nicht jeder Fehler ist ein Bug ...
KingCrunch
 
Posts: 1724
Joined: 26. November 2005 19:25

Postby kschroeder » 20. May 2007 19:35

Ich gehe schwer davon aus, dass es eine Speicher-basierte Geschichte ist, aber sicher bin ich mir natürlich auch nicht.
Ich werd wohl mal auf die 4er PHP-Version umstellen müssen und dann nochmal testen.
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33


Return to PHP

Who is online

Users browsing this forum: No registered users and 48 guests