Rest-API Performance Probleme

Hallo zusammen, wir haben hier eine Schnittstelle zum Bestands- und Preisabgleich zwischen Warenwirtschaft und Shopware Rest-API geschrieben. Diese Schnittstelle bekommt alle 5 Minuten geänderte Artikeldaten aus der Warenwirtschaft und aktualisiert damit dann die Daten in Shopware. Wenn wir nur den Wert “inStock” aktualisieren, dann dauert das Update von ca. 75 geänderten Artikeln ca. 5 Sekunden. Als Identifier verwenden wir die OrderNumber. Der Code sieht so aus: /\* Compute article data array \*/ $ArticleDataUpdate = array(); for($i = 0; $i \< count($ChangedArticles); $i++) { $ArticleDataUpdate[] = array( 'mainDetail' =\> array( 'number' =\> $ChangedArticles[$i]["EAN"], 'inStock' =\> $ChangedArticles[$i]["Bestand"], ), ); } /\* Output articles array for shopupdate \*/ //print\_r($ArticleDataUpdate); /\* Put data \*/ $articles = $client-\>put('articles/',$ArticleDataUpdate); Wenn wir nun nicht nur den Wert “inStock” sondern auch den Werte “changed” anpassen, dann dauert das Update unverhältnismäßig viel länger. Beim Beispiel mit 70 geänderten Artikeln sind es dann ca. 250 Sekunden. Der Code sieht dann so aus: /\* Compute article data array \*/ $ArticleDataUpdate = array(); for($i = 0; $i \< count($ChangedArticles); $i++) { $ArticleDataUpdate[] = array( 'mainDetail' =\> array( 'number' =\> $ChangedArticles[$i]["EAN"], 'inStock' =\> $ChangedArticles[$i]["Bestand"], ), 'changed' =\> $RunTime, ); } /\* Output articles array for shopupdate \*/ //print\_r($ArticleDataUpdate); /\* Put data \*/ $articles = $client-\>put('articles/',$ArticleDataUpdate); Ich hatte auch probiert, als Identifier die ArtikelID anstatt der OrderNumber zu vewenden. Aber auch das löst das Performance Problem nicht. Der Code dazu sieht dann so aus: /\* Compute article data array \*/ $ArticleDataUpdate = array(); for($i = 0; $i \< count($ChangedArticles); $i++) { $ArticleDataUpdate[] = array( 'id' =\> $ChangedArticles[$i]["ArtikelID"], 'mainDetail' =\> array('inStock' =\> $ChangedArticles[$i]["Bestand"]), 'changed' =\> $RunTime, ); } /\* Output articles array for shopupdate \*/ //print\_r($ArticleDataUpdate); /\* Put data \*/ $articles = $client-\>put('articles/',$ArticleDataUpdate); Wir möchten den Werte “changed” bei der Aktualisierung neu setzen, damit die Änderungen auch im Frontend sichtbar werden. Nach unserer Erfahrung werden Preis- und Bestandsänderungen erst im Frontend sichtbar, wenn das Changed-Datetime neu ist und somit die Cache-Datei für den einzelnen Artikel neu generiert wird. Da das Skript alle 5 Minuten läuft, kann es nun sein, dass dieses schon wieder neu gestartet wird, obowohl die vorherige Aktualisierung noch nicht abgeschlossen ist. Wir haben im Shop ca. 7.500 Artikel. Wenn ich alle Artikel direkt aus der Datenbank auslese, dann dauert das 0,5 Sekunden. Ich frage mich nun, ob ich das Thema Rest-API für diesen Zweck beiseite legen muss und die Aktualisierung direkt in die Datenbank laufen lasse, via MySQL. Wird beim Artikel-Update über die Rest-API noch mehr gemacht, als nur die Daten in der Datenbank zu ändern? Vielen Dank für Eure Hilfe, Jan

Hier noch folgende Ergänzung bzgl. der Zeitunterschiede. Ohne den Wert “changed”: 2015-08-25T17:20:10+02:00: Aktualisierte Artikel im Shop: 13 (REST-Processing-Time: 0.94709587097168 Sek.) 2015-08-25T17:25:10+02:00: Aktualisierte Artikel im Shop: 6 (REST-Processing-Time: 0.7804229259491 Sek.) 2015-08-25T16:25:10+02:00: Aktualisierte Artikel im Shop: 16 (REST-Processing-Time: 0.63694596290588 Sek.) Mit dem Wert “changed”: 2015-08-25T17:29:24+02:00: Aktualisierte Artikel im Shop: 35 (REST-Processing-Time: 29.653499126434 Sek.) Was macht das so langsam, wenn man “changed” setzt? Wenn der Wert “changed” ebenfalls aktualisiert wird, dann wird auch der neue Bestand sofort auf der Artikeldetailseite sichtbar (so möchte ich es auch haben). Wenn der Wert “change” nicht aktualisiert wird, dann stimmt zwar der Bestand im Backend und es können auch nicht mehr Artikel bestellt werden, als verfügbar, aber die Bestandsansicht auf der Artikeldetailseite zeigt noch den Wert von vor der Aktualisierung an. Jan

