Performance Tipps zu Web Services

20.09.2009 Permalink

Kommunikation über SOAP ist große Mode geworden, nicht zuletzt, da jede bedeutende Technologieplattform einen mehr oder minder ausgereiften SOAP-Stack bereithält. Nun ist SOAP fix auf XML gebunden, besser gesagt: auf das XML Infoset. Und auch REST, mit dem wegen seines einfachen Grundprinzips so mancher liebäugelt, kommt praktisch nicht ohne XML aus, obwohl beliebige Formate zulässig sind.

Das Verarbeiten von XML ist teuer, Remote Kommunikation ist sowieso teuer, aber wir nehmen das in Kauf. Es ist für betriebliche Informationssysteme üblich, sparsamen Umgang mit Rechenzeit und Speicher zugunsten von Interoperabilität, Portabilität und Wartbarkeit entweder zu opfern oder mit mehr "Blech" zu ersetzen. Auch wenn Techniker gerne das Gesicht verziehen, angesichts anhaltend hoher Personalkosten und stetig fallender Preise pro Taktzyklus und Speichereinheit macht das Sinn.

Manch ein Projektteam treibt das sorglose Spiel aber zu weit. Es entsteht Software, von der maßgeblich der Eindruck bleibt, dass sie nicht lasttauglich oder zu langsam ist und schlecht skaliert. Die ersten beiden Fragen, die ich stelle, wenn ich mir eine Meinung in einem solchen Fall bilden will, sind:

Zur ersten Frage treibt mich immer das folgende Bild, das die Aufrufzeiten für verschiedene Technologien vergleicht:

Vergleich

Man erkennt, dass ein Nachrichtenversand über das Netzwerk verglichen mit lokalen Methodenaufrufen extrem teuer ist, und solange wir in einem System davon unnötig viele haben, brauchen wir nicht weiter nach Optimierungsmöglichkeiten zu suchen. Durch Reduktion der Anzahl können wir ein gewaltiges Potential ausschöpfen. Abgesehen davon, dass diese Maßnahme meist aufwändig ist, weil sie verlangt, die beteiligte Software stark zu verändern, ist die Idee trivial, und hat insbesondere mit Web Services und XML nicht viel zu tun. Wo können wir aber speziell bei Web Services ansetzen, wenn diese erste Maßnahme noch nicht reicht?

Hier meine zweitbesten Ideen:

HTTP 1.1 und Keep-Alive verwenden
Der TCP Verbindungsaufbau selbst kostet bei jedem Austausch Zeit, die enorm ansteigt, wenn z.B. SSL/TLS im Spiel ist, denn zur Aushandlung des symmetrischen Sitzungsschlüssels ist asymmetrische Kryptographie erforderlich. Durch Keep-Alive, das bei HTTP 1.1 default ist, kann man die Häufigkeit der Aushandlung reduzieren.

Schemavalidierung in Produktion abschalten
Während Integrationsstests ist Schemavalidierung hilfreich, um die Übereinstimmung der versendeten Nachrichten mit den Angaben aus den Schnittstellenspezifikation festzustellen. Ist ein System aber getestet, so bringt die Validierung auf den meisten Kommunikationsstrecken keinen Wert mehr. Da sie teuer ist, kann man sie auch abschalten.

Kompression bei Kapazitätsproblemen Ist Netzwerkkapazität ein Flaschenhals, dann können sich die beteiligten Teilsysteme auf GZip Kompression und/oder Fast Infoset einigen, was sich vor allem bei großen Nachrichten deutlich auswirkt. Die Kompression benötigt natürlich mehr Rechenzeit, das muss man dann abwägen.

Teildekodierung von Nachrichten
Gerade bei Diensten, die im wesentlichen als Router fungieren, ist eine vollständige Deserialisierung großer XML Nachrichten nur teurer Luxus. Um inhaltsbasiert Entscheidungen zu treffen, reichen XPath Anfragen auf der nackten XML Nachricht.

MTOM für umfangreiche Binärdaten
Binärdaten in Base64 sind zwar in XML zulässig, aber bei Mengen über 100K eine ziemliche Belastung für XML Parser. MTOM verwendet das MIME Multipart Verfahren, um die Binärdaten aus XML auszulagern, ohne dass die Anwendung diese Zerlegung merkt.

Einsatz von WS-Security überdenken
Die Signaturberechnung und Verschlüsselung bei WS-Security verwendet asymmetrische Verfahren, die rechenintensiv sind. Gerade Verschlüsselung kann man auch durch SSL/TLS erreichen. Oder man richtet durch Firewalls oder VPN Vertrauenszonen ein, in denen keine Sicherheitsmaßnahmen auf dem Application Layer mehr erforderlich sind.

Einsatz von Reliable Messaging überdenken
Fragt man den unbedarften Anwender, dann darf natürlich keine einzige Nachricht verloren gehen, die Kommunikation muss jederzeit vollständig zuverlässig sein. Folgt man diesem hehren Ziel, dann zwingt das zum Einsatz von Messaging Lösungen, die jede Nachricht transaktionsgesichert auf einen Plattenspeicher schreiben. Das ist zwar sicher, aber eben auch teuer. Was kostet es tatsächlich, wenn bestimmte Nachrichten verloren gehen?

Ganz gleich, was wir am Ende umsetzen, es ist entscheidend, Performanceprobleme früh zu entdecken, denn gerade eine Restrukturierung von Teilsystemen, so dass weniger Aufrufe stattfinden, will man nicht erst nach einem Integrationstest beginnen. Frühes Entdecken gelingt, wenn man

Auch hier also gilt wie an so vielen Ecken in der Softwareentwicklung: Es braucht früh nur ein paar Tage, um sich späte Monate mühsamer Strafarbeit zu ersparen.