PrestaShop-Shop während eines Ausverkaufs langsam? Finden Sie heraus, welche Ebene zuerst leer war.

Die Kampagne startet um 9 Uhr. Der Traffic verdreifacht sich bis 9:20 Uhr. Produktseiten laden acht Sekunden lang, der Warenkorb bleibt bei „In den Warenkorb“ hängen, und ein Kunde schickt einen Screenshot einer 504-Fehlermeldung. Sie starten PHP neu, der Shop funktioniert wieder, und das Werbebudget hat die beste Stunde des Tages bereits verbraucht.

Wenn ein PrestaShop-Shop während eines Sales langsam läuft, liegt es selten an der Bandbreite, sondern an der gleichzeitigen Nutzung. Zehn und vierhundert Kunden zu bedienen, sind unterschiedliche Aufgaben für dieselbe Hardware: Jeder nicht zwischengespeicherte Seitenaufruf belegt einen PHP-Prozess für seine gesamte Laufzeit, nutzt ein oder zwei Datenbankverbindungen und konkurriert mit allen anderen Prozessen um CPU und Arbeitsspeicher. An einem ruhigen Dienstag erreicht man diese Kapazitätsgrenze nie. Nach zwanzig Minuten einer Kampagne ist sie jedoch erreicht.

Die Aufgabe besteht also darin, herauszufinden, welche Ebene zuerst an ihre Grenzen stieß. Sechs mögliche Szenarien decken die meisten Vorfälle ab: unvollständig konfiguriertes Caching, nicht zwischengespeicherte dynamische Seiten, Datenbankkonflikte, ein ressourcenintensives Modul innerhalb eines Hooks, Hosting, das nur für durchschnittliche Tage ausgelegt ist, und ein Frontend, das für Smartphones zu ressourcenintensiv ist. Jeweils ein Abschnitt dazu folgt.

1.0 Was passiert tatsächlich mit PrestaShop bei Traffic-Spitzen?

Verfolgen Sie eine Produktseitenanfrage. Apache oder Nginx empfängt sie und leitet sie an einen PHP-FPM-Worker weiter. Dieser Worker hat nun eine lange Liste von Aufgaben zu erledigen: den Kernel starten, den Controller auflösen, alle registrierten Hooks eines Moduls ausführen, Preise, Lagerbestände und Warenkorbregeln von MySQL abfragen, die Smarty-Templates rendern und das HTML zurückgeben. Er ist währenddessen durchgehend beschäftigt. Der nächste Besucher wartet, bis die Verarbeitung abgeschlossen ist.

Die maximale Anzahl an Prozessen ist schwer zu bestimmen. Angenommen, der Prozesspool erlaubt 20 gleichzeitige PHP-Prozesse und das Laden einer Produktseite dauert 800 ms. Damit sind maximal etwa 25 Seiten pro Sekunde möglich, unabhängig von der Bandbreite. Werden 60 Seiten pro Sekunde geladen, staut sich der Überschuss in der Warteschlange, führt zu Verzögerungen und schließlich zum Erreichen des `max_execution_time`-Limits oder des Lesetimeouts des Proxys. Dann treten 502- und 504-Fehler auf.

Was passiert eigentlich mit PrestaShop bei einem Traffic-Anstieg?

Das Unangenehme daran ist, dass sich das Problem selbst verstärkt. Langsame Seiten halten die Mitarbeiter länger auf, die Warteschlange wird länger, die Seiten laden noch langsamer, und die Kunden, die es satt haben zu warten, aktualisieren die Seite, wodurch die Last noch weiter ansteigt. Shops verschlechtern sich während Rabattaktionen nicht sanft. Sie sehen einwandfrei aus, und zwei Minuten später sind sie verschwunden.

Die Time to First Byte (TTFB) ist die entscheidende Kennzahl. jPresta interpretiert eine TTFB über einer Sekunde als Indiz dafür, dass serverseitig etwas Aufmerksamkeit erfordert, was durchaus plausibel erscheint. Wenn Sie an einem ruhigen Montag bereits nahe an diesem Wert liegen, ist für eine Kampagne nichts mehr übrig.

Checkliste 2.0: PrestaShop-Shop während des Sales langsam – wo Sie zuerst suchen sollten

