Integrated Data, Message, and Process Recovery for Failure Masking in Web Services [article]

German Shegalov, Universität Des Saarlandes, Universität Des Saarlandes
2006
Modern Web Services applications encompass multiple distributed interacting components, possibly including millions of lines of code written in different programming languages. With this complexity, some bugs often remain undetected despite extensive testing procedures, and occasionally cause transient system failures. Incorrect failure handling in applications often leads to incomplete or to unintentional request executions. A family of recovery protocols called interaction contracts provides
more » ... contracts provides a generic solution to this problem by means of system-integrated data, process, and message recovery for multi-tier applications. It is able to mask failures, and allows programmers to concentrate on the application logic, thus speeding up the development process. This thesis consists of two major parts. The first part formally specifies the interaction contracts using the state-and-activity chart language. Moreover, it presents a formal specification of a concrete Web Service that makes use of interaction contracts, and contains no other error-handling actions. The formal specifications undergo verification where crucial safety and liveness properties expressed in temporal logics are mathematically proved by means of model checking. In particular, it is shown that each end-user request is executed exactly once. The second part of the thesis demonstrates the viability of the interaction framework in a real world system. More specifically, a cascadable Web Service platform, EOS, is built based on widely used components, Microsoft Internet Explorer and PHP application server, with interaction contracts integrated into them. v Kurzfassung Heutige Web-Service-Anwendungen setzen sich aus mehreren verteilten interagierenden Komponenten zusammen. Dabei werden oft mehrere Programmiersprachen eingesetzt, und der Quellcode einer Komponente kann mehrere Millionen Programmzeilen umfassen. In Anbetracht dieser Komplexität bleiben typischerweise einige Programmierfehler trotz intensiver Qualitätssicherung unentdeckt und verursachen vorübergehende Systemsausfälle zur Laufzeit. Eine ungenügende Fehlerbehandlung in Anwendungen führt oft zur unvollständigen oder unbeabsichtigt wiederholten Ausführung einer Operation. Eine Familie von Recovery-Protokollen, die so genannten "Interaction Contracts", bietet eine generische Lösung dieses Problems. Diese Recovery-Protokolle sorgen für die Fehlermaskierung und ermöglichen somit, dass Entwickler ihre ganze Konzentration der Anwendungslogik widmen können. Dies trägt zu einer erheblichen Beschleunigung des Entwicklungsprozesses bei. Diese Dissertation besteht aus zwei wesentlichen Teilen. Der erste Teil widmet sich der formalen Spezifikation der Recovery-Protokolle unter Verwendung des Formalismus der State-and-Activity-Charts. Darüber hinaus entwickeln wir die formale Spezifikation einer Web-Service-Anwendung, die außer den Recovery-Protokollen keine weitere Fehlerbehandlung beinhaltet. Die formalen Spezifikationen werden in Bezug auf kritische Sicherheits-und Lebendigkeitseigenschaften, die als temporallogische Formeln angegeben sind, mittels "Model Checking" verifiziert. Unter anderem wird somit mathematisch bewiesen, dass jede Operation eines Endbenutzers genau einmal ausgeführt wird. Der zweite Teil der Dissertation beschreibt die Implementierung der Recovery-Protokolle im Rahmen einer beliebig verteilbaren Web-Service-Plattform EOS, die auf weit verbreiteten Web-Produkten aufbaut: dem Browser "Microsoft Internet Explorer" und dem PHP-Anwendungsserver. vi Summary Recovery is the last resort for preserving data and system state consistency in a failureprone environment. Critical applications use transactional database servers whose data recovery mechanisms establish atomic updates and durability of data in the presence of transient system failures. Unfortunately, data recovery on database servers does not enforce an appropriate exception handling in the other application components. It is the responsibility of every single component in the system to handle all system failures such as message losses, timeouts, and crashes in a correct manner. In a distributed application with a rich state some component interdependences are often overlooked, which leads to incorrect application behavior in that some requests may unintentionally be repeated whereas others may not be executed at all due to message losses. This has motivated several recovery protocols aiming at masking system failures, and so relieving developers from dealing with them. The queued transactions approach has been the most successful industrial solution thus far. It requires that components store their state in transactional input and output message queues mostly residing on a database server, or in a database. In a multi-tier system, a single end-user request incurs a number of instances of the Two-Phase-Commit protocol incurring high logging overhead. Due to an inconvenient programming model and for insufficient scalability in the context of multi-tier applications, queued transactions have not been adopted for Web Services, although most of them are stateful by nature since they require several interactions with the user to accomplish a deal: authentication, catalog search, price negotiation or bidding, and finally committing the deal. This thesis elaborates on a recently proposed framework of interaction contracts geared towards general multi-tier applications that is more efficient than the queued transactions approach, and does not enforce any specific programming style. This thesis provides for the first time a formal specification for each interaction contract previously only informally described in the original literature. To this end, we adopted the state-and-activity chart language as defined and implemented in the commercial tool Statemate, widely used for modeling reactive systems such as embedded devices in the automotive and airspace industries. Each individual interaction contract is defined by a generic activity that can be easily reused in every application context. We model a complex Web Service comprising several components, which pass messages to each other either in synchronous or asynchronous fashion with the generic interaction contract vii activities as building blocks. Most importantly, the Web Service model does not involve any recovery actions other than those defined in the underlying interaction contract activities that are invisible at the application layer. After completing the formal specification process, we start with verification of the interaction contracts using Statemate's integrated model checker. For this purpose, we formulate crucial safety and liveness properties as temporal logic formulae. As for safety, we show that no message is ever executed more than once. For liveness, we prove that with a finite number of failures each interaction contract eventually terminates, and the corresponding requests are executed exactly once. While the verification of the individual bilateral interaction contracts is straightforward due to their relatively small model size, additional design engineering effort is needed to keep the Web Service model verifiable. We succeed in designing equivalent or more general, verifiable models, whose safety properties carry over into the original specification of the interaction contracts. Along with the formal specification of the interaction contract framework, in this thesis we describe a prototype Web Service platform called EOS that we built to investigate the framework's viability in a real-world setting. More specifically, we consider two popular products used in the Web Service context: Microsoft Internet Explorer as a browser (user front-end), and a script engine PHP as a Web application server which can be invoked either by a browser or by another application server. We implement the external interaction contract to handle interactions between an end-user and her browser. Interactions between a pair of Web application servers, and between a browser and a Web application server run under either the committed or the immediately committed interaction contract. To this end, we turned the browser and the Web application server into persistent components by equipping them with logging and recovery routines. In accordance with the framework goals, we achieved this without rewriting existing application programs such as PHP scripts and the browser by solely changing their runtime environment. The most challenging part of this work was providing the deterministic replay of the multi-threaded PHP script engine in the business-to-business context, in which the state is shared by multiple sessions and may be simultaneously accessed by several other application servers. Thus, deterministic replay requires logging of original output messages. Enhanced components exhibit acceptable overhead in comparison with the original implementation, which shows their viability in large-scale Web Services. viii Zusammenfassung Die Recovery ist das letzte Mittel, das die Inkonsistenz der Daten und des Systemzustandes in einer fehleranfälligen Ausfürungsumgebung verhindern kann. Kritische Anwendungen benutzen transaktionsfähige Datenbanksysteme, die die atomare Ausführung von mehreren Schreiboperationen und deren Dauerhaftigkeit trotz kurzzeitig auftretender Fehler gewährleisten. Die Daten-Recovery im Datenbanksystem erzwingt jedoch nicht, dass Fehler auch in den anderen Anwendungskomponenten adäquat behandelt werden. Jede Komponente ist selbst dafür verantwortlich, allen möglichen Fehlern wie Nachrichtenverlusten, Wartezeitüberschreitungen und Abstürzen richtig zu begegnen. In einer verteilten Anwendung mit einem großen Zustand werden wechselseitige Abhängigkeiten oft übersehen, was zu einem falschen Systemverhalten führt, in dem manche Operationen unbeabsichtigt mehrmals ausgeführt werden, während die Ausführung anderer Operationen wegen Kommunikationsstörungen gänzlich unterbleibt. Diese Problematik diente als Motivation für mehrere fehlermaskierende Recovery-Protokolle, die Entwicklern die Behandlung von Fehlern abnehmen. Den bisher erfolgreichsten industriellen Ansatz stellt das Queued-Transactions-Verfahren dar. Es erfordert, dass Komponenten ihren Zustand in transaktionsfähigen, meistens von Datenbanksystemen verwalteten, Ein-und Ausgabewarteschlangen oder in einer Datenbank speichern. In einem Mehrschichtensystem zieht eine einzige Operation des Endbenutzers mehrere Instanzen des Two-Phase-Commit-Protokolls nach sich, was hohe Protokollierungskosten verursacht. Aufgrund des unbequemen Programmiermodells und der für verteilte Anwendungen ungenügenden Skalierbarkeit wurde das Queued-Transactions-Verfahren nicht in den Bereich der Web-Services übertragen, obwohl wir es dort auch mit fehleranfälligen zustandsvollen Anwendungen zu tun haben. Diese Dissertation beschäftigt sich mit dem in den letzten Jahren veröffentlichten Framework der "Interaction Contracts", das eigens für Mehrschichtensysteme entworfen wurde. Es ist effizienter als das Queued-Transactions-Verfahren und erzwingt keinen bestimmten Programmierstil. Diese Dissertation präsentiert erstmalig formale Spezifikationen der "Interaction Contracts", die bis jetzt nur informal in der Literatur eingeführt wurden. Zu diesem Zweck setzen wir mit State-and-Activity-Charts einen automatentheoretischen Formalismus ein. Dieser Formalismus ist implementiert im kommerziellen Tool ix Statemate, das eine breite Verwendung in der Automobilindustrie und der Luft-und Raumfahrtbranche hat. Jeder einzelne "Interaction Contract" wird modelliert durch eine generische Aktivität, die sich leicht in unterschiedlichen Anwendungsszenarien wiederverwenden lässt. Darüber hinaus, wir modellieren einen komplexen Web-Service, der aus mehreren Komponenten besteht. Die Komponenten tauschen mehrere Nachrichten synchron und asynchron aus, jeweils unter Verwendung der generischen Aktivitäten. Besonders wichtig ist, das hierbei keine andere als die für die Anwendungsebene unsichtbaren, in den generischen Aktivitäten definierten Recovery-Aktionen zum Tragen kommen. Die erstellten Spezifikationen der "Interaction Contracts" werden mit Hilfe des "Statemate Model Checker" verifiziert. Dazu formulieren wir wichtige Sicherheits-und Lebendigkeitseigenschaften als temporallogische Formeln. Als eine der Sicherheitseigenschaften beweisen wir beispielsweise, dass keine vom Endbenutzer initiierte Operation mehr als einmal ausgeführt wird. Unter der Annahme einer endlichen Anzahl von Fehlern beweisen wir, dass jeder "Interaction Contract" terminiert (Lebendigkeit) und die betreffenden Operationen genau einmal ausgeführt werden. Während sich die Verifikation der einzelnen "Interaction Contracts" aufgrund der verhältnismäßig geringen Modellkomplexität einfach gestalten ließ, erforderte die Verifikation der Web-Service-Anwendung zusätzlichen Aufwand, um analoge verifizierbarere Modelle zu finden, deren Sicherheitseigenschaften sich ins Ursprungsmodell übertragen lassen. Neben der formalen Spezifikation und Verifikation der "Interaction Contracts", beschreiben wir eine prototypische Implementierung der Web-Service-Plattform EOS, mit der die Praxistauglichkeit der "Interaction Contracts" in einer realen Software-Anwendung untersucht wird. Wir betrachten zwei beliebte Web-technologische Produkte: Internet Explorer, den Web-Browser von Microsoft, und den Interpreter der Skriptsprache PHP, die Ausführungsumgebung für Webanwendungsserver. Ein Webanwendungsserver kann entweder von einem Browser oder von einem anderen Webanwendungsserver aufgerufen werden. Wir implementieren den "External Interaction Contract", um die Interaktionen des Endbenutzers mit seinem Browser zu behandeln. Die Interaktionen zwischen zwei Webanwendungsservern und zwischen einem Browser und einem Webanwendungsserver werden durch den "Committed Interaction Contract" oder den "Immediately Committed Interaction Contract" geregelt. Hierzu statten wir den Browser 2 Background on Formal Methods 3. Given the basic operators above the following additional operators can be derived: Let P be a finite set of atomic proposition. The CTL formulae are interpreted over a Kripke structure K = (S, R, L), where S is the finite set of states, R OE S µ S is the state transition relation with (s, t) oe R if t is an immediate successor of s, and L: S µ P ö {0, 1} is the valuation function. Note that for a software system, the function L is interpreted as a valuation of individual bits of the program variables in the given program state. A computation tree is obtained through unwinding the graph (S, R). A path of the structure K is a potentially infinite state sequence (s 0 , ... , s i , s i+1 , ...) with each successive pair of states (s i , s i+1) oe R. Whether a current state s of the Kripke structure K fulfills the formula f denoted K, s 6= f is recursively defined over the formula structure: K, s 6= p ñ L(s , p) = 1, where p is an atomic proposition K, s 6= Ÿp ñ K, s 6∫ p K, s 6= p ⁄ q ñ K, s 6= p and K, s 6= q K, s 0 6= EX p ñ for at least one path (s 0 , s 1 , ...) holds K, s 1 6= p K, s 0 6= E(p U q) ñ for at least one path (s 0 , s 1 , ...) there is an i with K, s i 6= q and for all j < i holds K, s j 6= p K, s 0 6= A(p U q) ñ for all paths (s 0 , s 1 , ...) there is an i with K, s i 6= q and for all j < i holds K, s j 6= p Explicit CTL Model Checking The automatic recursive procedure that verifies whether K, s 6= f holds by using the finite state-transition graph (S, R) is called explicit model checking [Clarke and Schlinghoff 2001] . For a subset P OE S the set of predecessor states is defined as Pred(P) ú { s | (s, t) oe R and t oe P }, and the set of successors is defined as Succ(P) ú { t | (s, t) oe R and s oe P } Let g be a subformula of f and M g OE S such that s oe M g if K, s 6= g. Then, one can recursively apply the following explicit model checking algorithm of Figure 2 that considers seven different cases with regard to the structure of the formula f.
doi:10.22028/d291-23768 fatcat:5aa4fbxsxzbeplvvjjfoxm7xha