Was die Qualität von Websystemen ausmacht - Teil 8

Speed is a Feature: Wie Sie Performance in Webanwendungen planen

Daniel Takai, Nicolas Bär, Christian Wittwer

@shutterstock/maglyvi

Für den Ingenieur ist das Beste an der Performance ihre leichte Messbarkeit: Kaum ein anderes Qualitätsmerkmal lässt sich so leicht messen, wie die Antwortzeit eines Systems. Diese Messungen kann man auch gut automatisieren und in Form von Histogrammen grafisch aufbereiten. Zudem sind die Maßangaben verständlich, denn jeder kann sich unter einer Ladezeit von zwei Sekunden etwas vorstellen. Leider fällt schnell auf, wenn das System langsam ist – aber dem kann man strukturiert begegnen.

„Fast performance is a nebulous statement at best, and often entirely useless“ [1]. Die Performance ist ein Qualitätsmerkmal, das von allen Stakeholdern stets erwartet wird, denn niemand mag ein langsames System. Lädt eine Seite langsam, so sinken die Besucherzahlen und der Page Rank bei Google. Eine gute Performance ist jedoch schwierig, in einigen Fällen sogar unmöglich zu erreichen, sodass eine wiederkehrende Analyse und Diskussion unserer Systeme nicht fehlen sollte. In diesem ersten Artikel über Performance konzentrieren wir uns auf das Backend und untersuchen, welche Methoden und Techniken wir einsetzen können, um das Maximum aus einer Maschine zu holen.

Welche Faktoren beeinflussen die Performance im Browser? Die wesentlichen Aspekte (dazu Kasten: „Terminologie“) sind die Latenz der Verbindung, die Kapazität, das Protokoll und die Antwortzeit sowie die Skalierbarkeit unserer Anwendung. In diesem Artikel betrachten wir die Antwortzeit des Backends, die durch die Technologiewahl beeinflusst werden kann, eine möglichst effiziente, nebenläufige Implementierung sowie einen Cache. Eine Rahmenbedingung der Antwortzeit kann ein integrierter externer Dienst und die Laufzeitumgebung der Maschine sein, letztere insbesondere bei virtualisierten Lösungen.

Terminologie
Eine Page View bezeichnet das Laden einer Seite mit allen benötigten Ressourcen. Ein Request ist der Abruf einer einzigen Ressource. Eine einzelne Page besteht immer aus einem einzigen HTTP-Request für das HTML sowie mehreren Requests für alle für die Darstellung benötigten Inhalte (CSS Style Sheets, JavaScript-Dateien und Bilder). Da ein Browser bei HTTP/1 meist nur zwischen sieben und elf Requests parallel verarbeiten kann, lassen sich hier auch Richtlinien für die maximale Anzahl von Requests pro Page View ableiten, um eine optimale Frontend-Performance zu erreichen, bzw. um die Last auf die Backend-Server zu reduzieren. Eine einzige Page View kommt schnell auf über 50 Requests. Bei HTTP/2 müssen zwar auch noch fünfzig Ressourcen geladen werden, aber der Wasserfalleffekt wie bei HTTP/1 ist nicht mehr so sichtbar und es geht schneller.

Die Performance ist die Zeit, die das System benötigt, um eine Transaktion auszuführen. Man muss für jedes System definieren, was eine Transaktion ist. Man kann beispielsweise einen Request oder eine Page View als Transaktion definieren.

Performance Eindruck beim Benutzer
0 bis 100ms Sofort
100 bis 300ms Merkbare Latenz
300 bis 1 000ms Anwendung funktioniert
1 000+ ms Kontextwechsel wahrscheinlich
10 000+ ms Abbruch

Tabelle 1: Subjektive Performance nach Ilya Grigorik [1]