Gehen Sie diese Liste durch, bevor Sie sich für eine Theorie entscheiden. Fünfzehn Minuten, und meistens haben Sie so den Übeltäter gefunden.

  • Debug-Modus: ist _PS_MODE_DEV_ Oder ist der Profiler noch immer aktiv von Ihrer letzten Untersuchung?
  • SmartySteht in den Template-Einstellungen „nie neu kompilieren“ oder wird bei jeder Anfrage neu kompiliert?
  • CCCSind die CSS- und JavaScript-Caches tatsächlich aktiviert?
  • Cache-Back-End: Alles, was über das Dateisystem hinausgeht, wie z. B. APCu, Memcached oder Redis?
  • ArbeitskräfteWas ist pm.max_childrenUnd wie viele waren zur Hauptsaison beschäftigt?
  • Langsame AbfragenEnthält das Protokoll der langsamen Abfragen irgendwelche Daten aus dem Verkaufsfenster?
  • ModuleWurde für diese Kampagne ein Promotion-, Countdown- oder Popup-Modul eingesetzt?

3.0 Ursache 1: Caching, das aktiviert zu sein scheint, aber nicht aktiviert ist.

Beginnen Sie unter Erweiterte Parameter → Leistung . Die günstigste Option im Backend und die Seite, die am häufigsten falsch eingestellt ist.

Templates werden in PHP kompiliert, bevor sie den Browser erreichen. Wie oft dies geschieht, können Sie selbst festlegen. Die offizielle Dokumentation zur Performance beschreibt drei Modi; einer davon ist besonders für stark ausgelastete Shops relevant: Template-Dateien nie neu kompilieren . Wählen Sie „Neu kompilieren, wenn Dateien aktualisiert werden“, führt jede Anfrage zu einer Dateisystemprüfung für jedes Template: Bei geringem Traffic akzeptabel, bei hohem Traffic ineffizient. Die erzwungene Kompilierung ist eine Entwicklereinstellung. Wenn Sie diese während einer Kampagne aktiviert lassen, werden identische Templates tausende Male unnötig neu erstellt.

Zwei weitere Funktionen sind auf diesem Bildschirm zu sehen. Der Debug-Modus gibt Stacktraces aus und deaktiviert Optimierungen; daher sollte er in der Produktionsumgebung immer deaktiviert sein. Die Schalter zum Deaktivieren von Nicht-PrestaShop-Modulen und aller Überschreibungen dienen der Diagnose; diese Einstellungen werden nicht ausgeliefert.

4.0 PrestaShop-Caching-CCC-Konfiguration – vor dem Verkauf prüfen

Die drei Cs stehen für Kombinieren, Komprimieren und Caching. Das Ergebnis sind weniger und kleinere Asset-Dateien, die PrestaShop nicht bei jedem Seitenaufruf neu erstellen muss. Aktivieren Sie die CSS-Option; sie verursacht selten Probleme. Führen Sie zunächst einen Testlauf für JavaScript durch, da das Zusammenführen von Dateien deren Ausführungsreihenfolge ändert und manche Module dies gar nicht vertragen. Es ist besser, dies an einem Donnerstag herauszufinden als mitten im Bezahlvorgang am Black Friday.

Gut zu wissen: HTTP/2-Multiplexing verarbeitet viele kleine Dateien problemlos, daher bringt deren Zusammenfassung weniger Vorteile als früher . Minifizierung und lange Browser-Cache-Lebensdauern sind aber weiterhin sinnvoll.

Das Cache-Backend ist der letzte Schritt auf diesem Bildschirm. Standardmäßig wird das Dateisystem verwendet, und es reicht aus, bis das Volume verfügbar ist. APCu eignet sich für einen einzelnen Server, Memcached für mehrere, und Redis ist gut für Session- und Objekt-Caching geeignet. Alle lesen Daten aus dem Arbeitsspeicher statt von der Festplatte, und bei gleichzeitigem Zugriff vergrößert sich dieser Unterschied schnell.

5.0 Ursache 2: Ihre dynamischen Seiten werden nicht zwischengespeichert.

Alles in Ursache 1 reduziert die Kosten für die Seitenerstellung. Nichts davon verhindert die Seitenerstellung. PHP wird weiterhin gestartet, die Abfragen werden ausgeführt und der HTML-Code wird für jeden Besucher neu generiert, auch für die zweitausend, die innerhalb derselben Minute auf derselben Seite mit den reduzierten Kategorien landen.

