Die Technologien hinter unserem neuen Kundenbereich und unseren Site-Tools

Als wir die Einführung unseres neuen Kundenbereichs und unserer Site-Tools ankündigten, sprach unser COO darüber aus geschäftlicher Sicht und wie wichtig dieses Projekt für unser zukünftiges Wachstum ist. Ich möchte Ihnen die technische Perspektive erläutern und warum wir diese neuen Schnittstellen auch als technischen Meilenstein für SiteGround sehen.

SiteGround war schon immer in erster Linie ein Dienstleistungsunternehmen. Unser Geschäftswachstum ist jedoch seit vielen Jahren eng mit unserer technischen Entwicklung verbunden. Je mehr Software wir selbst entwickelten, desto mehr stieg die Qualität unserer Dienstleistungen und desto mehr wuchs unser Ruf. Darüber hinaus haben wir das Selbstbewusstsein eines High-Tech-Unternehmens, das leistungsstarke und smarte Softwarelösungen produziert und immer als eines der Ersten die innovativsten Technologien einsetzt.

Als wir also erkannten, dass viele unserer Geschäftsideen durch die Einschränkungen unserer derzeit zugrunde liegenden Plattform verlangsamt oder unmöglich gemacht wurden, hatten wir den Mut, an etwas größeres zu denken als das, was auf dem Markt verfügbar war, und wagten es, alles neu zu erschaffen.

Die Herausforderung

Aus geschäftlicher Sicht wollten wir eine Plattform (Frontend und Backend) verwalten, die auf jedem Gerät funktioniert, ein modernes Aussehen hat, leichtgewichtig, schnell, sicher und leicht skalierbar ist. Um dies ins Technische zu übersetzen, haben wir die folgenden Ziele definiert:

1. Geschwindigkeit und erweiterte UX

Wir haben uns für Single-Page-Anwendungen entschieden, da dies die unverzichtbare Technologie für ein schnelleres Web-Erlebnis darstellt.

2. Skalierbarkeit und Sicherheit

Wir haben uns entschieden, die Micro-Services-Philosophie zu übernehmen und alles API-basiert zu gestalten, damit wir das System einfacher skalieren und bei Vorfällen auf einen geringeren Schadensumfang rechnen können.

Bei vielen Diensten ist die Authentifizierung und Autorisierung jedoch ein großes Problem. Daher brauchten wir eine sichere, schnelle und einfache Lösung für die Bedürfnisse der ursprungsübergreifenden Ressourcenfreigabe, bei der wir uns für die Verwendung von JSON-Webtoken entschieden haben.

Ein skalierbarer Betrieb mit Millionen von Sites, die auf Hunderttausenden von Containern gehostet werden, erfordert auch Orchestrierung, Service-Erkennung und eine zuverlässige Messaging-Ebene, auf der wir Consul und NSQ einführen.

Schließlich sind gute Beobachtbarkeit, Überwachung und Alarmierung angesichts der Komplexität des Systems von entscheidender Bedeutung. Also setzen wir Prometheus und Grafana in Aktion.

Die Lösungen

1. Single-Page-Anwendungen mit React und Redux

Als wir vor drei Jahren mit der Arbeit an dem Projekt begannen, wussten wir, dass Single-Page-Anwendungen immer beliebter werden, weil sie eine bessere Benutzererfahrung, schnellere Seitenladezeiten, die Vereinheitlichung von Designprinzipien, ein modulares Design und mehr ermöglichen. Auch das SPA-Ökosystem entwickelte sich schnell. Es gab viele JavaScript-Frameworks wie AngularJS, ReactJS und Vue.js. Es schien natürlich und offensichtlich, dass die Single-Page-Anwendung die Antwort war, wenn es um etwas Leichtes, Schnelles und API-basiertes ging. Nach einigen Tests mit verschiedenen Frameworks haben wir uns entschieden, ReactJS + Redux für unsere neuen Klienten-Bereich und Site Tools zu verwenden, da es die besten Performance-Ergebnisse zeigte.

Schnelles Laden der Seite

Wir haben zwei Hauptanwendungen für eine Seite. Eine davon ist die Klienten-Bereich-App und die andere ist unsere Site Tools App. Sie werden beide stündlich von Tausenden von Menschen genutzt und die Zahl wächst. Das Verschieben von Anwendungslogik in die Browser der Benutzer, in denen JS lokal ausgeführt wird, machte die Dinge schneller. Dies liegt zum Teil daran, dass wir im Backend weniger Datenmanipulationen durchführen. Zum anderen existieren  unsere Apps auf einer Objekt-Caching-Lösung mit CDN davor. Dies macht es für Benutzer auf der ganzen Welt sehr schnell, die App zu laden und zu verwenden.