Wenn es um die Performance von Backend-Systemen geht, wird häufig von der Time To First Byte (TTFB) gesprochen. Damit ist die Dauer gemeint, die zwischen dem Absenden des Requests bis zum Eintreffen des ersten Bytes der Antwort liegt. In der TTFB ist die Zeit für den DNS Lookup, das Aufbauen der Verbindung zum Backend (inklusive TLS-Handshake falls HTTPS im Spiel ist) und der Verarbeitung des Requests im Backend enthalten. Wenn man pragmatisch sein möchte, kann man TTFB mit Latenz gleichsetzen.

Der Durchsatz (engl. Throughput) ist die Anzahl der Transaktionen, die ein System pro Zeiteinheit verarbeiten kann. Die Kapazität ist die maximale Bandbreite, die ein System unter einer bestimmten Last (engl. Workload) bei akzeptabler Performance aufrechterhalten kann. Damit bestimmt das konkrete Lastszenario die Kapazität. Da sich Lastszenarien nicht kontrollieren lassen, kann es sein, dass sich die Kapazität eines Systems plötzlich dramatisch verändern kann.

Die Definitionen in diesem Artikel sind an [2] und [3] angelehnt.

Backend-Performance einordnen

Die Performance beschreibt die Sparsamkeit in Bezug auf Rechenzeit und Speicherplatz einer Software, die Effizienz, deren Dynamik, also ob sich die Performance im Laufe der Zeit verändern soll, sowie das Antwortverhalten des Systems. Die Backend-Performance meint ausschließlich die Antwortzeit unseres Systems, und ist deswegen als Grundlage einer Diskussion rund um die Geschwindigkeit – unlogischerweise – irrelevant. Relevant ist nur die Antwortzeit bei einer bestimmten Arbeitslast des Systems (Kasten: „Terminologie“), also die Kapazität des Systems, die wir erst in einem kommenden Artikel behandeln. Aus diesem Grund gibt es auch in diesem Artikel ausnahmsweise keine Qualitätsszenarien zur Diskussion mit dem Fach. Die Konzepte und Methoden rund um die Backend-Performance sind in Abbildung 1 skizziert und Gegenstand dieses Artikels.

Abb. 1: Konzepte rund um die Backend-Performance

Lücken füllen mit Application Performance Monitoring

In einer modernen Webapplikation sind im Backend häufig sehr viele verschiedene Systeme in die Beantwortung von einzelnen Requests involviert. Für die Analyse der Auslastung dieser Systeme aber auch in der Problemfindung werden verschiedene Performancemonitoringlösungen verwendet, um Metriken auf einem Zeitstrahl sichtbar zu machen. Beispiele dafür sind Zabbix, collectd oder Graphite. Ziel dabei ist, dass sich schnell mithilfe von Dashboards und den Drill-down-Möglichkeiten dieser Tools das System identifizieren lässt, das mehr CPU als sonst verwendet wird oder einen höheren Speicherverbrauch in der JVM hat.

Dabei helfen die Tools, das betroffene System zu identifizieren. Nur lassen sich keine Aussagen über den Grund des abnormalen Verhaltens machen, da der Einblick in die Applikation fehlt. Diese Lücke füllt das Application Performance Monitoring (APM). Über das Java-Agent-Interface kann sich eine APM-Lösung in die JVM einklinken und verschiedene Informationen herausholen. Dieser Blick in die JVM ermöglicht eine tiefergehende Analyse. Es können langsame Stellen im Code identifiziert, die durchschnittliche Antwortzeit von Transaktionen überwacht oder die Requests auf Umsysteme wie die Datenbank oder dem Web Service aufgezeichnet werden.

Ein bekannter Anbieter für APM ist New Relic. New Relic verwendet zur Instrumentierung das ASM-Framework und lässt sich auch in bestehende Systeme relativ einfach integrieren, allerdings zum Preis einer kleineren Performanceeinbuße und monatlich wiederkehrenden Kosten für die Lizenzierung. Eine weitere Option für den Export von Metriken aus der JVM ist Servo von Netflix. Mittels einfacher Annotation lassen sich hiermit per JMX Daten exportieren und dann in anderen Tools weiterverarbeiten.