Die Lösung ist Full-Page-Caching. Schalten Sie einen Reverse-Proxy vor den Webserver ( üblicherweise Varnish ), lassen Sie ihn das fertige HTML speichern, und die nächsten paar hundert Besucher werden bedient, ohne dass PHP oder MySQL aktiv werden müssen. Die Antworten kommen in einstelligen Millisekunden zurück, und Ihr Ursprungsserver verarbeitet nur die tatsächlich notwendigen Daten. An Tagen mit Blitzverkäufen kann diese eine Ebene oft den entscheidenden Unterschied zwischen einem gut funktionierenden und einem erfolgreichen Geschäft ausmachen.

Es gelten unumstößliche Regeln:

  • Sitzungsspezifische Routen bleiben draußen. Schließen Sie Warenkorb-, Kassen-, Anmelde- und Kontoseiten aus, sonst sehen Kunden irgendwann den Warenkorb eines anderen Kunden. Jedes Team, das mit einem Full-Page-Cache schlechte Erfahrungen gemacht hat, kennt dieses Problem.
  • Die Ungültigerklärung sollte vor dem Start entschieden werden. Ermitteln Sie, welche Maßnahmen einen Eintrag löschen, wenn sich der Kurs oder der Aktienkurs ändert, und testen Sie diese Löschung anschließend. Die Verwendung des gestrigen Kurses während einer Werbeaktion kostet Vertrauen und führt zu einem ganzen Morgen voller Supportanfragen.
  • Verwenden Sie ESI für die kleinen personalisierten Details. wie beispielsweise Warenkorbsummen oder der Name eines Kunden, sodass ein einzelner dynamischer Block nicht die gesamte Seite unbrauchbar macht.

Ursache 2: Ihre dynamischen Seiten werden nicht zwischengespeichert.

Datenspitzen lassen sich am besten in mehreren Schichten abfangen. Der Browser speichert, was er kann, ein CDN lädt statische Dateien, der Proxy verarbeitet HTML, Redis oder Memcached beantworten wiederkehrende Anfragen, und die Datenbank kommt nur zum Einsatz, wenn keine der darüberliegenden Schichten eine Antwort liefern kann. Viele Shops haben nur die erste und die letzte Schicht, aber keine dazwischen.

6.0 Ursache 3: Die Datenbank ist der Ort, an dem die Warteschlange tatsächlich gebildet wird

Die Worker stauen sich, weil jeder einzelne auf MySQL wartet. Die Tabellen für Warenkorb und Bestellung bleiben konstant, sodass ps_cart , ps_cart_product , ps_orders und ps_order_detail genau dann am stärksten ausgelastet sind, wenn der Checkout-Prozess besonders viel zu tun hat. Die PrestaShop-Datenbankoptimierung für Traffic-Spitzen umfasst im Wesentlichen diese vier Aufgaben:

  1. Ermitteln Sie die langsamen Abfragen anhand des Protokolls, nicht durch Intuition. Ein Standard lange Abfragezeit Zehn Sekunden sind für den Einzelhandel nutzlos, also reduzieren Sie den Wert. jPresta meint, alles über 100 ms sollte überprüft werden, und eine Datenbankzeit von mehr als der Hälfte der Seitenladezeit ist ein Warnsignal. Der Profiler liefert für jeden Hook die gleichen Ergebnisse; beschränken Sie ihn auf Ihre IP-Adresse. config/defines.inc.php Daher bekommen es die Käufer nie zu sehen.
  2. Füllen Sie den Pufferpool. InnoDB speichert Daten und Indizes im Arbeitsspeicher (RAM), sofern ausreichend Platz vorhanden ist. Auf einem dedizierten Datenbankserver werden etwa 70–80 % des Arbeitsspeichers genutzt, um den Warenkorb und die Produktseiten vom Datenträger fernzuhalten.
  3. Beschneiden Sie nur, was gefahrlos beschnitten werden kann. Abgelaufene Gastsitzungen, alte Verbindungsprotokolle und veraltete Suchstatistiken blähen Tabellen auf und verlangsamen jeden Scan. Monatlicher Cronjob, keine Panik am Verkaufstag. Warenkörbe und Bestellungen sind Geschäftsunterlagen, daher archivieren statt löschen.
  4. Verlassen Sie sich nicht auf den Abfragecache. MySQL 8.0 hat diese Funktion abgeschafft. Falls Sie also immer noch eine Datenbank verwenden, die sich wiederholte Abfragen merkt, sollten Sie Ihr Modell aktualisieren. Redis oder Memcached übernehmen diese Aufgabe nun.

