Beitragsupervisior » 22.04.2022, 12:13 Sind hier Wordpress Nerds unterwegs?
Ich hab mit Unterstützung vom @HanzoDingenskirchen einen Crawler entwickelt, der dazu dient einen HTTP Cache aufzuwärmen. Nachdem ich diesen Crawler nun an die Bedürfnisse von WP anpasse, ist mir etwas aufgefallen, das sich so bei anderen CMS nicht finden lässt.
Um den Crawler auch für extreme Bedingungen zu testen, habe ich eine WP Installation mit mehreren 1000 Post befüllt und dann den Crawler darauf angesetzt. Das besondere an diesem Crawler ist, dass dieser parallel arbeitet und es dadurch möglich ist bis zu 100.000 URLs binnen 1 Std. zu crawlen und das auch auf einem Shared Hosting. Normalerweise würde man da bei der Script Ausführung als erstes ein Timeout Problem bekommen, aber das lässt sich beim LSWS deaktivieren. Nichtsdestotrotz steigt mir nach einer gewissen Zeit der Datenbank Server aus. Ich hatte erst den Verdacht, dass das durch die parallen Aufrufe kommt, weil ich Daten aus dem Response, bzw. aus dem Response Header in die DB schreibe. Daran liegts aber nicht. Es scheint wohl so zu sein, dass WP die Datenbank Verbindung nach einem Seitenaufruf nicht sofort wieder schließt. Wenn ich damit richtigliege, und danach sieht es aus, könnte man jede WP Installation mit vergleichsweise geringem Aufwand abschießen. Also noch nicht mal einen Denial of Service Angriff, sondern ganz einfach mit einem Crawler. Man muss nur genügend URLs aufrufen.
Weiß da jemand was darüber, ob WP das tatsächlich so macht, wie ich meine?
Beitragstaticweb » 22.04.2022, 17:06 Sind hier Wordpress Nerds unterwegs?
Es gibt eine Verbindung die vom wpdb Objekt verwaltet wird. Spätestens wenn das script beendet wird ist auch die DB Conn weg. Was sich da auf Netzwerkebene abspielt kannst du leicht selbst überprüfen. Auf alle Fälle wäre das Problem bekannt. Vielleicht ist der Wert für max_connections zu gering für deine Simultanabfragen.
Beitragsupervisior » 22.04.2022, 17:13 Sind hier Wordpress Nerds unterwegs?
Wenns dem so ist, wie ich im Moment nur vermute und ich erst noch weiter untersuchen muss, dann muss das kein Bug, sondern kann auch ein Feature sein, weil wenn die DB Verbindung offen bleibt, könnte zumindest theoretisch der nächste Seitenaufruf schneller gehen. Ist aber nur eine Theorie. Ich weiß aber von anderen Anwendungen, dass man das durchaus so praktiziert hat, zumindest in der Vergangenheit. Unter HTTP 1.1 gabs/gibts so was, aber das bezieht sich nicht auf DB Verbindungen. Es gibt aber auch aktuelle Anwendungen, die das noch unter dem Begriff "persistent connections" unterstützen.
Beitragsupervisior » 22.04.2022, 17:17 Sind hier Wordpress Nerds unterwegs?
Ich bin jetzt nicht der MySQL Experte, aber dass eine DB Verbindung nach dem Beenden eines PHP Prozesses automatisch beendet wird, stelle ich mal in Frage, weil wofür gibt es dann mysqli_close? PHP sagt zwar, dass es optional wäre, aber es besser wäre, wenn man die Anweisung zum Schließen explizit geben sollte.
Beitragsupervisior » 22.04.2022, 17:27 Sind hier Wordpress Nerds unterwegs?
In Deiner letzten Antwort könnte aber trotzdem die Lösung liegen. Wenn es so ist, wie Du sagst, dann wäre es nur folgerichtig, dass der DB Server aussteigt. Der PHP Prozess für das Crawlen kann auch mal 1 Stunde dauern. Von daher wäre es kein Wunder, dass das dem DB Server zu lange dauert. Also probier ich mal was aus....
Beitragstaticweb » 22.04.2022, 18:07 Sind hier Wordpress Nerds unterwegs?
> wofür gibt es dann mysqli_close
Natürlich um die Verbindung vorzeitig zu beenden. Das spart Ressourcen, ist aber bei WP nicht notwendig, bzw. u.U. "gefährlich". Eine entsprechende wpdb Methode wurde in Version 4.5 hinzugefügt.
Beitragsupervisior » 22.04.2022, 18:15 Sind hier Wordpress Nerds unterwegs?
Im Moment versuche ich noch herauszufinden, was das Aussteigen des DB Servers verursacht, weil ich gleich mehr MySQL Queries in meinem Crawler habe, wobei der Verdacht naheliegt, dass es nicht das eigentliche Crawlen ist, sondern das Reporting. Optional und wenn aktiviert, schreibe ich Header Informationen aus dem Response in die DB und das sind dann schon mal gleich mehrere zig-tausend. Die können natürlich nicht alle gleichzeitig in die DB geschrieben werden, sondern nur in einer Schleife. Mit deaktiviertem Logging habe ich das Problem mit großer Wahrscheinlichkeit nicht. Was ich im Moment ausprobiere, ist dass ich die Response Daten nicht on-the-fly in die DB schreibe, sondern erstmal in ein *.sql file, das ich am Ende der Crawling Session inserte. Ob das was löst, weiß ich nicht. Bin grad noch am machen....
Beitragsupervisior » 22.04.2022, 20:01 Sind hier Wordpress Nerds unterwegs?
Alles zurück zum Anfang. Durch die parallele Arbeistweise des Crawlers ist es schlichtweg unmöglich erhauszufinden, was die DB Verbindung zu lange offen hält. Zumal ich das Ganze bewusst auf einem Shared Hosting ausprobiere. Das macht das Ganze ungemein schwierig, weil es nicht die Last ist, die ich selber erzeuge, sondern sich ausgesprochen dynamisch verhält, also in Abhängigkeit zur Gesamtlast des Servers. Was vor 5 Min. noch problemlos funktioniert hat, geht 5 Min später schon nicht mehr. Sicher ist im Moment nur, dass es nicht an der Menge an Insert Queries liegt und WP selbst auch aus dem Schneider ist, weil ich das gleiche Phänomen auch bei anderen Anwendungen feststellen kann. Das war heute Morgen aber nicht so... Zefix!
Beitragsupervisior » 25.04.2022, 08:58 Sind hier Wordpress Nerds unterwegs?
Inzwischen bin ich zumindest schon 10x weiter wie am Anfang und hab jetzt zumindest 2 neue Optionen. Das eigentliche Problem war aber nicht, dass zu viele Daten in die DB geschrieben werden und es zu lange dafür dauern könnte. Das Problem war/ist viel früher gelagert. Ich hole mir zunächst die URLs aus der Sitemap.xml, parse diese und schreibe diese in die DB. Danach hole ich mir diese URLs wieder, um sie mit cURL aufzurufen. Das Problem ist nun, dass die DB Verbindung um die URLs aus der DB abzurufen eigentlich geschlossen werden könnte, aber das tut es erst, wenn alle URLs aufgerufen wurden. Das ganze ist also ein timeout Problem. Die Verbindung wird zu lange wegen Inaktivität offen gehalten, eben weil diese erst geschlossen wird, wenn das Aufrufen der URLs fertig ist. Dafür brauche ich aber die DB Verbindung nicht mehr.
Die Lösungsvariante würde nun darin bestehen das Ganze zu splitten und komplett DB-los zu machen, zumindest das parsen der Sitemap.xml mit anschließendem Schreiben in die DB und das erneute holen. Ich schreib die geparsten URLs einfach in ein File und mit lese dieses File in dem nur mehr noch die URLs stehen einfach wieder aus. So zumindest der Lösungsgedanke, um das timeout Problem wegen Inaktivität zu umgehen.