Das frühzeitige Planen der Messung und Auswertung dieser Daten kann sich insbesondere bei kommerziellen Systemen schnell auszahlen. Wir haben beispielsweise bei einem proprietären E-Commerce-System eine hohe Anzahl von Datenbankabfragen festgestellt, die durch die Entwicklung nicht reduziert werden konnten (4 000 pro Page View). Durch die Verringerung der Latenz zwischen E-Commerce-Server und Datenbank um nur eine Millisekunde konnte die Gesamtperformance des Systems nahezu verdoppelt werden. Außerdem kann die Analyse auch Fehler in der Applikation oder Probleme im Softwaredesign sichtbar machen.

Culling: Maschinen vergleichen

Der Betrieb von Applikationen in der Cloud wird immer mehr zum Standard. Eine einzelne Maschine ist also nicht mehr so isoliert wie bei dedizierter Hardware, d. h., die anderen virtuellen Maschinen können einen Einfluss auf die Performance unseres Systems haben. Wir können dies nicht kontrollieren, nur versuchen, durch Messungen herauszufinden, ob unsere VM negativ beeinflusst wird (Noisy Neighbor). Zeigt eine solche Messung einen deutlichen Abfall, so werfen wir die Maschine weg und starten eine Neue, in der Hoffnung, dass diese dann beim Provider in einer günstigeren Umgebung laufen wird. Diese Technik nennen wir Culling. Verfolgt man sie konsequent, so startet man mehrere dutzend Maschinen gleichzeitig, misst sie durch und behält nur die schnellste.

Concurrent Users managen

Die Anzahl möglicher gleichzeitiger Benutzer (Concurrent Users), die ein Web Service verarbeiten kann, beinhaltet eine essenzielle Qualitätsanforderung an die Architektur und Entwicklung. Verschiedene Einflussfaktoren bestimmen diese Zahl. Den Grundbaustein dazu bietet die Nebenläufigkeit des Applikationsservers und Connection-Pools in der Verarbeitung von Requests.

Ein synchroner Applikationsserver kann jeweils nur eine Anfrage gleichzeitig verarbeiten. Jede weitere Anfrage wird erst bearbeitet, wenn die vorherige abgeschlossen ist. Synchrone Applikationsserver werden nur innerhalb von Entwicklungsumgebungen eingesetzt. Denn produktive Systeme müssen je nach Anforderung viele gleichzeitige Anfragen beantworten können. Das beliebteste Modell dazu ist ein Thread-Pool, der zunächst Anfragen in eine Queue ablegt. Die Anfragen werden in der Sortierung der Ankunftszeit an ihn befördert. Der Thread-Pool definiert in diesem Modell die Nebenläufigkeit des Service. Wenn beispielsweise 200 Threads zur Verfügung stehen, können 200 Anfragen gleichzeitig verarbeitet werden. Weitere Anfragen würden in der Queue verweilen und allenfalls nicht innerhalb des gewollten Timeouts beantwortet. Ein Thread-Pool kann nicht beliebig groß sein, sondern wird maßgeblich von den Systemressourcen (CPU, I/O) und der Komplexität der Applikation beeinflusst. Eine CPU-intensive Applikation sollte auf die entsprechenden Cores des Systems abgestimmt sein [4]. Ein sehr hoher I/O-Bedarf kann nicht mit einem beliebig großen Pool gelöst werden, da sonst der Kontextwechsel zwischen den Threads die Performance verschlechtert. Ein Applikationsserver wie z. B. Apache Tomcat hat eine Default-Konfiguration von maximal 200 Threads und einer Queue von 100. Diese Einstellungen dienen als guter Start für weitere Optimierungen. Einen alternativen Ansatz bieten reaktive (bzw. eventbasierte) Frameworks. Es werden alle Anfragen initial von einem Thread beantwortet, der als Multiplexer dient und die entsprechenden Events weiterleitet. Performance-Benchmarks konnten bisher nicht beweisen, dass dieses Reactor Pattern zu einer Verbesserung der Geschwindigkeit führt [5]. Klar ist jedoch, dass es sich dabei um ein anderes Denkmuster handelt. Mittels eines Thread-Pools entwickeln wir innerhalb eines blockierenden Threads. Der Zugriff auf einen externen Dienst blockiert die weitere Logik des Requests. In einer reaktiven Umgebung schreiben wir nicht blockierende Callbacks, die aufgerufen werden, nachdem z. B. langsame Operationen durchgeführt wurden.