Hi, deaktiviere mal probeweise die Funktion “Automatische Cache-Invalidierung” unter Einstellungen->Cache/Performance->Einstellungen->Http-Cache. Das ist die Funktion, die dafür sorgt, dass der Cache für einen Artikel nach dem Update gelöscht wird (also eigentlich genau das, was du willst.). Meine Vermutung wäre, dass die automatische Cache-Invalidierung (warum auch immer) gerade nur bei Änderungen auf dem Artikel-Model greift. Entsprechend hinge es nicht am “changed” date, sondern nur daran, dass ihr überhaupt was am Artikel ändert. Vermutung 2 ist, dass die Cache-Invalidierung bei dem Shopware-Reverse-Proxy relativ langsam sein kann, weil er dazu auf dem Dateisystem viele Cache-Dateien durchsuchen muss, um die “richtigen” zu löschen. Wenn es mit deaktivierter Cache-Invalidierung schneller geht, liegt es tatsächlich daran. Probeweise könntest du erstmal die ganzen API-Updates fahren und dann den Cache manuell leeren - mit einem DELETE call gegen “dein-shop.de/api/cache/http”. Dabei wird aber der gesamte HTTP-Cache geleert - also sicher auch keine dauerhafte Lösung. Alternativ würde varnish helfen - das wäre ein “richtiger” HTTP-Cache, der deutlich schneller invalidieren kann. Weiterhin alternativ könnte man überlegen, das HTTP-Cache-Verzeichnis in eine Ram-Disk zu packen, müsstet ihr aber evaluieren, ob das gut für euch funktioniert. So oder so: Probiere das mal mit der deaktiviereten “Cache invalidieren” Funktion, würde mir helfen, das einschätzen zu können. Gruß, Daniel

Hi Daniel, vielen Dank für deine Rückmeldung. Wir sind bei AIXPRO als Hoster auf SSD mit NGINX. Wir setzen jedoch kein Varnish ein, weil der Shop komplett auf SSL läuft. APCu und Zend OPcache sind aktiviert. PHP Version 5.4.X. Nach einem Tag ist der Cache mehrere GB groß. D.h. es könnnte also schon sein, dass das Auffinden der korrekten Cache-Datei eine Weile dauert. Mir ist auch aufgefallen, dass wenn wir Artikel im Backend pflegen, das Speichern eine ganze Weile (2-3 Sekunden) dauert. Ich habe jetzt mal den kompletten Cache geleert und anschließend wieder beide Skripts laufen lassen. 1x mit Changed und 1x ohne. Das sind jetzt die Zeiten dafür: Ohne Changed: 2015-08-26T17:13:20+02:00: Aktualisierte Artikel im Shop: 58 (REST-Processing-Time: 1.227306842804 Sek.) Mit Changed: 2015-08-26T17:14:03+02:00: Aktualisierte Artikel im Shop: 58 (REST-Processing-Time: 7.5622308254242 Sek.) Jetzt sind wir also schonmal schneller als mit vollem Cache. Wenn ich die Cache-Invalidierung herausnehme, dann sieht es so aus: Ohne Changed: 2015-08-26T17:21:24+02:00: Aktualisierte Artikel im Shop: 61 (REST-Processing-Time: 1.545490026474 Sek.) Mit Changed: 2015-08-26T17:22:01+02:00: Aktualisierte Artikel im Shop: 60 (REST-Processing-Time: 1.0274710655212 Sek.) D.h. die Performance ist gleich oder in diesem Fall sogar schneller. Die Cache-Invalidierung ist also der Grund, warum es so viel länger dauert! Wenn also nur ein Wert in der s_articles_details geändert wird, dann greift die Cache-Invalidierung nicht. Wenn ein Wert in s_articles geändert wird, dann wird auch die Cache-Datei gelöscht. AIXPRO bietet auch ein Paket mit Varnish an. Wäre das deiner Meinung nach die Lösung? Ich hatte es so verstanden, dass Varnish nichts nutzt, wenn der Shop komplett auf SSL läuft. Hast du noch eine Idee oder Tipp oder liege ich mit Varnish und SSL falsch. Danke. Jan

Hi, Varnish selbst kann kein SSL-Offloading, darum hat man in der Regel davor noch einen Nginx o.ä. der das Offloading macht, den Request an den Varnish weiterleitet - und der kümmert sich dann um den Rest. Funktioniert also prinzipiell schon, haben auch einige Kunden so im Einsatz und macht auch durchaus Sinn, ist halt nur etwas mehr Konfigurationsaufwand. Du kannst auf jeden Fall auch nochmal ein Ticket dafür anlegen - damit die Core-Jungs das auf dem Schirm haben :slight_smile: Schönen Gruß, Daniel