Noch etwas, das oft zu Fehlern führt: `max_connections` . Setzt man diesen Wert unterhalb der Anzahl der Worker multipliziert mit der Anzahl der Verbindungen, die jede Anfrage öffnet, erhält man in Spitzenzeiten die Fehlermeldung „Zu viele Verbindungen“. Das liest sich wie ein Systemabsturz. Es ist jedoch reine Arithmetik.

7.0 Ursache 4: Ein Modul führt rechenintensive Operationen innerhalb eines Hooks aus

Der Verkauf ist der Zeitpunkt, an dem neue Module installiert werden; deshalb dominiert diese Kategorie die Nachbetrachtungen am Verkaufstag.

Hook-Code wird bei jedem Seitenaufruf ausgeführt, wodurch sich seine Auswirkungen mit dem Traffic vervielfachen. Ein Countdown-Modul prüft die aktiven Aktionen für jedes Produkt in einer Liste mit 48 Artikeln. Ein Widget für die zuletzt angesehenen Produkte schreibt pro Seitenaufruf eine Zeile. Ein Modul für Lagerbestandsbenachrichtigungen ruft eine API ohne Timeout auf. Jede dieser Aktionen wandelt eine Seitenanfrage in Dutzende von Operationen um – bei zehn Besuchern unbemerkt, bei vierhundert jedoch deutlich sichtbar.

Ursache 4: Ein Modul, das innerhalb eines Hooks rechenintensive Aufgaben ausführt

Ausgehende API-Aufrufe sind die schlimmste Variante. Ein Modul, das synchron mit einem Drittanbieterdienst kommuniziert, wartet, und wenn dieser Dienst selbst einmal überlastet ist, warten auch Ihre Worker mit. Zwanzig Worker, die auf einen fünfsekündigen API-Aufruf warten, sind wie ein geschlossener Laden – egal, was die CPU-Auslastung anzeigt.

Die Fehlersuche erfordert eine Bisektionsmethode. Deaktivieren Sie auf einer Testumgebung die Nicht-PrestaShop-Module, prüfen Sie die Seitenladezeit und aktivieren Sie die Module anschließend schrittweise wieder, bis die Kosten wieder gleich sind. Der Profiler verkürzt diesen Prozess erheblich, da er Abfrageanzahl und Laufzeiten pro Hook anzeigt, anstatt diese manuell zu ermitteln. hiddentechies und jPresta kommen zum selben Ergebnis: Das Entfernen ungenutzter Module bringt mehr Vorteile als die meisten Optimierungsmaßnahmen.

8.0 Ursache 5: Hosting-Dimensionierung für einen durchschnittlichen Tag

Shared Hosting kommt mit konstantem Traffic gut zurecht. Strukturell stößt es jedoch bei Rabattaktionen an seine Grenzen: Man teilt sich CPU, Arbeitsspeicher und I/O mit anderen Nutzern, und die Anbieter drosseln die Bandbreite bei Lastspitzen. Eine Rabattaktion ist ein solcher langer Lastanstieg.

Vier Dinge, die Sie überprüfen sollten:

  • PHP-Version und OPcache. Neuere PHP-Versionen sind deutlich schneller als die 7.x-Reihe, und OPcache speichert kompilierten Bytecode im gemeinsamen Speicher, sodass der Interpreter Ihre Dateien nicht erneut einlesen muss. Prüfen Sie, ob OPcache aktiviert ist, und überprüfen Sie anschließend die Speicherbelegung, da die Standardeinstellungen nicht für eine Codebasis dieser Größe ausgelegt sind.
  • PHP-FPM-Pooldimensionierung. Projekte pm.max_children Die Werte stammen aus gemessenen Arbeitsspeicherbelegungen pro Worker, nicht aus einem Blogbeitrag. Bei einem niedrigen Wert werden Anfragen in die Warteschlange gestellt, während die CPU im Leerlauf ist. Bei einem hohen Wert lagert das System Daten aus, was die Leistung beeinträchtigt.
  • Sinnvolle Serverkonfiguration. Das PrestaShop-Projekt php-ps-info-Skript wird Ihnen mitteilen, ob Ihre PHP- und Webserver-Einstellungen den Anforderungen Ihrer Version entsprechen.
  • Kopffreiheit. Eine TTFB von über einer Sekunde trotz aller Optimierungen bedeutet, dass Ihre Hardware an ihre Grenzen stößt. Ein VPS oder Managed PrestaShop Hosting auf einer NVMe-Plattform kann Abhilfe schaffen, ebenso HTML-Caching im Frontend. Die Kombination beider Maßnahmen ist am effektivsten.