Externe Dienste

Die Antwortzeit des Backends kann durch einen externen Dienst mitbestimmt werden, der integriert werden muss. Angenommen, die Preisberechnung ihrer Produkte geschieht in Abhängigkeit des browsenden Kunden, seines Kundensegments, des Markts, von dem er den Preis abruft und seiner Kundennummer (bestimmte Kunden erhalten einen verhandelten Rabatt). Da es sich um eine schwierig zu implementierende Geschäftsfunktion handelt, wurde dieser Pricing-Service als eigenständiger REST-Dienst entwickelt. Leider ist dieser aber eng an das ERP-System gekoppelt, sodass Anfragen nicht besonders schnell und auch nicht in beliebiger Menge platziert werden können.

Eine solche Integration muss gut abgesichert werden, um verschiedene Fehlerquellen zu antizipieren, welche die Performance des Pricing-Service beeinflussen können. Einerseits möchten wir verhindern, dass wir den gleichen Connection-Pool für mehrere externe Dienste verwenden. Falls z. B. die Latenz des ERP-Systems zunimmt und somit den Connection-Pool füllt, können wir nicht mehr auf die Datenbank mit vorberechneten Preisen zugreifen. Das Bulkhead Pattern kann in diesem Falle angewendet werden [3].

Besonders wichtig ist es, ein Timeout auf einen externen Dienst festzulegen. Ansonsten besteht die potenzielle Gefahr, die eigene Kapazität zu erschöpfen, und die Wartezeit wird weiter propagiert. Das Timeout sollte dabei die maximale Antwortzeit für den externen Dienst festlegen. Eine entsprechende Implementierung davon kann z. B. für jede Verbindung dieses Timeout berücksichtigen oder einen Circuit Breaker (CB) für diesen Dienst einführen [6]. Der CB führt einen Health Check durch, um festzustellen, ob der Dienst verfügbar ist. Hierfür definiert man kontextspezifische Trip Breaker, die im Fehlerfalle den CB auf open schalten (nichts geht mehr durch). Nach einer bestimmten Zeit im Status open wechselt der CB auf half-open und lässt wieder eine Anfrage durch. Wird diese ordnungsgemäß beantwortet, schaltet der CB auf closed, also Normalbetrieb; falls nicht, auf open. Dies entspricht dem Fail-Fast-Prinzip und verhindert, ein bereits bekanntes Timeout mehrmals anzutreffen.

Abb. 2: Circuit Breaker

Bottleneck-Analyse

Application Performance Monitoring bietet bereits einen sehr guten Einstieg in die Analyse von Performance-Problemen. Jedoch gibt es Limitierungen, die bedingen, dass auf weitere Verfahren und Tools zurückgegriffen wird. Einerseits läuft die Applikation beispielsweise noch nicht in einem produktiven Umfeld und entsprechend kann ohne Last keine Analyse durchgeführt werden. In diesem Falle können Load-Test-Applikationen verwendet werden, um Simulationen durchzuführen. Andererseits kann es vorkommen, dass die Analyse aus den APM-Tools nicht das benötigte Detail hervorbringt. In einer solchen Situation können wir mittels Profiler einzelne Aufrufe im Java-Stack verfolgen.

