Wir haben im Rahmen des siebenten Magento-Stammtischs Wien unsere Erfahrungen aus unserem letzten Magento-Enterprise-Projekt geteilt.
In der Präsentation geben wir Tipps zu den Themen Projektübernahme, Verwaltung der Aufgaben, 3rd-Party-Extensions, Geotargeting, Bestellungsabwicklung, Backend-Anpassungen, Verwaltung mehrerer Entwicklungsumgebungen und Monitoring.
5. 5
VitaminExpress
Seit 1990 im Geschäft
Online & Katalog
Nahrungsergänzungsmittel
Mehr als 100.000 Kunden
Mehr als 5 Millionen ausgelieferte Produkte
Wechsel von Java-Lösung zu Magento
40.000+
Personentage
12. 12
Projekt-Übernahme
„Never trust a foreign issue tracker“
Projekt anhand klar abgrenzbarer Aufgaben
kennen lernen
Entwicklungsstand Modul für Modul evaluieren
14. 14
Issues, Issues, Issues
Issue = Aufgabe / Feature / Bug
Issues großzügig verwenden
Priorisieren!
• vor dem Start
• nach dem Start
Kunde mit Leserechten = ok
Kunde mit Schreibrechten ≠ ok
16. 16
3rd-Party-Extensions
Probleme:
Sicherheitslücken
Performance-Einbußen
Missachtung von Best Practices
Mangelnde/r Dokumentation/Support
Viele Extensions entsprechen den Anforderungen
nicht zu 100%
Abwägen, ob Extensions sinnvoll sind!
Installationsaufwand
Einarbeitungs- und Anpassungsaufwand
16
25. 25
Bestellungsabwicklung
Murphy‘s Law #1:
„Anything that can be allocated wrong – will be
allocated wrong“
Fallbeispiele überlegen
Anhand von Ablaufdiagrammen durchspielen
Worst case überlegen
Viel Zeit einplanen
26. 26
Bestellungsabwicklung
Murphy‘s Law #2:
„Anything that can go wrong without a transaction –
will go wrong“
„Wir müssen aufpassen, dass nichts dazwischen
funkt!“ „Nein!“ „Doch!“ „Oh!“
Race conditions!
Transaktionen:
$transaction = Mage::getModel('core/resource_transaction');
$transaction->addObject($invoice);
$transaction->addObject($invoice->getOrder());
$transaction->save();
27. 27
Bestellungsabwicklung
Abläufe und Überlegung dahinter dokumentieren
Externe Dokumente vermeiden
Direkt im Backend erläutern
Nach Vereinfachungsmöglichkeiten suchen
Fühlt es sich falsch an, dann ist es meistens auch
falsch
28. 28
Bestellungsabwicklung
„Don‘t mess with order states (and statuses)“
Magento-Standard-States verwenden
Externe Systeme ignorieren die eigene
Geschäftslogik
Asynchrone Bestellstatusaktualisierungen
Lösung:
3rd-Party-Extensions überschreiben oder
Bestellungen regelmäßig auf fehlgeleitete Stati überprüfen
Wir überprüfen die Bestellungen im Rahmen der
Order-Flow-Cronjobs
32. 32
Backend-Anpassungen
Callcenter-Funktionalität
Store-Auswahl überspringen
Letzte Bestellungen anzeigen
Liste der bestellbaren Produkte anpassen
Zusätzliche Kunden- und Produkt-Informationen
Link zum Kundenkonto hinzufügen
Reduzierung der AJAX-Loads bei Adressdaten
33. 33
Backend-Anpassungen
Backend Grids in der Enterprise Edition
Achtung bei zusätzlichen Joins:
SQL-Errors für eingeschränkte User
„ambiguous column names“ beseitigen
Grids allgemein
Performance-Verluste beim Joinen von Tabellen
Views helfen nur, wenn sich Daten selten ändern
Werte vorberechnen
Grid-Tabellen erweitern oder eigene Grid-Tabellen
entwerfen => automatische Propagation erweitern!
34. 34
Backend-Anpassungen
Create New Order
Anpassungen sind mühsam:
AJAX-Calls
Nachladen von Blöcken
Abhängigkeiten / Verbindungen zwischen Blöcken
Wenig Events
40. 40
Dev / Live
Pro Umgebung zu berücksichtigen
Automatismen abstellen?
Importe / Exporte deaktivieren?
Cronjobs deaktivieren?
Andere externe Systeme verwenden?
Häufig keine vollfunktionalen Testsysteme vorhanden
Testsysteme verhalten sich häufig anders als Livesysteme
Manchmal gar keine Testsysteme
(I‘m looking at you, Amazon)
Echtdaten anonymisieren/entfernen?
41. 41
Dev / Live
Live-Systeme schützen
Extension:
LimeSoda_LiveGuard @ GitHub
Ergänzt LimeSoda_EnvironmentConfiguration
Überwacht jeden Magento-Aufruf
„Defensive“ Taktik
Plugin-Architektur
Testen auf
Konfigurationswerte
E-Mail-Adressen
FTP-/SSH-/REST-/SOAP-Verbindungsdaten
PSPs: Acceptance, Sofortüberweisung, Billsafe, PayPal
Datenbank: EE Standard 447, M2E Pro 179, Sonstige 134
Zustand des externen Issue Trackers: veraltete Information, nicht hilfreich => zu viel implizites Wissen
- Es war sinnlos, zuerst den kompletten Status quo zu erheben- Arbeitspakete zusammenstellen: Anhand klarer Aufgaben kann man arbeiten, sich im System orientieren lernen
Issues großzügig verwenden: lieber zu viele Issues als zu wenige verwenden
Viele Aufgaben, wenig Zeit => wir mussten priorisieren! Aufteilung in 2 Phasen: => bietet mehr Flexibilität => bei harter Deadline: Weniger wichtige Issues auf nach dem Start verlagern oder simplere Lösung finden
Man sollte vor Einsatz Code-Checks machen! (Fabian: 2 PT Aufwand für Check)
Sicherheitslücken: SQL-Injection, Textfile mit letzter Transaktion im Root-Verzeichnis
Performance: Cross-Selling-Extension: Produktseite: +2,5 Sekunden, + 600 Queries
Missachtung von Best Practices: Haarsträubender Code: Original-Dateien überschrieben, unnötige Rewrites, vorhandener Code nach programmiert, Model/View/Controller vermischt, …
Kunden glauben es meistens nicht, und doch ist es so: gekaufte Extensions verursachen ebenfalls Kosten, manchmal mehr als eine Eigenprogrammierung (plus: Aufwände bei Upgrades)
Caching: Cache-Keys für Blöcke anpassen, die GeoIP berücksichtigen!
Order wird erstellt => nach Bezahlung im Status Processing. Lagerstand wird reduziert und wir merken uns, wieviele Stück reserviert sind.
Wir benötigen den allokierten Lagerstand, um aufgrund des Versandlager-Lagerbestands die tatsächlich im Shop verfügbare Menge zu berechnen.
Cronjobs (für regelmäßige Abläufe, die man planen kann)
Observer (schießen irgendwann dazwischen): Wareneingänge, Stornierungen / Refundierungen, …
Lücken: entstehen durch lang laufenden Cronjobs. Sind inzwischen in extra Prozesse ausgelagert.
Außerdem haben wir nun auch häufiger laufende Cronjobs.
Außerdem indiziert die EE laufend.
„Lagerstandsverwaltung = komplexes Thema“
Fallbeispiele erstellen: komplexe Fälle durchüberlegen
Worst case besprechen: was passiert, wenn XY schief geht? => ist wichtig, denn irgendwann wird es schief gehen! Vorbereitung wichtig: wenn es schief geht, hat man nicht die Zeit dafür.
Wir: „Was passiert, wenn gerade die Aktion X ausgeführt wird und mittendrin Aktion Y passiert?
Kunde: „Das wird in der Praxis nicht passieren!“ => Lücke von max. 0,1 Sekunde bei Order-Speichern und Verarbeiten
=> Bis zum nächsten Abend hatten wir den ersten Fall.
Externe Dokumente sind schnell outdated
Direkt im Backend = man erfasst schneller, worum es geht. Hinweis auf Issues sind möglich
Vereinfachungen suchen:
„Manchmal sieht man den Wald vor lauter Bäumen nicht“. Wenn es sich falsch anfühlt, ist es meistens auch falsch.
Zuerst hatten wir 4 variable Lagerstände:
Versandlager Lagerstand
Reservierter Lagerstand
Freier Lagerstand
Magento-Lagerstand
Reduzierung auf:
Extern definierten und berechneten Versandlager-Lagerstand
Reservierter Lagerstand (variabel)
Magento-Lagerstand (berechnet sich aus Versandlager - reserviert)
Don‘t mess:
Keine eigenen States
Eigene Statuses gefahrloser, aber potentiell problematisch mit externen Systemen
- Externe Schnittstellen und deren Extensions scheren sich normalerweise nicht darum, welchen Status eine Extension gerade hat und ob der neue Status Sinn macht => Entweder alle Extensions überschreiben oder Orders regelmäßig überprüfen => Entscheidung für Cronjob, siehe Order-Stop-Rules und Order-Status-Flow
Wir gehen nur auf die Anpassungen rund um die Sales- und Customer-Menüs ein
Adressdaten von woanders beziehen
Auto-Propagation: Herausforderung, eigene Daten in Grids aktuell zu halten => man muss die Auto-Propagation erweitern, damit diese Daten !
AJAX-Calls schießen kreuz und quer
Blöcke werden kreuz und quer nachgeladen
Es gibt Verknüpfungen zwischen Blöcken
Es gibt keine anständigen Events / Rewrites
Deployfähig = „funktionsfähiger und stabiler Code, der ohne wenn und aber ins Live-System darf“
Files und Daten in den Entwicklungskopien müssen aktuell gehalten werden
ugitsub: Bash-Script, das alle Submodule aktualisiert
backportlive: Shell-Skript: Umgebung und Backup angeben: holt sich eines der nächtlichen Backups vom Live-Server, spielt sie ein, passt die Konfiguration etc. der Datenbank an.
LimeSoda_EnvironmentConfiguration: Hilft, die Umgebung vorzubereiten (Beispiele folgen gleich)
Variablen und Befehle
Beliebig viele Vererbungen
Daraus ergibt sich im Gegenzug eine weitere Anforderung: Live-Systeme müssen geschützt werden