Einheitlicher Styleguide

Single-Page-Anwendungen ermöglichen es Ihnen, mit fertigen Komponenten zu arbeiten, die wiederverwendbar sind und dafür sorgen, dass Ihre Schnittstellen bestimmten Standards entsprechen. Für unseren haben wir einen Styleguide geschrieben, der unsere Schnittstellen homogen aussehen lässt und uns einfacher und schneller neuen Code schreiben lässt. Der Kompromiss besteht darin, dass das Styleguide-Repository alleine mit allen Beispielen etwa 550 000 Codezeilen umfasst!

Da unsere Entwicklung ziemlich groß ist und ständig wächst und der Code, mit dem wir arbeiten, ziemlich umfangreich ist, mussten wir sicherstellen, dass unsere Standards eingehalten und nicht durch Änderungen zurückgesetzt werden. Deshalb haben wir den Code mit Visual- und e2e-Tests (Cypress) abgedeckt. Wenn eine Codeänderung eine bestimmte Seite visuell erheblich verändert, haben wir eine rote Flagge und wir können sogar die Codebereitstellung und -builds automatisch stoppen.

2. RESTful APIs und Microservices

Wir haben jetzt über 100 API-Aufrufe, die verwendet werden können, um eine einzelne Site zu verwalten, die auf unseren Servern gehostet wird. Dinge wie die Installation von WordPress, das Ausstellen eines privaten SSL-Zertifikats, das Erstellen von E-Mail-Konten, das Erstellen neuer MySQL-Datenbanken, das Hinzufügen von SSH-Schlüsseln und sogar das Migrieren von Sites zwischen Servern werden alle über API-Aufrufe erledigt. Diese APIs bieten uns die folgenden Vorteile:

Fördert die Verwendung verschiedener Sprachen

Wir haben Softwareingenieure, die in den folgenden Sprachen/Frameworks für unsere Plattform schreiben:

  • PHP (Symfony, Zend-Framework)
  • Perl (Dancer)
  • Gehen
  • Python
  • JavaScript (ReactJS, AngularJS), TypeScript

Um sicherzustellen, dass alle beweglichen Teile miteinander kommunizieren können, brauchten wir RESTful-APIs, um die Kommunikation zu ermöglichen.

RESTful API-Design ist gut bekannt

Das Gute an RESTful APIs ist, dass sie heutzutage so ziemlich jeder Entwickler versteht und mit dem Konzept vertraut ist. Das bedeutet, dass wir, wenn wir neue Funktionen hinzufügen müssen, Entwickler nicht schulen oder ihnen die Vor- und Nachteile des gesamten Systems beibringen müssen, damit sie liefern können. Sie können sich einfach auf den neuen benötigten Code konzentrieren und ihn in das System integrieren.

Unsere Partner können die APIs verwenden

Die Tatsache, dass alles API-basiert ist, macht es einfach, Partnern Zugriff zu gewähren und sie Websites erstellen, ein CMS installieren oder andere Funktionen auf unserer Plattform ausführen können. Das macht uns flexibel und ist eine gute Grundlage für unser zukünftiges Geschäftswachstum.

Anpassung des Benutzerzugriffs

Die RESTful-APIs wenden das CRUD-Prinzip an, das besagt, dass jedes von der API manipulierte Objekt die folgenden 4 Funktionen unterstützen sollte: Erstellen, Lesen, Aktualisieren und Löschen. In Verbindung mit der vereinheitlichten REST-Repräsentation von Ressourcen ermöglicht dies eine einfache Trennung von Aktionen und eine benutzerdefinierte Zugriffs- und Benutzersteuerung.

Zusammen mit den JSON-Webtoken haben wir die APIs verwendet, um benutzerdefinierte Zugriffsebenen in unseren neuen Schnittstellen bereitzustellen. Es ist jetzt möglich, einem Operator zu erlauben, Mail-Accounts für einen Domain-Namen zu erstellen, aber keinen Zugriff auf die bestehenden Mail-Accounts oder andere Tools zuzuweisen. Für den Anfang haben wir nur 3 Benutzerrollen eingeführt: Site-Inhaber, Mitarbeiter und White-Label-Kunde, aber wir haben die Grundlage gelegt, um in Zukunft viele Anpassungsoptionen einfach hinzuzufügen. Die rollenbasierte Zugriffskontrolle ermöglicht es uns, einen granularen Zugriff auf bestimmte Dienste und Funktionen zu erlauben.