Load-Testing-Applikationen wie Gatling oder JMeter ermöglichen das Nachahmen von komplexem Benutzerverhalten und eine entsprechende Simulation mit beliebig vielen Benutzern. Somit können Applikationen bereits während der Entwicklungsphase kontinuierlich quantifiziert werden. Dies ermöglicht einerseits Performanceprobleme frühzeitig zu erkennen und ebenfalls Kennzahlen zu ermitteln.

Ein Profiler wie JProfiler ermöglicht die Messung von Applikationscode auf der lokalen Entwicklungsumgebung. Man unterscheidet dabei zwischen Sampling und Instrumentierung. Letzteres misst einzelne Aufrufe und ermöglicht die Einsicht aller einzelnen Komponenten im Java-Stack. Das heißt, ich kann z. B. feststellen, welche Methode innerhalb des Aufrufs am meisten Zeit konsumiert. Sampling hingegen entnimmt aus mehreren Aufrufen eine statistische Auswertung und zeigt auf, wo Problemfelder versteckt sein könnten. Beide Methoden eignen sich in Kombination, um Deep-dive-Analysen durchzuführen.

HTTP/2: Die Umstellung lohnt sich

Eine der ersten Maßnahmen zur Verbesserung der Performance auf dem Backend ist künftig der Einsatz von HTTP/2. Dies hat viele verschiedene Gründe, vor allem in Bezug darauf, Netzwerkkapazitäten im Vergleich zu HTTP/1 effizienter zu nutzen. Wir werden in den kommenden Artikeln genauer auf die Vorteile von HTTP/2 eingehen, wenn wir über Latenz und Kapazitäten sprechen. Vorerst reicht es, wenn wir künftig dafür Sorge tragen müssen, dass unser Webserver HTTP/2 unterstützt. Browser und Clients, die HTTP/2 unterstützen, werden automatisch auf das neue Protokoll wechseln. Alle bestehenden alten Clients kommunizieren weiterhin mit HTTP/1. Da die Semantik des Protokolls gleich geblieben ist, benötigt ein Rollout von HTTP/2 keine Anpassungen an der Webapplikation. Wenn noch keine Erfahrungen mit HTTP/2-Webservern im Betrieb vorliegen und per Domain Sharding statische Assets ausgeliefert werden, so beginnt man am besten bei diesem Teil der Architektur.

Schneller und sicherer durch Transport Layer Security und HTTP/2
Im HTTP/2-Standard war die zwingende Verwendung von Transport Layer Security (TLS) vorgesehen. Der Zwang wurde jedoch gestrichen, sodass der Standard den Einsatz von TLS nur empfiehlt. Die meisten Browserhersteller haben aber die Implementierung von HTTP/2 ausschließlich per TLS in ihre Produkte eingebaut. Damit wird der Einsatz von TLS im Betrieb zwingend und muss entsprechend bei der Auslegung der Infrastruktur berücksichtigt werden. Durch den zusätzlichen TLS-Handshake erhöht sich die Response-Zeit bei initialen Handshakes, was gerade bei Verbindungen mit hoher Latenz (z. B. Mobile) problematisch sein kann. Jedoch mitigiert HTTP/2 durch die effizientere Nutzung der Kapazität den (geringfügig) längeren Verbindungsaufbau durch zügigeres Laden aller weiteren Ressourcen. Durch HTTP/2 wird es also schneller und sicherer.

Application Caching
Die Zwischenspeicherung von Inhalten ist seit jeher eine Maßnahme zur Verbesserung der Performance. Allerdings sollte man sich vor Augen halten, dass Caching nie eine Anforderung, sondern immer ein Workaround ist. In einer perfekten Welt bräuchten wir keinen Cache, denn das Netzwerk und alle involvierten Systeme wären schnell genug. Was gilt es also zu beachten, damit der Workaround kein Rohrkrepierer wird?