9.0 Ursache 6: Ein Frontend, das den Browser blockiert

Kapazität und gefühlte Geschwindigkeit sind zwei unterschiedliche Probleme, nicht nur eines. Ein Backend, das in 200 ms antwortet, wirkt selbst bei vier Megabyte unveränderter Hero-Bilder noch langsam. Googles Schwellenwerte funktionieren wie eine Anzeigetafel: 2.5 Sekunden für das größte Inhaltsbild, eine Fünftelsekunde für die Interaktion bis zum nächsten Bild, 0.1 Sekunden für Layoutänderungen. Kampagnenseiten erfüllen alle drei Kriterien gleichzeitig nicht, da Banner, Badges, Countdown-Widgets und alle Tags, die das Marketing letzte Woche hinzugefügt hat, zu spät geladen werden und die Seite während des Lesens neu anordnen.

Keine der vorgeschlagenen Lösungen ist besonders interessant, weshalb sie wohl auch ignoriert werden. Komprimieren Sie die Bilder und liefern Sie sie im WebP- oder AVIF-Format aus. Laden Sie Inhalte unterhalb des sichtbaren Bereichs erst nach dem Öffnen. Geben Sie Bannern und Countdowns feste Abmessungen, damit diese den Inhalt nicht verschieben können. Laden Sie JavaScript-Code, von dem keine Abhängigkeiten bestehen, erst später. Lagern Sie statische Dateien anschließend auf ein CDN aus. Dadurch verkürzt sich die Ladezeit für Kunden in größerer Entfernung und Ihr Server wird entlastet.

10.0 Auswertung der Beweise nach einem schlechten Verkaufstag

Die Aufzeichnungen eines missglückten Freitags befinden sich noch auf Ihrem Server. Arbeiten Sie sie rückwärts durch.

Die Beweislage nach einem schlechten Verkaufstag auswerten

  • Erstelle eine Zeitleiste. Vergleichen Sie die Zugriffsprotokolle, PHP-FPM-Protokolle und MySQL-Protokolle mit dem Zeitpunkt des Anstiegs des Datenverkehrs. Die Ressource, die in diesem Zeitraum zuerst ausgelastet ist, wird angezeigt.
  • Lesen Sie die Fehlermeldung und überprüfen Sie sie anschließend. Ein 502-Fehler bedeutet in der Regel, dass kein Worker verfügbar war oder ein Worker während der Anfrage ausgefallen ist; ein 504-Fehler bedeutet, dass ein Timeout aufgetreten ist. „Zu viele Verbindungen“ ist eine Meldung der Datenbank. Keiner dieser Fehler gibt allein die Ursache an; lesen Sie sie daher zusammen mit dem Anwendungsprotokoll.
  • Aktivieren Sie das PHP-FPM-Langsamprotokoll. Alles, was langsamer als der festgelegte Schwellenwert ist, erzeugt einen Stacktrace mit dem Namen der noch laufenden Funktion. Diese Methode wird selten genutzt und ist meist der schnellste Weg zu einem bestimmten Modul.
  • Überprüfen Sie das Protokoll für langsame Abfragen. für das Verkaufszeitraum, sortiert nach Gesamtzeit und nicht nach der schlechtesten Einzelausführung.
  • Die Messung am Vorderteil sollte separat erfolgen. Lighthouse, PageSpeed ​​Insights, WebPageTest oder GTmetrix Cover-Rendering. Die Kombination dieser Daten mit Server-Timings führt letztendlich dazu, dass Anwender Hardware kaufen, um ein Bildproblem zu beheben.

Ein APM-Tool wandelt dies von forensischer Analyse in Monitoring um, was die bessere Reihenfolge ist.

11.0 Wie Sie sich auf den nächsten Verkauf vorbereiten

Ein Ausverkauf ist ein Kapazitätsereignis, das zufällig mit Marketing verbunden ist. Planen Sie ihn entsprechend.