Probleme leichter erkennen & besser messen

Je detailgenau die Konstruktion, desto einfacher ist es, ein geschädigtes Teil zu isolieren und auszutauschen oder zu reparieren. Das ist einer der Hauptvorteile der Micro-Services-Philosophie. Wir können Probleme mit einer bestimmten Funktion, die von einem bestimmten Dienst bereitgestellt wird, leichter verfolgen und beheben. Wir können auch die Leistung und Nutzung der verschiedenen Dienste besser verfolgen, sodass wir die Plattformressourcen skalieren und Probleme vermeiden können.

3. JSON-Webtoken

Als wir mit der Arbeit an Single-Page-Anwendungen begannen, wussten wir, dass wir unser Authentifizierungs- und Autorisierungs-Setup irgendwie skalieren müssen. Angesichts der Anzahl von APIs, die miteinander kommunizieren und Benutzern, die auch mit diesen APIs interagieren (die über verschiedene Domains verteilt waren), war die Autorisierung auf die alte Weise – über Cookies – nicht optimal und nicht skalierbar. Die beiden Hauptprobleme, die wir hatten, waren:

  • Der Umgang mit Cross-Origin Resource Sharing-Cookies und HTTP-Headern ist nicht einfach, und wir wollten dies vermeiden. Durch die Kombination von JSON Web Tokens mit unseren eigenen APIs können wir dieses Problem lösen.
  • Die Skalierung eines Backend-Systems, das jede API-Anfrage überprüft, sah aus Sicht der Sitzungsleistung sehr schlecht aus.

Nach einigen Recherchen haben wir uns entschieden, JSON Web Tokens für diesen Teil der Infrastruktur zu verwenden. Wir haben auf unserer Seite ein benutzerdefiniertes Authentifizierungs- und Autorisierungssystem konfiguriert. Es ermöglicht uns, von Dingen zu profitieren wie:

  • Einheitlicher Autorisierungsmechanismus für verschiedene APIs
  • Reduzierte Serverlast und weniger DB-Zugriffe
  • Möglichkeit, diese Lösung in verschiedenen Domains zu verwenden
  • Einfachere horizontale Skalierbarkeit
  • Ein höheres Sicherheitsniveau für unsere Benutzer
  • “Out of the box” einmaliges Anmelden 

4. Orchestrierung und Messaging

Je mehr wir wachsen, desto mehr Server (als Hardwareeinheit) und Container (als virtuelle Einheit) betreiben wir. Der Linux-Container ist die Haupteinheit unserer Infrastruktur, aber die Art und Weise, wie wir diese Container verwalten, ändert sich im Laufe der Zeit. Das Bestellen neuer Server, das Bereitstellen eines Containers mit dem erforderlichen Software-Stack, das Hinzufügen dieses neuen Containers zu allen Datenbanken, die verschiedene Dienste und APIs versorgen, all das und mehr erfordert eine Orchestrierung. Für diesen Teil haben wir viel Code geschrieben, der spezifisch für unsere Plattform und unsere Prozesse ist. Dennoch sind wir stark von etablierten Softwareprojekten abhängig, um unsere Ziele zu erreichen. Wir verwenden HashiCorp Consul für Service Discovery und Systemautomatisierung. Unsere bevorzugte Messaging-Plattform ist NSQ. Wir verwenden Ansible, um viele Aufgaben der Softwarebereitstellung und des Konfigurationsmanagements zu automatisieren.

Zwei gute Beispiele sind unsere überarbeiteten Systeme Let’s Encrypt und Automatische WordPress Updates. Früher liefen sie lokal auf jedem Hosting-Server, heute funktionieren sie auf der Basis eines verteilten Ansatzes. Server werden automatisch im System registriert. Die Dienste verwenden die von Consul bereitgestellte automatische Erkennung. Dann werden die oben genannten APIs verwendet und die SSL-Ausstellung und -Erneuerung erfolgt für jeden neuen Domainnamen, den wir im System registrieren. Dasselbe gilt für jede App, die in die automatischen Updates von WordPress eingeht.

5. Prometheus/Grafana für Beobachtbarkeit