Zunächst verursacht ein Application Level Caching, d. h. die Speicherung von Objekten in der JVM als Teil unserer Anwendung, eine erhöhte Komplexität. Wenn es hier um eine einfache Liste geht, die nie invalidiert werden muss, ist diese Steigerung nicht hoch. Oft sind es aber komplexe Geschäftsobjekte, die unter Einbezug von Drittsystemen komponiert werden möchten. In diesem Fall erreicht die zusätzliche Komplexität dann eine Größenordnung, die im Vergleich zum Aufwand nicht mehr zu rechtfertigen ist, weil die Invalidierung eine eigene Geschäftslogik notwendig macht.

Wer heute ein Websystem produziert, möchte am besten so wenig Application Level Caching wie möglich betreiben und das Problem auf eine eigene Schicht auslagern, die über HTTP Cache Header gesteuert wird. Komplexe Geschäftsobjekte werden erst auf dem Frontend komponiert, dazwischen sorgt ein dedizierter Cache für die Performance. Abbildung 3 zeigt dies am Beispiel.

Der Vorteil dieser Delegation liegt auf der Hand: Ich kann eine handelsübliche Lösung wie Varnish direkt auf meinem Server installieren, ein Content-Delivery-Network einsetzen oder einfach auf den Browser-Cache setzen. Da die HTTP Cache Header standardisiert sind, gibt es in Bezug auf die Architektur viele Möglichkeiten. Tatsächlich kann ich das gewünschte Cacheverhalten sehr früh implementieren (und testen) und damit den konkreten Technologieentscheid dadurch lange hinauszögern. Den Freunden des Last-Responsible-Moment-Prinzips (LRM, [7]) kommt das zupass.

Setzt man also auf einen HTTP-Cache in einer dedizierten Schicht, schlägt man vier Fliegen mit einer Klappe: Die Komplexität wird geringer, gleichzeitig wird die Testbarkeit und Änderbarkeit erhöht und die Performance steigt. Konkret haben wir in weltweit verteilten Websites gute Erfahrungen mit dem Caching aller Inhalte (außer den personalisierten) für jeweils 15 Minuten gemacht. Je nach Traffic kann diese Zahl justiert werden.

Manchmal ist es nicht möglich, eine dedizierte Schicht für das Caching einzusetzen. Zum Beispiel, wenn die internen Architekturvorgaben keinen Varnish erlauben. Dann ist die Verwendung eines Caches in der JVM auch eine Option. Hier gibt es verschiedene Libraries, wie EhCache  oder Infinispan . Man sollte in einem solchen Fall versuchen, das Caching so einfach wie möglich zu gestalten, damit der Cache keine Fehler produziert. Wenn die Invalidierung von Inhalten nicht richtig funktioniert, kann die Anwendung schwierig zu reproduzierende Fehler aufweisen. Üblicherweise lassen sich diese In-Memory-Caches nicht so leicht testen, wie eine Beobachtung der HTTP-Header. Außer in den trivialsten Caching-Fällen wird die Komplexität der Anwendung steigen. Eine weitere Cachealternative sind Memcache oder Redis, die als eigene Maschinen betrieben werden können. Beide bieten einen In-Memory-Cache für die Speicherung von Datenstrukturen.

Setzt man einen solchen Cache ein, sollte man immer im Hauptspeicher cachen, da Plattenzugriffe nach wie vor zu langsam sind. In den meisten Fällen auch nicht zu empfehlen ist eine Cachepersistenz, damit die Einträge beispielsweise bei einem Neustart nicht verlorengehen. Zum einen muss man sich dann nämlich um den Storage State des Caches kümmern und zum anderen verlangsamt dies die Start-up-Zeit, da die Daten zunächst geladen werden müssen.

Abb. 3: Einsatz von Varnish als Cache