Wie Sie sich auf den nächsten Verkauf vorbereiten

  1. Beschreibe, wie der Normalzustand aussieht. TTFB, LCP, Cache-Trefferrate, durchschnittliche Datenbankzeit – alles gemessen an einem ereignislosen Mittwoch. Lässt man diese Daten aus, wird jede spätere Änderung zur Meinungsfrage statt zur Messgröße.
  2. Lasttest der Staging-Kopie. Testen Sie die maximale gleichzeitige Nutzung, einschließlich der Warenkorb-Funktion, und notieren Sie die Anfragerate, ab der Fehler auftreten. Diese Rate entspricht Ihrer tatsächlichen Kapazität.
  3. Den Shop vor dem Start einfrieren. In den letzten Tagen wurden keine Theme-Änderungen, keine neuen Module und keine Aktualisierungen vorgenommen. Bei der Bereitstellung werden die Caches geleert, und ein leerer Cache wenige Minuten vor dem Öffnen ist der denkbar ungünstigste Zeitpunkt.
  4. Caches vorwärmen und Bilder vorab generieren für Kampagnenseiten nach der endgültigen Bereitstellung, damit Besucher Nummer eins einen Treffer erhält, anstatt den Eintrag zu erstellen.
  5. Schauen Sie zu, während es läuft. Worker-Auslastung, Cache-Trefferrate, Datenbankverbindungen, Fehlerrate. Probleme in der zweiten Minute zu erkennen ist besser, als erst in der vierzigsten Minute davon zu erfahren.
  6. Legen Sie jetzt den Degradierungsplan fest. Empfehlungsblock, Live-Bestandszähler, ein umfangreicher, mehrschichtiger Filter: Wissen Sie, was Sie abschalten können, um Lasten zu reduzieren, ohne den Betrieb einzustellen?

Schritt fünf wird oft übersprungen, und dann erfahren Kunden per E-Mail von schleppenden Verkäufen. Wählen Sie zwei oder drei Kennzahlen, die Sie wirklich im Blick behalten, und entscheiden Sie, wo: in einem Dashboard, einer APM-Ansicht oder einem Terminal mit laufenden Protokollen. So verringern Sie die Wahrscheinlichkeit, dass die Verkäufe nur langsam angehen, und erkennen, dass es an der Datenbank liegt. Im Kampagnenverlauf kann sich diese Differenz in verlorenen Bestellungen niederschlagen.

12.0 Wo stehen Sie nun?

Ein PrestaShop-Shop, der während eines Sales langsam ist, deutet auf ein Kapazitätsproblem hin, das sich leicht beheben lässt. Der Traffic hat eine zuvor nie erreichte Grenze überschritten. Häufige Ursachen sind unvollständiges Caching, nicht zwischengespeicherte dynamische Seiten, eine Datenbank, die unnötig viel arbeitet, ein fehlerhaftes Modul innerhalb eines Hooks, ein für durchschnittliche Tage ausgelegtes Hosting oder ein Frontend, das nicht für mobile Endgeräte optimiert ist.

Arbeiten Sie die Liste der Reihe nach ab, da die günstigsten Artikel oben stehen. Smarty so einstellen, dass es nie neu kompiliert, CCC aktivieren, Cache in den Arbeitsspeicher verschieben, Debug-Modus deaktivieren: Das ist an einem Nachmittag erledigt und verändert die Belastbarkeit Ihres Servers. Führen Sie anschließend einen Lasttest durch, damit die nächste Kampagne auf Basis von konkreten Zahlen und nicht von Optimismus startet.

Wenn Sie diese Woche nur eine Sache erledigen, öffnen Sie das Protokoll für langsame Abfragen neben der Leistungsseite und arbeiten Sie die obige Checkliste ab. Was dort auftaucht, wird Ihnen beim nächsten Mal Probleme bereiten, und es lässt sich an einem ruhigen Dienstag viel einfacher beheben als am Morgen des Starts um 9:20 Uhr.

Haben Sie Fragen zur Performance Ihrer Website oder benötigen Sie Unterstützung bei deren Migration? Unsere Experten helfen Ihnen gerne. Kontaktieren Sie das Knowband-Team noch heute unter [email protected] für zuverlässige E-Commerce-Plugins, die perfekt auf Ihre Bedürfnisse zugeschnitten sind.

Schreiben Sie bitte einen Kommentar.