Auch die Art und Weise, wie wir neue Dienstleistungen anbieten, hat sich stark verändert. In der Cloud-einheimischen Welt kümmern wir uns nicht mehr darum, dass einzelne Hosts ausfallen. In diesem Fall werden keine Ingenieure im Netzwerk-Operationszentrum gerufen. Es gibt keine handwerklichen Systemadministratoren, die Maschinen und Dienste mit viel Aufmerksamkeit behandeln. Jetzt überwachen wir die gesamte Infrastruktur mit folgenden Zielen:

  • Wir müssen wissen, wenn etwas schief geht
  • Wir können Fehler beheben und haben Einblick in den spezifischen Kontext
  • Wir müssen in der Lage sein, Veränderungen im Laufe der Zeit zu sehen und Vorhersagen zu machen
  • Daten sollten leicht von anderen Systemen und Prozessen konsumiert werden können

Um das oben Gesagte konkreter zu machen, definieren wir jetzt die „Fehler“-Szenarien und die Warnungen, die wir für jedes erhalten, neu. Wir können beispielsweise Warnungen erhalten, die eine menschliche Interaktion erfordern, wenn es direkte Auswirkungen auf den Benutzer gibt, beispielsweise wenn ein Dienst betroffen ist, der die Websites von Kunden direkt betrifft. Es ist jedoch möglicherweise kein menschliches Eingreifen erforderlich, wenn ein bestimmter Knoten ausgefallen ist, da die Daten automatisch auf andere Knoten verteilt werden und es keine Auswirkungen auf den Benutzer gibt, sodass in diesem Fall keine Warnung erforderlich ist.

Wenn wir an diesen Warnungen arbeiten, wollen wir von der Warnung zu den problematischen Subsystemen übergehen. Damit unsere Ingenieure eine schnelle Analyse durchführen und eine schnelle Auflösung bieten können, müssen wir über genügend Daten verfügen. Dies wird als verteiltes Tracing bezeichnet und ermöglicht es uns, die Anforderungen bestimmter Benutzer von den Browsern unserer Kunden über mehrere APIs und verschiedene Dienste bis hin zu Datenbanken und/oder Speicher-Engines zu verfolgen. Jeder Datensatz zu einer Anforderung im verteilten Ablaufverfolgungssystem liefert uns Leistungsprofilinformationen und eine Möglichkeit, Probleme mit anderen Ereignissen zu korrelieren. Wir verwenden verteiltes Tracing, um Fehler in unseren Code schneller zu beheben und zu optimieren. Dadurch können wir eine höhere Feature-Geschwindigkeit erreichen.

Um alle Ziele zu erreichen, haben wir uns für die Verwendung von Prometheus und Grafana für die Profilerstellung, die Erfassung von Metriken, die Protokollanalyse und die verteilte Verfolgung von Ereignissen entschieden. Wir sind jetzt in der Lage, Informationen aus mehreren Quellen zu korrelieren und Mängel aufzudecken und vorherzusagen.

Fazit

Die Software, die wir schreiben mussten, um die Herausforderung zu meistern und die oben genannten Lösungen bereitzustellen, ist umfangreich, aber sehr lohnend. Zum Abschluss überlasse ich Ihnen einige Zahlen direkt aus den neuen Software-Repositorys und unserem JIRA:

  • 2 539 604 Codezeilen
  • 99% Codetestabdeckung
  • 9250 JIRA-Aufgaben
  • 199 560 Wörter in JIRA-Geschichten

Besonders stolz sind wir auf die Code-Testabdeckung. Obwohl 2,5 Millionen Codezeilen beeindruckend sind, wissen wir, dass dies kein wirklich großer Erfolgsfaktor ist. Die Tatsache, dass unser gesamter Code durch Tests abgedeckt wird, ist jedoch eine große Leistung. Von Anfang an haben wir die Codetestabdeckung als eines unserer Hauptkriterien für die Bereitstellung hochwertiger Software festgelegt. Und wenn unser neuer Kundenbereich und unsere Site-Tools keine Qualitätsgarantien bieten können, können wir nicht den großartigen Service bieten, den unsere Kunden gewohnt sind. Seien Sie versichert, wir sind bestrebt, denselben erstklassigen Hosting-Service anzubieten, diesmal jedoch mit noch besseren Site-Management- und Collaboration-Tools, die auf den weltweit besten und innovativsten Webtechnologien basieren.

author avatar
Nikolay Todorov

CEO bei SiteGround

Service-Updates

Kommentare für diesen Beitrag sind jetzt geschlossen.