JVM tunen
Die Java Virtual Machine kann mittels Optionen auf den Anwendungsfall abgestimmt werden. Garbage Collection zeigt sich vor allem bei lang laufenden Applikationen, wie Web Services, als typisches Problemfeld. Garbage Collection (GC) räumt kontinuierlich den Speicherverbrauch der JVM auf. Dazu sind verschiedene Algorithmen und entsprechende Optionen vorhanden, die auf die Applikation abgestimmt werden müssen. Im schlimmsten Fall können Stop-the-World-Pausen auftreten, welche die Applikation potenziell über mehrere Minuten pausieren. Aktuelle GC-Verfahren, wie Concurrent Mark Sweep oder G1, versuchen, gerade solche Pausen zu umgehen und automatisch optimale Garbage-Zyklen für die Applikation zu ermitteln [8]. Um entsprechende Optionen manuell zu optimieren, müssen Benchmarks und Tests durchgeführt werden, die erst durch Performancetests und Monitoring ermöglicht werden.

Technologiewahl: Es gibt keinen Königsweg
Es ist sehr einfach: Setzen Sie nur Technologien ein, die das Team bereits kennt und gut findet, und beginnen Sie bei der Auswahl mit der Programmiersprache. Prinzipiell gibt es viele verschiedene Möglichkeiten. Zudem ist es nicht unwahrscheinlich, dass eine Liste derer zum Zeitpunkt der Veröffentlichung schon wieder veraltet wäre, so schnell dreht das Rad heute. Möchte man aber ein Beispiel geben, so wären Go oder Clojure interessante Optionen für die Serviceentwicklung. Java ist für alles Mögliche gut geeignet, weil es viele Entwickler gibt und die Plattform Maturität aufweist, aber dies ist eben auch bei PHP der Fall. Lua kommt. Es gibt keinen Königsweg, aber die Entscheidung sollte bewusst und begründet gefällt werden. Im Laufe des Projekts sollte man die gewählten Technologien regelmäßig auditieren, um sicherzustellen, dass es das zu Beginn bewusst ausgeschlossene Framework nicht doch über Umwege wieder in das Projekt geschafft hat. Unterm Strich geben sich die Technologien in Bezug auf Performance nicht viel. Zumindest nicht bei den Zugriffszahlen, wie wir sie üblicherweise bei Großunternehmen oder im Mittelstand erwarten.

Fazit
Die Backend Performance ist ein konstantes Thema, dem kontinuierlich durch Messung, Analyse und Bericht Rechnung getragen werden muss. Insbesondere moderne APM-Lösungen verursachen laufende Kosten, bei größeren Systemen sogar substanzielle. Da ein langsames System aber heute keine Option mehr ist, wenn man am Markt überleben möchte, gilt es, die Performance möglichst strukturiert und damit effizient durchzuführen und dies bereits zu Beginn der Systementwicklung. Werden Performanceprobleme erst nach Go-Live entdeckt, kann dies erhebliche Mehrkosten sowie einen Imageschaden nach sich ziehen.

Verwandte Themen:

Geschrieben von
Daniel Takai
Daniel Takai
Daniel Takai ist Enterprise-Architekt, arbeitet in der Schweiz und ist auf die digitale Transformation spezialisiert. Er berichtet regelmäßig im Java Magazin über seine Erfahrungen und Erkenntnisse. Im Frühling 2016 erscheint sein Buch über Methoden der Entwicklung von Cloud-basierten und serviceorientierten Websystemen.
Nicolas Bär
Nicolas Bär
Nicolas Bär arbeitet als IT-Architekt bei der Unic AG in Zürich. Als Performanceenthusiast optimiert er Webapplikationen und engagiert sich in seiner Freizeit im Open-Source-Umfeld.
Christian Wittwer
Christian Wittwer
Christian Wittwer ist IT-Architekt bei der Unic AG in Bern. Er kümmert sich mit seinem Team um die Performance von Webapplikationen, von der Entwicklung bis in den Betrieb.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: