Design und Implementierung eines generischen QoS

Transcrição

Design und Implementierung eines generischen QoS
Fachhochschule Wiesbaden
Fachbereich Design Informatik Medien
Studiengang Allgemeine Informatik
Diplomarbeit
zur Erlangung des akademischen Grades
Diplom-Informatiker/in (FH)
Design und Implementierung eines generischen
QoS-Proxys für SOA Dienste
vorgelegt von Michael Frey
am 08. Dezember 2008
Referent: Prof. Dr. Kröger
Korreferent: Dipl.-Inform. (FH), M.Sc. Markus Schmid
II
Erklärung
Ich versichere, dass ich die Diplomarbeit selbstständig verfasst und keine anderen als die
angegebenen Hilfsmittel benutzt habe.
Wiesbaden, 08.12.2008
Michael Frey
Hiermit erkläre ich mein Einverständnis mit den im Folgenden aufgeführten Verbreitungsformen dieser Diplomarbeit:
Verbreitungsform
Einstellung der Arbeit in die
Bibliothek der FHW
Veröffentlichung des Titels der
Arbeit im Internet
Veröffentlichung der Arbeit im
Internet
Wiesbaden, 08.12.2008
ja
nein
√
√
√
Michael Frey
III
IV
Inhaltsverzeichnis
1
Einleitung
1
2
Grundlagen
5
2.1
Web-Service-Agreement-Protokoll . . . . . . . . . . . . . . . . . . . . .
5
2.1.1
Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.1.2
Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
2.1.2.1
Struktur eines Agreements . . . . . . . . . . . . . . .
8
2.1.2.2
Struktur eines Agreement Templates . . . . . . . . . .
15
2.1.2.3
Agreement-Zustände . . . . . . . . . . . . . . . . . .
16
2.1.3
Quality-of-Service-Erweiterung . . . . . . . . . . . . . . . . . .
17
2.1.4
Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
Service Component Architecture . . . . . . . . . . . . . . . . . . . . . .
20
2.2.1
Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.2.2
Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
2.2.3
Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
2.2.4
Apache Tuscany SCA . . . . . . . . . . . . . . . . . . . . . . .
33
Queueing-Strategien . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
2.3.1
Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
2.3.2
Strategien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
2.3.2.1
Multi Band Priority Queueing . . . . . . . . . . . . . .
36
2.3.2.2
Stochastic Fairness Queueing . . . . . . . . . . . . . .
37
2.3.2.3
Weighted Fair Queuing . . . . . . . . . . . . . . . . .
38
2.3.2.4
Class Based Queueing . . . . . . . . . . . . . . . . . .
39
2.3.2.5
Leaky Bucket . . . . . . . . . . . . . . . . . . . . . .
39
2.3.2.6
Hierarchical Token Bucket . . . . . . . . . . . . . . .
40
2.2
2.3
V
3
Analyse
41
3.1
Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
3.1.1
Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
3.1.2
Queueing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
3.1.3
Monitoring und Konfiguration . . . . . . . . . . . . . . . . . . .
44
Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
3.2.1
Erweiterung der SCA . . . . . . . . . . . . . . . . . . . . . . . .
45
3.2.2
Erweiterung von Tuscany . . . . . . . . . . . . . . . . . . . . .
49
3.2.3
Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . .
56
Queueing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
3.3.1
Untersuchung der Queueing-Strategien . . . . . . . . . . . . . .
56
3.3.2
Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . .
58
Monitoring und Konfiguration . . . . . . . . . . . . . . . . . . . . . . .
59
3.4.1
Java Management Extensions . . . . . . . . . . . . . . . . . . .
60
3.4.2
Monitoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
3.4.2.1
Kenngrößen . . . . . . . . . . . . . . . . . . . . . . .
62
3.4.2.2
Instrumentierung . . . . . . . . . . . . . . . . . . . . .
63
3.4.3
Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
3.4.4
Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . .
66
3.2
3.3
3.4
4
Design
67
4.1
Architekturüberblick . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67
4.2
Queueing-Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
4.2.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
4.2.2
Beschreibung der Klassen . . . . . . . . . . . . . . . . . . . . .
71
4.2.3
Beispiel: Weighted-Fair-Queueing-Algorithmus . . . . . . . . . .
75
Monitoring-Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
4.3.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
4.3.2
Beschreibung der Klasse . . . . . . . . . . . . . . . . . . . . . .
77
WS-Agreement-Subsystem . . . . . . . . . . . . . . . . . . . . . . . . .
80
4.4.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
4.4.2
Beschreibung der Klasse . . . . . . . . . . . . . . . . . . . . . .
81
Konfigurationssubsystem . . . . . . . . . . . . . . . . . . . . . . . . . .
81
4.3
4.4
4.5
VI
4.6
4.7
4.8
5
4.5.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
81
4.5.2
Konfiguration des QoS-Proxys . . . . . . . . . . . . . . . . . . .
83
4.5.2.1
Initialisierung . . . . . . . . . . . . . . . . . . . . . .
83
4.5.2.2
Management . . . . . . . . . . . . . . . . . . . . . . .
85
4.5.3
Beschreibung der Klassen . . . . . . . . . . . . . . . . . . . . .
85
4.5.4
Ablauf der Kommunikation . . . . . . . . . . . . . . . . . . . .
91
Integrationssubsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . .
92
4.6.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
92
4.6.2
Beschreibung der Klassen . . . . . . . . . . . . . . . . . . . . .
93
Proxy-Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
95
4.7.1
Anpassung einer SCA-Anwendung . . . . . . . . . . . . . . . .
95
4.7.2
Initialisierung der Subsysteme . . . . . . . . . . . . . . . . . . .
96
Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
Implementierung
101
5.1
Umgebung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
5.2
Namenskonventionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
5.3
Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
5.4
Queueing-Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
5.5
5.6
5.7
5.8
5.9
5.4.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
5.4.2
Beschreibung der Implementierung . . . . . . . . . . . . . . . . 104
Monitoring-Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
5.5.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
5.5.2
Beschreibung der Implementierung . . . . . . . . . . . . . . . . 107
WS-Agreement-Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . 108
5.6.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
5.6.2
Beschreibung der Implementierung . . . . . . . . . . . . . . . . 109
Konfigurationsubsystem . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.7.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.7.2
Beschreibung der Implementierung . . . . . . . . . . . . . . . . 111
Integrationssubsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
5.8.1
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
5.8.2
Beschreibung der Implementierung . . . . . . . . . . . . . . . . 113
Proxy-Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
5.10 Implementierungsaufwand . . . . . . . . . . . . . . . . . . . . . . . . . 118
5.11 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
VII
6
Bewertung
123
6.1
Bewertung der Architektur . . . . . . . . . . . . . . . . . . . . . . . . . 123
6.2
Bewertung der Leistungsfähigkeit . . . . . . . . . . . . . . . . . . . . . 124
6.2.1
Versuchsaufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
6.2.2
Auswertung der Messungen . . . . . . . . . . . . . . . . . . . . 125
6.2.3
Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . 126
7
Zusammenfassung
127
8
Literaturverzeichnis
131
A Abkürzungen
137
B Messwerttabellen für den QoS-Proxy
141
C Inhalt des Datenträgers
143
VIII
Abbildungsverzeichnis
2.1
Sequenzdiagramm: Agreement Creation Process . . . . . . . . . . . . . .
8
2.2
Agreement Zustände aus Sicht des Initiators . . . . . . . . . . . . . . . .
16
2.3
Beziehung von Component und Implementation (nach [BBB+ 07]) . . . .
24
2.4
SCA Service Symbol (nach [BBB+ 07]) . . . . . . . . . . . . . . . . . . .
27
2.5
SCA Reference Symbol (nach [BBB+ 07]) . . . . . . . . . . . . . . . . .
29
2.6
SCA Component Diagramm (nach [BBB+ 07]) . . . . . . . . . . . . . . .
29
2.7
Tuscany-SCA-Java-Architektur (nach [Fou08]) . . . . . . . . . . . . . .
34
2.8
Tuscany-SCA-Contribution-Modell (nach [Fou08]) . . . . . . . . . . . .
35
2.9
Graphische Repräsentation der Begriffe der Bedientheorie . . . . . . . .
37
2.10 Multi Band Priority Queueing . . . . . . . . . . . . . . . . . . . . . . .
37
2.11 Stochastic Fairness Queueing . . . . . . . . . . . . . . . . . . . . . . . .
38
2.12 Weighted Fair Queuing . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
3.1
Anwendungsfalldiagramm: Berücksichtigung QoS-Anforderungen . . . .
42
3.2
Anwendungsfalldiagramm: Umsetzung QoS-Anforderungen . . . . . . . .
42
3.3
Anwendungsfalldiagramm: Service Level Management . . . . . . . . . .
43
3.4
Calculator Service Component . . . . . . . . . . . . . . . . . . . . . . .
48
3.5
Calculator Service Component mit QoS-Proxy Component . . . . . . . .
49
3.6
Tuscany-SCA-Runtime-Wire-Modell (nach [Fou08]) . . . . . . . . . . . .
50
3.7
Integration Policy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
3.8
Integration Proxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
3.9
Integration Proxy mit Nachrichten-Queue . . . . . . . . . . . . . . . . .
55
3.10 Integration Proxy mit Thread-Queue . . . . . . . . . . . . . . . . . . . .
55
3.11 Java-Management-Extension-Architektur . . . . . . . . . . . . . . . . .
60
3.12 Instrumentierung von Apache Tuscany . . . . . . . . . . . . . . . . . . .
63
3.13 Kommunikation zwischen QoS-Proxy, WSAG4J und einem Client . . . . .
65
IX
3.14 Remote-Method-Invocation-Architektur (nach [Sun04]) . . . . . . . . . .
66
4.1
Grobarchitektur des QoS-Proxy . . . . . . . . . . . . . . . . . . . . . . .
67
4.2
Klassendiagramm: Überblick Queueing-Subsystem . . . . . . . . . . . .
70
4.3
Klassendiagramm: Item . . . . . . . . . . . . . . . . . . . . . . . . . . .
71
4.4
Klassendiagramm: Queue . . . . . . . . . . . . . . . . . . . . . . . . . .
72
4.5
Klassendiagramm: QueueStatistic . . . . . . . . . . . . . . . . . . . . .
73
4.6
Klassendiagramm: ItemList . . . . . . . . . . . . . . . . . . . . . . . . .
73
4.7
Klassendiagramm: Strategy . . . . . . . . . . . . . . . . . . . . . . . . .
74
4.8
Klassendiagramm: LeakyBucket . . . . . . . . . . . . . . . . . . . . . .
74
4.9
Klassendiagramm: Weighted-Fair-Queueing-Algorithmus . . . . . . . . .
75
4.10 Sequenzdiagramm: Bearbeitung eines Interceptors . . . . . . . . . . . .
77
4.11 Klassendiagramm: Statistic . . . . . . . . . . . . . . . . . . . . . . . . .
78
4.12 Klassendiagramm zur QoS-Proxy-WSAG4J Kommunikation . . . . . . . .
81
4.13 Überblick über das Konfigurationssubsystem . . . . . . . . . . . . . . .
82
4.14 Klassendiagramm: ICallback und Callback . . . . . . . . . . . . . . . .
86
4.15 Klassendiagramm: ServiceClass . . . . . . . . . . . . . . . . . . . . . .
86
4.16 Klassendiagramm: ServiceLevelAgreement . . . . . . . . . . . . . . . .
87
4.17 Klassendiagramm: ServiceLevelAgreementList . . . . . . . . . . . . . .
88
4.18 Klassendiagramm: ServiceLevelAgreementFile . . . . . . . . . . . . . .
88
4.19 Klassendiagramm: ConfigurationFile . . . . . . . . . . . . . . . . . . .
89
4.20 Klassendiagramm: ConfigurationFile . . . . . . . . . . . . . . . . . . .
89
4.21 Klassendiagramm: Manager . . . . . . . . . . . . . . . . . . . . . . . .
90
4.22 Sequenzdiagramm: Kommunikation mit WSAG4J-System/QoS-Proxy . . .
92
4.23 Klassendiagramm: ProxyPolicyProcessor . . . . . . . . . . . . . . . . .
93
4.24 Klassendiagramm: ProxyPolicyInterceptor . . . . . . . . . . . . . . . . .
95
4.25 Klassendiagramm: Proxy . . . . . . . . . . . . . . . . . . . . . . . . . .
97
4.26 Sequenzdiagramm: Berücksichtigung QoS-Anforderungen . . . . . . . . 100
6.1
Aufbau der Versuche für die Leistungsbewertung . . . . . . . . . . . . . 125
X
Tabellenverzeichnis
3.1
Bewertung der Queueing-Strategien . . . . . . . . . . . . . . . . . . . .
58
3.2
Berechnung der Kenngrößen im QoS-Proxy . . . . . . . . . . . . . . . .
64
5.1
Implementierungsaufwand sortiert nach Subsystemen . . . . . . . . . . . 119
6.1
Mittelwerte der Versuch 1 bis 3 . . . . . . . . . . . . . . . . . . . . . . . 126
B.1 Messwerte für Versuch 1 . . . . . . . . . . . . . . . . . . . . . . . . . . 141
B.2 Messwerte für Versuch 2 . . . . . . . . . . . . . . . . . . . . . . . . . . 141
B.3 Messwerte für Versuch 3 . . . . . . . . . . . . . . . . . . . . . . . . . . 142
XI
XII
Verzeichnis der Quellcodes
2.1
Agreement-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . .
8
2.2
AgreementContextType-XML-Schema . . . . . . . . . . . . . . . . . . .
9
2.3
AgreementRoleType-XML-Schema . . . . . . . . . . . . . . . . . . . . .
9
2.4
TermCompositorType-XML-Schema . . . . . . . . . . . . . . . . . . . .
10
2.5
ServiceDescriptionTermType-XML-Schema . . . . . . . . . . . . . . . .
11
2.6
ServiceReferenceTermType-XML-Schema . . . . . . . . . . . . . . . . .
11
2.7
ServicePropertiesType-XML-Schema . . . . . . . . . . . . . . . . . . . .
11
2.8
Variable-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
2.9
GuaranteeTermType-XML-Schema . . . . . . . . . . . . . . . . . . . . .
12
2.10 ServicelLevelObjective-XML-Schema . . . . . . . . . . . . . . . . . . .
13
2.11 Business-Value-List-XML-Schema . . . . . . . . . . . . . . . . . . . . .
13
2.12 Penalty-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
2.13 Preference-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . .
14
2.14 Template-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
2.15 Item-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
2.16 QoS-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
2.17 Webservice-Agreement-Beispiel . . . . . . . . . . . . . . . . . . . . . .
19
2.18 Property-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
2.19 Implementation-XML-Schema . . . . . . . . . . . . . . . . . . . . . . .
23
2.20 Component-Type-XML-Schema . . . . . . . . . . . . . . . . . . . . . . .
24
2.21 ConstrainingType-XML-Schema . . . . . . . . . . . . . . . . . . . . . .
24
2.22 Binding-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
2.23 Interface-Java-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . .
26
2.24 Service-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
2.25 Wire-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
XIII
2.26 Reference-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . .
28
2.27 Component-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . .
29
2.28 Composite-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . .
30
2.29 SCA-Interface-XML-Schema . . . . . . . . . . . . . . . . . . . . . . . .
31
2.30 SCA-Interface-Java-XML-Schema . . . . . . . . . . . . . . . . . . . . .
32
2.31 Calculator Composite . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
3.1
Beispiel-composite mit JDKLoggingPolicy . . . . . . . . . . . . . . .
51
3.2
Beispiel-defintions.xml der JDKLoggingPolicy . . . . . . . . . . .
52
4.1
QoS-Proxy-XML-Schema der Konfigurationsdatei . . . . . . . . . . . . .
83
4.2
XML-Schema der Service-Level-Agreement-Datei . . . . . . . . . . . . .
84
4.3
Beispiel: Auszug aus der Datei definitions.xml . . . . . . . . . . .
94
4.4
Beispiel: Angepasste composite-Datei einer SCA-Anwendung . . . . .
96
5.1
Beispiel: Konfigurationsdatei für log4j . . . . . . . . . . . . . . . . . . . 102
5.2
Konfiguration: StAXArtifactProcessor-Datei . . . . . . . . . . . . . . . . 114
5.3
Konfiguration: ProxyPolicyProviderFactory-Datei . . . . . . . . . . . . . 115
5.4
definitions.xml-Datei des QoS-Proxys . . . . . . . . . . . . . . . 116
5.5
Konfiguration: SCADefinitionsProvider-Datei . . . . . . . . . . . . . . . 116
5.6
Logging: Initialisierung des QoS-Proxys . . . . . . . . . . . . . . . . . . 118
5.7
Logging: Bearbeiten einer Web-Service-Anfragen . . . . . . . . . . . . . 120
5.8
Logging: Wartende Web-Service-Anfragen . . . . . . . . . . . . . . . . . 121
XIV
Vorwort
Diese Diplomarbeit entstand im Labor für Verteilte Systeme an der Fachhochschule Wiesbaden.
Ich möchte mich hiermit bei Herrn Prof. Dr. Kröger sowie bei Herrn Schmid für die hervorragende Unterstützung und Betreuung während der Erstellung dieser Arbeit bedanken.
Ein besonderer Dank gilt meiner Familie, die während des gesamten Studiums immer
hinter mir stand und mir sowohl finanziell als auch moralisch den Rücken frei gehalten
hat.
Wiesbaden, im Dezember 2008
Michael Frey
XV
XVI
Kapitel 1
Einleitung
Im Zuge der Globalisierung unterliegen Unternehmen neuen Anforderungen in der Geschäftswelt. Neue Märkte und Mitbewerber erfordern eine Transformation von Geschäftsprozessen auf IT- und TK-Technologien. Ziel der Transformation ist die Nutzung
der Spezialisierungs-, Rationalisierungs- und Anpassungsmöglichkeiten dieser Technologien zur Effizienzsteigerung [Kö07]. Realisiert wird diese Entwicklung durch den Einsatz
unternehmensweiter verteilter Anwendungen. Diese Anwendungen werden auch als Geschäftsanwendungen bezeichnet.
Zu den Anforderungen an Geschäftsanwendungen gehören die Integration in bereits im
Unternehmen existierende Systeme, Flexibilität bei der Abbildung von Geschäftsprozessen und Interoperabilität mit den Systemen kooperierender Unternehmen. Mit der zunehmenden Durchdringung von Unternehmen mit Geschäftsanwendungen und der Integration unterschiedlicher Geschäftsprozesse in Geschäftsanwendungen steigt die Anzahl der
an einer Anwendung beteiligten Anwendungskomponenten. Restrukturierungen, Unternehmenszukäufe und Verkäufe von Unternehmensteilen erfordern die Anpassung der bestehenden Software und erhöhen die Komplexität der gesamten Softwarearchitektur. Viele Unternehmen tendieren mittlerweile dazu, im Rahmen der Kostensenkung den Betrieb
und das Management von Geschäftsanwendungen, an externe Dienstleister auszulagern.
Dieser Prozess wird auch als Outsourcing bezeichnet.
Eine Umsetzungsansatz für diese Anforderungen bietet das Modell der Serviceorientierten Architektur (SOA) [Erl07]. Das Modell beschreibt ein Paradigma für die Strukturierung und Nutzung von verteilter Funktionalität, die von unterschiedlichen Benutzern
verantwortet wird. Bestehende Geschäftsanwendungen und ihre Schnittstellen werden in
Dienste gekapselt. Die Dienste einer SOA bieten damit standardisierte, plattform- und
programmiersprachenunabhängige Schnittstellen.
1
Kapitel 1. Einleitung
Vorteil von SOA-basierten Anwendungen ist die eindeutige Spezifikation von Schnittstellen. SOA-basierte Geschäftsanwendungen erleichtern das Outsourcing, da durch die Spezifikation von Schnittstellen eine klare Trennung in Dienste vorgenommen werden kann.
Die Trennung in Dienste ist auch für große Unternehmen interessant, deren Anwendungen unter Umständen verteilt in verschieden Abteilungen laufen. Geschäftsanwendungen
sind kritisch für den Unternehmenserfolg und erfordern damit vertragliche Zusicherungen
zwischen einem Unternehmen und einem Outsourcing-Dienstleister oder zwischen einem
Unternehmen und seinen Abteilungen. Für ein Kunden sind dabei nicht-funktionale Anforderungen wie Zusicherungen an die Dienstgüte (Quality of Service, QoS) [Tan02] von
besonderer Bedeutung. Über die Dienstgüte eines Dienstes lassen sich unterschiedliche
Dienstgüteklassen definieren. Je höher die Anforderungen an einen Dienst, desto höher
die Wertigkeit der Dienstgüteklasse. Outsourcing-Dienstleister oder Unternehmen können
zwischen verschiedenen Kunden eines Dienstes unterscheiden und erhalten ein Abrechnungsmodell auf Basis von Dienstgüteklassen für einen Dienst.
Die wenigsten Implementierungen unterstützen jedoch Zusicherungen an die Dienstgüte
einer Geschäftsanwendung. Das Anpassen einer bestehenden SOA-Anwendung um eine
Dienstgütefunktionalität kann als zu aufwendig betrachtet werden. Wünschenswert wäre
eine generische Lösung für unterschiedliche Dienste. Eine solche Lösung soll sich transparent integrieren lassen um die Schnittstellen gegenüber einem Nutzer zu erhalten. Ein
solcher generische und transparente QoS-Proxy erfordert keine Anpassung an einer Geschäftsanwendung und keine Anpassung am System des Teilnehmers.
Das Ziel dieser Arbeit ist der Entwurf und die Implementierung eines generischen QoSProxys für SOA-Dienste. Der QoS-Proxy sollte generisch implementiert werden um eine
Kombination mit beliebigen SOA-basierten Anwendungen zu erleichtern.
Weiterhin sollen verschiedene Priorisierungsstrategien auf Ihre Eignung zur Umsetzung
von Dienstgütekriterien untersucht werden und in dem QoS-Proxy integriert werden. Um
die Integration des QoS-Proxys in eine bestehende SLM-Umgebung zu erleichtern, solle
das Monitoring und die Konfiguration über eine einheitliche Schnittstelle erfolgen.
Im folgenden Kapitel wird in grundlegende Technologien eingeführt. Zunächst wird detailliert die Web-Service-Agreement-Spezifikation betrachtet. Im Anschluß wird die Architektur der Service Component Architecture vorgestellt. Das Kapitel endet mit einer
kurze Einführung in Begriffe der Bedientheorie und stellt unterschiedliche QueueingStrategien vor.
In Kapitel 3 werden zunächst die Anforderungen an einen generischen QoS-Proxy formuliert. Auf Grundlage der Anforderungen wird die Service Component Architecture
2
Kapitel 1. Einleitung
auf mögliche Ansätze zur Integration des QoS-Proxys untersucht. Weiterhin werden die
im Grundlagenkapitel vorgestellten Queueing-Strategien auf ihre Tauglichkeit zur Umsetzung von Dienstgüteeigenschaften analysiert. Das Kapitel endet mit einer Betrachtung
von möglichen Ansätzen zum Monitoring und der Konfiguration des Proxys. Diese Betrachtung schließt das Definieren von Kenngrößen und Identifizieren von Instrumentierungspunkten im Entwurf der Architektur ein.
Aufbauend auf der Analyse beschreibt Kapitel 4 einen Entwurf der Architektur des QoSProxys. Zunächst wird dabei aus den im vorherigen Kapitel beschriebenen Anforderungen eine Grobarchitektur formuliert und einzelne Subsysteme identifiziert. Die einzelnen
Subsysteme werden nach einer Bottom-Up-Strategie beschrieben. Das Kapitel endet mit
einer Zusammenfassung in der ein in der Analyse vorgestellter Anwendungsfall das Zusammenspiel der einzelnen Subsysteme verdeutlicht.
In Kapitel 5 wird die verwendete Entwicklungsumgebung und Werkzeuge vorgestellt. Im
Anschluß werden die Implementierungsdetails der zuvor entworfenen Subsysteme betrachtet.
Kapitel 6 beginnt mit einer architekturellen Bewertung der Implementierung des QoSProxys. Nach der ersten Bewertung wird das Messmodell einer leistungsorientierten Bewertung vorgestellt und entsprechende Messungen durchgeführt.
Die Arbeit endet mit einer zusammenfassenden Bewertung und stellt nächste mögliche
Implementierungsschritte vor und gibt einen Ausblick auf mögliche weitere Entwicklungen im Bereich Quality of Service für Service-orientierte Architekturen.
3
Kapitel 1. Einleitung
4
Kapitel 2
Grundlagen
2.1
2.1.1
Web-Service-Agreement-Protokoll
Einleitung
Aufgrund wirtschaftlichen Drucks sind viele Unternehmen gezwungen Kosten einzusparen. Dienstleistungen, die nicht Teil der Kernkompetenzen eines Unternehmens sind, werden ausgelagert. Besonders das Auslagern von IT-Dienstleistungen an Drittanbieter ist zu
beobachten [Deb04]. Mit der Auslagerung von Diensten und Teilprozessen an externe
Dienstleister enstehen Anforderungen, die in einem vertraglichen Rahmen festgehalten
werden müssen. Mit den Jahren haben sich verschiedene Verfahren für die Umsetzung von
IT-Service-Management herausgebildet. Diese Strategien werden in der IT Infrastructure
Library (ITIL)1 zusammengefasst.
Einen Rahmen für das vertragliche Erfassen von Anforderungen an einen Dienst und Teilprozesse bietet das Dienstgütemanagement (Service Level Management, SLM) [BVP06,
Lew99]. Das SLM ist Teil der Service-Delivery-Sepzifikation der ITIL [GC01]. Die
Service-Delivery-Spezifikation ist verantwortlich für den strategischen Teil des ITGeschäftes einer Firma und stellt IT-Services durch planende und steuernde Prozesse
sicher.
SLM beschäftigt sich mit der Einhaltung von Dienstgütevereinbarungen. Dienstgütevereinbarungen werden formal in Service Level Agreements (SLAs) zwischen Anbieter und
Nutzer eines Services vereinbart. Das SLA, als vertragliches Rahmenwerk, besteht aus
1
Homepage der ITIL: http://www.itil-officialsite.com/home/home.asp
5
2.1. Web-Service-Agreement-Protokoll
Kapitel 2. Grundlagen
Dienstgüteparametern, die in Form von SLA-Parametern spezifiziert werden. Um die Einhaltung der SLAs festzustellen, muss das System überwacht werden. Für die technische
Überwachung sind insbesondere Dienstgüteparameter relevant, welche sich auf die Verfügbarkeit und Performanz eines Services beziehen. Beispiele für solche Parameter sind
der Durchsatz und die Antwortzeit eines Services. Der Durchsatz beschreibt, wieviele Anfragen innnerhalb einer bestimmten Zeitspanne verarbeitet werden. Die Antwortzeit wird
definiert als die Zeit, die ein Service benötigt, um die Anfrage eines Clients zu beantworten. In sogenannten Service Level Objectives (SLOs) werden zulässige Wertebereiche für
diese Dienstgüteparameter definiert. Neben der Pflege und ständige Verbesserung der mit
einem Kunden vereinbarten IT-Services, gehört zu den Aufgaben des SLMs, die definierten SLA-Parameter und ihre SLOs permanent zu überwachen. Die technische Grundlage
für die Realisierung von SLM bildet daher eine Management-Infrastruktur.
Mit WS-Agreement soll im folgenden Abschnitt eine Spezifikation vorgestellt werden,
die einen Teilansatz für die technische Umsetzung von SLM bietet.
2.1.2
Architektur
Web Services Agreement (WS-Agreement) ist eine Spezifikation des Open Grid Forums
(OGF)1 und definiert ein Web-Service-basiertes Protokoll zur Aushandlung von Vereinbarungen (Agreements) zwischen zwei Partnern [ACD+ 07]. Ein verwandter Ansatz zur
technischen Umsetzung findet sich in HPs Open-View-Internet-Services-Anwendung2 ,
die mit Hilfe der Web Service Management Language ausgedrückte Dienstgüteanforderungen überwacht [SMS+ 02]. Inhalt der WS-Agreement-Spezifikation sind die zur Kommunikation nötigen XML-Schemata und die Beschreibung von Operationen zur Verwaltung des Lebenszyklus von SLAs.
SLAs werden in der Regel zwischen einem Anbieter von Services (Service Provider) und
einem möglichen Nutzer der Services (Service Consumer) getroffen. Ursprünglich für den
Grid-Kontext entwickelt, erlaubt die flexible Architektur, die Spezifikation auch außerhalb dieses Bereiches einzusetzen. Der vorliegende Abschnitt stellt die Architektur näher
vor und führt in verschiedene Begriffe ein. Darauf aufbauend wird die Struktur der XMLDokumente beschrieben. Im Anschluss werden die möglichen Zustände zur Lebenszeit
eines Agreements betrachtet. Abschließend wird eine Quality-of-Service-Erweiterung für
WS-Agreement, die im Labor für Verteilte Systeme3 der FH Wiesbaden entwickelt wurde,
1
Homepage des Open Grid Forums: http://www.ggf.org/
Homepage von HP Internet Services: http://openview.hp.com/products/ovis/index.html
3
Homepage des Labors für Verteilte Systeme: http://wwwvs.informatik.fh-wiesbaden.de
2
6
Kapitel 2. Grundlagen
2.1. Web-Service-Agreement-Protokoll
vorgestellt und ein Beispiel-Agreement mit der Erweiterung präsentiert.
Zur besseren Abstraktion unterscheidet WS-Agreement zwischen einem Agreement und
dem Service Layer. Der Agreement Layer offeriert eine Web-Services-Schnittstelle zum
Erzeugen, Beobachten und Verwalten von Agreements. Der Service Layer repräsentiert
den Service innerhalb der Architektur. Innerhalb der Architektur von WS-Agreement unterscheidet man zwischen verschiedenen Teilnehmer-Rollen. Neben dem Service Consumer und Service Provider existiert der Initiator. Der Initiator erzeugt und verwaltet in
Bezug auf die Verfügbarkeit eines Services die Agreements eines Services. Dabei ist die
Rolle des Initiators nicht auf den Service Provider oder den Service Consumer festgelegt. Grundlage der Kommunikation sind unterschiedliche XML-Dokumente, die zwischen den Teilnehmern ausgetauscht werden:
• Agreement
Ein Agreement beschreibt die Beziehungen zwischen Teilnehmern. Gegenstand des
Agreements ist die Nutzung eines Services auf Basis der im Agreement getroffenen
Vereinbarungen. Das Agreement beinhaltet Eigenschaften zur Identifikation und
Nutzung eines Services, sowie nicht-funktionale Eigenschaften eines Services, wie
Performanz oder Verfügbarkeit.
• Template (Agreement Template)
Das Agreement Template ist in der Struktur weitestgehend identisch zum Agreement, enthält aber zusätzlich Informationen zur Erzeugung eines Agreements und
bietet meist mehrere Alternativen an.
• Offer (Agreement Offer)
Ein Agreement Offer enthält Bedingungen, zu denen ein Initiator bereit ist, ein
Agreement einzugehen.
Der Agreement Creation Process beschreibt den Prozess zum Erzeugen eines Agreements
und ist in Abbildung 2.1 dargestellt. Die Kommunikation zwischen den Teilnehmern erfolgt auf der Basis von Web Services. Ein Initiator (Service Consumer) fordert von einem Service Provider eine Liste von Agreement Templates zu einem Service an. Aus den
Templates wählt der Initiator geeignete Parameter aus und erzeugt ein Offer. Der Initiator
sendet der Offer an den Service Provider, der diesen prüft. Ist der Offer für den Responder
akzeptabel, so erzeugt er ein Agreement. Für den Fall eines inakzeptablen Offers teilt der
Service Provider dem Initiator mit dass der Offer abgelehnt wurde.
7
2.1. Web-Service-Agreement-Protokoll
Kapitel 2. Grundlagen
: ServiceConsumer
: ServiceProvider
1: getTemplates()
2: createOfferFromTemplate()
3: sendOffer()
4: offerIsValid()
alt
[if offer is valid]
5: sendAgreement()
[else]
6: sendCancellation()
Abbildung 2.1: Sequenzdiagramm: Agreement Creation Process
2.1.2.1
Struktur eines Agreements
Ein Agreement besteht aus verschiedenen Elementen, wie sie im Agreement-XMLSchema in Quellcode 2.1 dargestellt sind.
1 <wsag:Agreement AgreementId="xs:string">
2 <wsag:Name>xs:string</wsag:Name> ?
3 <wsag:AgreementContext>wsag:AgreementContextType</wsag:AgreementContext>
4 <wsag:Terms>wsag:TermCompositorType</wsag:Terms>
5 </wsag:Agreement>
Quellcode 2.1: Agreement-XML-Schema
Der Name des Agreements wird über das Element Name festgelegt. Innerhalb des Elementes AgreementContext werden allgemeine Daten zum Agreement beschrieben.
Die Bedingungen eines Agreements werden mit dem Element Terms ausgedrückt und
in Service Terms und Guarantee Terms unterschieden. Service Terms geben Informationen über einen Service. Guarantee Terms enthalten Zusicherungen von Eigenschaften an
einen Service, der in den Service Terms beschrieben wird.
8
Kapitel 2. Grundlagen
2.1. Web-Service-Agreement-Protokoll
Context
Das Element AgreementContextType, beschrieben in Quellcode 2.2, enthält Informationen zu den Teilnehmern, die Lebensdauer des Agreement und optional eine Referenz auf das Template, aus dem das Agreement hervorgegangen ist.
1 <wsag:Context xs:anyAttribute>
2 <wsag:AgreementInitiator>xs:anyType</wsag:AgreementInitiator> ?
3 <wsag:AgreementResponder>xs:anyType</wsag:AgreementResponder> ?
4 <wsag:ServiceProvider>wsag:AgreementRoleType</wsag:ServiceProvider>
5 <wsag:ExpirationTime>xs:DateTime</wsag:ExpirationTime> ?
6 <wsag:TemplateId>xs:string</wsag:TemplateId> ?
7 <wsag:TemplateName>xs:string</wsag:TemplateName> ?
8 <xs:any/> *
9 </wsag:Context>
Quellcode 2.2: AgreementContextType-XML-Schema
In den Elementen AgreementInitiator und AgreementResponder werden die
Teilnehmer des Agreement Creation Requests, Initiator und Agreement Responder, definiert. Das Element ServiceProvider identifiziert den Service Provider. Der Inhalt des Elementes muss vom Typ AgreementRoleType sein. In Quellcode 2.3 ist
die Definition des Typs AgreementRoleType dargestellt. Zulässige Werte für den
AgreementRoleType sind AgreementInitiator oder AgreementResponder.
Über das Element ExpirationTime wird ein Zeitpunkt festgelegt, ab dem ein Agreement nicht mehr gültig ist. Jedes Template hat eine eindeutige ID und einen Namen. Die
ID wird im Element TemplateID und der Name im Element TemplateName vergeben.
1 <xs:simpleType name="AgreementRoleType">
2 <xs:restriction base="xs:string">
3
<xs:enumeration value="AgreementInitiator"/>
4
<xs:enumeration value="AgreementResponder"/>
5 </xs:restriction>
6 </xs:simpleType>
Quellcode 2.3: AgreementRoleType-XML-Schema
Terms
Bedingungen eines Agreements werden in Form sogenannter Terms ausgedrückt. Ein
Agreement kann dabei aus beliebig vielen Terms bestehen. Bedingungen werden in Service Terms und Guarantee Terms unterschieden. Service Terms stellen Informationen zur
9
2.1. Web-Service-Agreement-Protokoll
Kapitel 2. Grundlagen
Verfügung, die zur Instanziierung oder Identifikation eines Service benötigt werden. Der
Service Term besteht aus:
• Service Description Term
Der Service Description Term (SDT) beschreibt die Funktionalität oder Teile der
Funktionalität eines Services.
• Service Reference
Adressen von Ressourcen werden innerhalb von SOAP als Endpoint Reference
(EPR) bezeichnet. Die Service Reference verweist auf den Service und stellt eine
EPR oder andere Metadaten zur Verfügung, unter der der Service erreicht werden
kann.
• Service Properties
Die Service Properties bieten die Möglichkeit, messbare Eigenschaften wie Antwortzeit oder Durchsatz eines Service zu definieren.
Guarantee Terms beschreiben die Zusicherungen an Dienstgüteeigenschaften, die über
einen Service in den Service Terms getroffen wurden. Quellcode 2.4 zeigt das XMLSchema für das Element TermCompositorType. Mit den logischen Operationen
AND, OR und XOR können TermCompositorTypes miteinander kombiniert werden. Die logischen Operationen werden mit den Elementen All, OneOrMore und
ExactlyOne beschrieben.
1 <wsag:Terms>
2 <wsag:All>
3
{
4
<wsag:All>wsag:TermCompositorType</wsag:All> |
5
<wsag:OneOrMore>wsag:TermCompositorType</wsag:OneOrMore> |
6
<wsag:ExactlyOne>wsag:TermCompositorType</wsag:ExactlyOne> |
7
<wsag:ServiceDescriptionTerm>wsag:ServiceDescriptionTermType</
wsag:ServiceDescriptionTerm> |
8
<wsag:ServiceReference>wsag:ServiceReferenceType</wsag:ServiceReference> |
9
<wsag:ServiceProperties>wsag:ServicePropertiesType</wsag:ServiceProperties> |
10
<wsag:GuaranteeTerm>wsag:GuaranteeTermType</wsag:GuaranteeTerm>
11
} +
12 </wsag:All>
13 </wsag:Terms>
Quellcode 2.4: TermCompositorType-XML-Schema
10
Kapitel 2. Grundlagen
2.1. Web-Service-Agreement-Protokoll
Service Terms
Jeder Service Term verfügt über die Attribute Name und ServiceName. Mit dem Attribut Name wird ein Name für den Term vergeben. Das Attribut ServiceName referenziert den zugehörigen Service.
Das XML-Schema für ein ServiceDescriptionTermType wird in Quellcode 2.5
beschrieben. Über das Element any kann eine zusätzliche Beschreibung für den Service
hinterlegt werden. Die Art der Beschreibung ist unabhängig von WS-Agreement und kann
damit in einer anderen, anwendungsspezifischen Sprache beschrieben werden.
1 <wsag:ServiceDescriptionTerm wsag:Name="xs:string" wsag:ServiceName="xs:string">
2 <xs:any>...</xs:any>
3 </wsag:ServiceDescriptionTerm>
Quellcode 2.5: ServiceDescriptionTermType-XML-Schema
In Quellcode 2.6 ist das XML-Schema für das Element ServiceReferenceTermType
aufgeführt. Das Element any referenziert auf den Service. Die Darstellung ist abhängig
von der Anwendung. Beispielsweise kann im Falle einer Webservice-Anwendung eine
EPR im any-Element abgelegt werden.
1 <wsag:ServiceReference wsag:Name="xs:string" wsag:ServiceName="xs:string">
2 <xs:any>...</xs:any>
3 </wsag:ServiceReference>
Quellcode 2.6: ServiceReferenceTermType-XML-Schema
Die Dienstgüteeigenschaften eines Service werden in den Service Properties definiert.
Dienstgüteeigenschaften werden genutzt, um Service Level Objectives auszudrücken.
Quellcode 2.7 gibt einen Überblick über das Element ServicePropertiesType.
Innerhalb eines ServiceProperty-Elementes werden Dienstgüteeigenschaften in
einem VariableSet-Element abgelegt. Ein VariableSet besteht aus mehreren
Variable-Elementen, wie sie in Quellcode 2.8 dargestellt sind. Das Attribut Name
eines Variable-Elementes vergibt einen Namen für die Eigenschaft. Das Element
Metric definiert eine messbare Einheit für die Dienstgüte-Eigenschaft.
1 <wsag:ServiceProperties wsag:Name="xs:string" wsag:ServiceName="xs:string">
2 <wsag:VariableSet>wsag:VariableSetType</wsag:VariableSet>
3 </wsag:ServiceProperties>
Quellcode 2.7: ServicePropertiesType-XML-Schema
11
2.1. Web-Service-Agreement-Protokoll
Kapitel 2. Grundlagen
Mit dem Element Location wird eine strukturelle Referenz auf Eigenschaften eines
Service gesetzt. XPath [BBC+ 07b] ist eine Abfragesprache, mit deren Hilfe es möglich
ist, Teile eines XML-Dokumentes zu adressieren. Neben einem einfachen Pfadnamen,
wie beispielsweise einem Netzwerkpfad, kann zwischen dem Location-Element ein
XPath-Ausdruck stehen, der sich auf ein Element des Templates bezieht. Eine Menge von
Variable-Elementen kann mit dem Element Variables gruppiert werden.
1 <wsag:Variable wsag:Name="xs:string" wsag:Metric="xs:URI">
2 <wsag:Location>xs:anyType</wsag:Location>
3 </wsag:Variable>
Quellcode 2.8: Variable-XML-Schema
Guarantee Terms
Die Guarantee Terms definieren die Zusicherungen an einen Service, der in den Service Terms beschrieben wurde. Quellcode 2.9 zeigt das GuaranteeTermType-XMLSchema. Ein GuaranteeTerm besitzt die Attribute Name und Obligated. Das
Attribut Name legt den Namen des Guarantee Term fest. Ein Guarantee Term kann
von verschiedenen Teilnehmern eingefordert werden. Das Attribut Obligated legt
fest, von welchem Teilnehmer, Service Provider oder Service Consumer, der Guarantee Term eingefordert wird. Ein GuaranteeTerm beinhaltet verschiedene XMLElemente. Zu den Elementen gehören ServiceScope, QualifyingConditions,
ServiceLevelObjectives und BusinessValues. Der ServiceScope enthält eine Liste von Services, auf die die Zusicherungen zutreffen. Die QualifyingConditions ermöglichen es, Rahmenbedingungen für ein ServiceLevelObjective zu setzen, wie einen Zeitpunkt, an dem ein ServiceLevelObjective zutreffen muss. Das ServiceLevelObjective besteht aus Zusicherungen von Eigenschaften aus den Service Terms.
1 <wsag:GuaranteeTerm Name="xs:string" Obligated="wsag:ServiceRoleType">
2 <wsag:ServiceScope ServiceName="xs:string">xs:any</wsag:ServiceScope> *
3 <wsag:QualifyingCondition>...</wsag:QualifyingCondition> ?
4 <wsag:ServiceLevelObjective>...</wsag:ServiceLevelObjective>
5 <wsag:BusinessValueList>...</wsag:BusinessValueList>
6 </wsag:GuaranteeTerm>
Quellcode 2.9: GuaranteeTermType-XML-Schema
12
Kapitel 2. Grundlagen
2.1. Web-Service-Agreement-Protokoll
Ein ServiceLevelObjective besteht nach dem Schema in Quellcode 2.10 aus
einem KeyPerformanceIndicator (KPI) oder einem CustomServiceLevel.
Der KPI definiert ein SLO in Form eines Zielwertes. Dienstgüteeigenschaften wie Durchsatz oder Verfügbarkeit sind geeignete Zielwerte. In der aktuellen Spezifikation von
WS-Agreement wird der KPI außer durch ein einfaches XML-Schema, das nur aus
den Elementen Name und Target besteht, nicht näher spezifiziert. Der Inhalt des
CustomServiceLevel ist frei gestaltbar und erlaubt es, ein eigenes XML-Schema
für SLOs zu definieren. Ein SLO besitzt ein oder mehrere Business Values.
1 <wsag:ServiceLevelObjective>
2 <wsag:KPITarget></wsag:KPITarget> |
3 <wsag:CustomServiceLevel>...</wsag:CustomServiceLevel>
4 </wsag:ServiceLevelObjective>
Quellcode 2.10: ServicelLevelObjective-XML-Schema
Ein Business Value repräsentiert einen Wert für ein SLO oder den Teil eines SLO. Quellcode 2.11 zeigt das Business-Value-List-XML-Schema. Zu den Elementen einer Business
Value List gehören die Elemente Importance, Penalty, Reward, Preference
und CustomBusinessValue. In vielen Fällen werden die SLOs eines Services nicht
gleich wichtig sein. Daher definiert das Element Importance eine relative Wichtigkeit zu einem SLO. Der Service Provider kann auf der Grundlage des ImportanceElementes Kompromisse zwischen verschiedenen Zusicherungen treffen. Die Wichtigkeit wird der Einfachheit halber in Form eines Integer-Wertes ausgedrückt. Die Elemente Reward und Penalty erlauben es, Belohnungen und Strafen für das Erfüllen oder
Nichterfüllen von Service Level Objectives zu definieren.
1 <wsag:BusinessValueList>
2 <wsag:Importance>xs:integer</wsag:Importance> ?
3 <wsag:Penalty></wsag:Penalty> *
4 <wsag:Reward></wsag:Reward> *
5 <wsag:Preference></wsag:Preference> ?
6 <wsag:CustomBusinessValue>...</wsag:CustomBusinessValue> *
7 </wsag:BusinessValueList>
Quellcode 2.11: Business-Value-List-XML-Schema
Das XML-Schema für das Reward-Element wird in der aktuellen WS-AgreementSpezifikation nicht näher beschrieben. In Quellcode 2.12 ist das XML-Schema für
das Penalty-Element aufgeführt. Das Penalty-Element beinhaltet die Elemente
AssesmentInterval, ValueUnit und ValueExpr.
13
2.1. Web-Service-Agreement-Protokoll
Kapitel 2. Grundlagen
1 <wsag:Penalty>
2 <wsag:AssesmentInterval>
3
<wsag:TimeInterval>xs:duration</wsag:TimeInterval> |
4
<wsag:Count>xs:positiveInteger</wsag:Count>
5 </wsag:AssesmentInterval>
6 <wsag:ValueUnit>xs:string</wsag:ValueUnit> ?
7 <wsag:ValueExpr>xs:any</wsag:ValueExpr>
8 </wsag:Penalty>
Quellcode 2.12: Penalty-XML-Schema
Über das Element AssesmentInterval wird der Zeitrahmen festgelegt, in dem eine Strafe angewendet wird. Kindelemente des AssesmentInterval sind die Element TimeInterval und Count. Der Zeitrahmen der Strafe wird über das Element
TimeInterval in Form von zeitlichen Einheiten wie Tage, Wochen oder Monate festgelegt. Alternativ lässt sich der Zeitrahmen mit dem Element count abhängig von der
Anwendung in Form der Anzahl der Service-Aufrufe beschreiben. Die Einheit der Strafe
wird im Element ValueUnit definiert. Das Element ValueExpr bestimmt den Wert
der Strafe.
Mit dem Preference-Element kann eine Liste von feingranularen Business Values für
verschiedene Wahlmöglichkeiten definiert werden. Jedes Preference-Element muss
einem SDT zugeordnet werden. In Quellcode 2.13 ist das Preference-XML-Schema
dargestellt. Die Elemente ServiceTermReference und Utility sind Kindelemente des Preference-Elementes. Beide Elemente können beliebig oft in einem
Preference-Element erscheinen. Die ServiceTermReference referenziert einen
Service Term. Das Utility-Element definiert den Nutzen, der beim Erreichen des zugehörigen SLOs entsteht.
1 <wsag:Preference>
2 <wsag:ServiceTermReference>xs:string</wsag:ServiceTermReference> *
3 <wsag:Utility>xs:float</wsag:Utility> *
4 </wsag:Preference>
Quellcode 2.13: Preference-XML-Schema
Im CustomBusinessValue-Element können anwendungsspezifische Business Values definiert werden. Die aktuelle WS-Agreement-Spezifikation macht keine näheren
Angaben zum Inhalt und Aufbau des CustomBusinessValue-Elementes.
14
Kapitel 2. Grundlagen
2.1.2.2
2.1. Web-Service-Agreement-Protokoll
Struktur eines Agreement Templates
Das Template entspricht in der Struktur dem Agreement. Zusätzlich zum Agreement
beinhaltet das Template sogenannte Creation Constraints. Der Agreement Offer entspricht in der Struktur dem Agreement Template. Basierend auf einem Template erzeugt ein Initiator ein Offer. Der Offer orientiert sich an dem Template und nutzt die
Auswahlmöglichkeiten der Terms und Creation Constraints. In Quellcode 2.14 ist das
XML-Schema für ein Template dargestellt. Ein Creation Constraint definiert optionale
Einschränkungen für die Erzeugung eines Agreements. Das CreationConstraintElement besitzt zwei Kindelemente, Item und Constraint. Das Item-Element spezifiziert den Teil eines Agreements, der in einem Agreement Offer vorhanden sein muss.
Zusätzlich werden darin die zulässigen Werte für diesen Teil definiert. Allgemeine Einschränkungen, die sich nicht auf Element eines Agreements beziehen, werden über das
Element Constraint gesetzt. Die Spezifikation von WS-Agreement lässt offen, in welcher Form eine Einschränkung innerhalb eines Constraint-Elementes beschrieben
werden muss.
1 <wsag:Template TemplateId="xs:string">
2 <wsag:Name>xs:string</wsag:Name> ?
3 <wsag:AgreementContext>wsag:AgreementContextType</wsag:AgreementContext>
4 <wsag:Terms>wsag:TermCompositorType</wsag:Terms>
5 <wsag:CreationConstraints>
6
<wsag:Item>...</wsag:Item> *
7
<wsag:Constraint>...</wsag:Constraint> *
8 </wsag:CreationConstraints> ?
Quellcode 2.14: Template-XML-Schema
In Quellcode 2.15 ist das XML-Schema für ein Item zu sehen. Der Name, der über das
Attribut Name vergeben wird, muss eindeutig sein. Das Element Location definiert
eine strukturelle Referenz, wie sie bereits beschrieben wurde. Die Einschränkungen für
ein Item werden im Kindelement ItemConstraint gesetzt. Ein ItemConstraint
besteht aus den Elementen restriction, group, all, choice und sequence.
Im Element restriction wird mit dem im XML-Namensraum definierten simpleRestrictionModel-Typ eine Einschränkung definiert. Die Elemente group, all,
choice, sequence und any ermöglichen es, auf ein Element des entsprechenden oder
eines verwandten XML-Types einzuschränken.
1 <wsag:Item Name="xs:string">
2 <wsag:Location>xs:anyType</wsag:Location>
15
2.1. Web-Service-Agreement-Protokoll
Kapitel 2. Grundlagen
3 <wsag:ItemConstraint>
4
<xs:restriction>xs:simpleRestrictionModel<xs:restriction> ?
5
<xs:group>xs:groupRef</xs:group> ?
6
<xs:all>xs:all</xs:all> ?
7
<xs:choice>xs:explicitGroup</xs:choice> ?
8
<xs:sequence>xs:explicitGroup</xs:sequence>?
9 </wsag:ItemConstraint>
10 <xs:any>any#other</xs:any> *
11 </wsag:Item>
Quellcode 2.15: Item-XML-Schema
2.1.2.3
Agreement-Zustände
Agreements und Terms haben zur Laufzeit unterschiedliche Zustände, die überwacht werden können. Ziel ist es, die Einhaltung eines Agreements sicherzustellen. In Abbildung
2.2 sind die möglichen Zustände für ein Agreement aus der Sicht eines Initiators dargestellt. Der Zustand Pending signalisiert, dass ein Agreement Offer gestellt aber weder
Offer Received
Rejected
Pending
Observed
Terminated
Completed
Abbildung 2.2: Agreement Zustände aus Sicht des Initiators
akzeptiert noch abgelehnt wurde. Wurde ein Agreement Offer gestellt und akzeptiert,
so befindet sich das erzeugte Agreement im Zustand Observed. Ein Agreement Offer,
der im Zustand Pending akzeptiert wurde, geht ebenfalls in den Zustand Observed
über. Wird ein Agreement Offer im Zustand Pending vom System abgelehnt, so ist der
Folgezustand Rejected. Der Zustand Rejected geht direkt über in den Endzustand.
16
Kapitel 2. Grundlagen
2.1. Web-Service-Agreement-Protokoll
Zieht der Agreement Initiator sein Agreement Offer zurück oder leitet eine Terminierungsoperation ein, während im Zustand Pending der Agreement Offer noch geprüft
wird, so geht der Offer in den Zustand Terminated über. Der Zustand Terminated
führt in den Endzustand. Leitet der Agreement Initiator eine Termination-Operation ein,
während das Agreement im Zustand Observed ist, so geht das Agreement vom Zustand Observed in Terminated über. Der Zustand Completed signalisiert, dass ein
Agreement Offer angenommen und genehmigt wurde und alle Aktivitäten, die mit dem
Agreement verbunden sind, erledigt wurden.
2.1.3
Quality-of-Service-Erweiterung
Im Labor für Verteilte Systeme der Fachhochschule Wiesbaden wurde eine Erweiterung
entwickelt, die ein XML-Schema für das ServiceLevelObjective-Element CustomServiceLevel implementiert. Die Erweiterung wurde in WSAG4J, einer WSAgreement-Implementierung des Fraunhofer Institiuts, integriert. Mit dem XML-Schema
ist es nun möglich, Quality-of-Service-Bedingungen als Service Level Objective zu setzen. Quellcode 2.16 stellt das XML-Schema vor. Das XML-Schema erlaubt es, mit
den logischen Operatoren AND und OR die Parameter throughput (Durchsatz) und
responseTime (Antwortzeit) zu setzen und Alternativen auszudrücken. Das Schema
ist um zusätzliche Parameter erweiterbar. In Zeile 3 wird ein abstraktes Element mit dem
Namen qosElement definiert. Alle weiteren Elemente in dem XML-Schema sind Erweiterungen dieses Elementes. Das Element and besteht aus zwei Kindelementen, die
vom abstrakten Typ qosElement sein können (Zeile 7 bis 9). Zeile 13 bis 21 beschreibt das Element or, welches wie das and-Element aus zwei Kindelementen vom
Typ qosElement besteht (Zeile 16 bis 18). Mit dem Element responseTime in Zeile
22 wird die Antwortzeit als qosElement beschrieben. Das Element besitzt die Attribute unit, variable und max. Das Attribut unit definiert die Einheit, in der ein Wert
im Attribut max angegeben wird. Mit dem Attribut variable wird eine Variable in den
Terms referenziert. Das Element throughput wird in Zeile 31 bis 41 definiert und enthält wie die responseTime die Attribute unit, variable und max. Zusätzlich hat
das Element noch ein weiteres Attribut mit dem Namen min, welches erlaubt, eine untere
Schranke für einen Durchsatz zu definieren.
1 <?xml version="1.0" encoding="UTF-8"?>
2 <xs:schema targetNamespace="http://vs.cs.fh-wiesbaden.de/agreement/" xmlns:xs="http://
www.w3.org/2001/XMLSchema" xmlns:qos="http://vs.cs.fh-wiesbaden.de/agreement/"
elementFormDefault="qualified" attributeFormDefault="unqualified">
17
2.1. Web-Service-Agreement-Protokoll
Kapitel 2. Grundlagen
3 <xs:complexType name="qosElement" abstract="true"/>
4 <xs:complexType name="and">
5
<xs:complexContent>
6
<xs:extension base="qos:qosElement">
7
<xs:sequence minOccurs="2" maxOccurs="2">
8
<xs:element name="qosElement" type="qos:qosElement"/>
9
</xs:sequence>
10
</xs:extension>
11
</xs:complexContent>
12 </xs:complexType>
13 <xs:complexType name="or">
14
<xs:complexContent>
15
<xs:extension base="qos:qosElement">
16
<xs:sequence minOccurs="2" maxOccurs="2">
17
<xs:element name="qosElement" type="qos:qosElement"/>
18
</xs:sequence>
19
</xs:extension>
20
</xs:complexContent>
21 </xs:complexType>
22 <xs:complexType name="responseTime">
23
<xs:complexContent>
24
<xs:extension base="qos:qosElement">
25
<xs:attribute name="unit" type="xs:string" use="required"/>
26
<xs:attribute name="variable" type="xs:string" use="required"/>
27
<xs:attribute name="max" type="xs:float" use="optional" default="0"/>
28
</xs:extension>
29
</xs:complexContent>
30 </xs:complexType>
31 <xs:complexType name="throughput">
32
<xs:complexContent>
33
<xs:extension base="qos:qosElement">
34
<xs:attribute name="unit" type="xs:string" use="required"/>
35
<xs:attribute name="variable" type="xs:string" use="required"/>
36
<xs:attribute name="min" use="optional"/>
37
<xs:attribute name="max" use="optional" default="0"/>
38
</xs:extension>
39
</xs:complexContent>
40 </xs:complexType>
41 <xs:element name="qos" type="qos:qosElement"/>
42 </xs:schema>
Quellcode 2.16: QoS-XML-Schema
2.1.4
Beispiel
Als Grundlage für das Beispiel wird ein Taschenrechner-Webservice (Calculator Webservice) gewählt. Hierbei will ein Initiator ein SLA über den Taschenrechner-Webservice
abschließen. In Quellcode 2.17 ist das vollständige Agreement Template zu sehen. Das
Agreement Template ist in einem SOAP Envelope eingebettet (Zeile 1). Der SOAP Header definiert in Zeile 2 bis 10 den Sender und Empfänger der Nachricht, die Message ID
18
Kapitel 2. Grundlagen
2.1. Web-Service-Agreement-Protokoll
und die Operation, die ausgeführt wird. Im Body des SOAP Envelopes befindet sich das
eigentliche Agreement-Template-Dokument (Zeile 11 bis 47). Der Name des Templates
ist qosTemplate und der des Agreements calculatorAgreement (Zeile 13). In
Zeile 14 ist zu sehen, dass das Context-Element leer ist. Die Service Description Terms
(Zeile 17) beschreiben den Service. Der Name des Service ist calculatorService.
In den Service Properties werden die Service Level Objectives definiert (Zeile 18). Für
den Taschenrechner-Webservice sind die SLOs throughput und responseTime
verfügbar (Zeile 20 und 21). Die SLOs müssen im Variable Set gesetzt werden, damit im
CustomServiceLevel-Element darauf referenziert werden kann. Der Service Provider bietet für den Taschenrechner-Webservice einen Durchsatz von mindestens 100 und
maximal 150 Requests per Minute (Anfragen pro Minute) (Zeile 28) oder eine maximale
Antwortzeit von 100 Milisekunden (Zeile 29). Die Oder-Verknüpfung wird über das or
Element in Zeile 27 realisiert.
1 <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://www.w3.org/2005/08/addressing/anonymous</wsa:To>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/none</wsa:Address>
</wsa:ReplyTo>
<wsa:MessageID>urn:uuid:9981F5FE2453F04D7A12149997859152</wsa:MessageID>
<wsa:Action>http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/
GetResourcePropertyRequest</wsa:Action>
<wsa:RelatesTo wsa:RelationshipType="http://www.w3.org/2005/08/addressing/reply">
uuid:6abcbec1-1ccd-1854-b065-36bb8564ffc2</wsa:RelatesTo>
</soapenv:Header>
<soapenv:Body>
<wsrf-rp:GetResourcePropertyResponse xmlns:tns="http://handler.server.wsag.graap.ogf
.org" xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
<wsag:Template wsag:AgreementId="calculatorAgreement" wsag:TemplateId="qosTemplate
" xmlns:wsag="http://schemas.ggf.org/graap/2007/03/ws-agreement">
<Context xmlns="http://schemas.ggf.org/graap/2007/03/ws-agreement"/>
<Terms xmlns="http://schemas.ggf.org/graap/2007/03/ws-agreement">
<All>
<ServiceDescriptionTerm NS1:ServiceName="calculatorService" xmlns:NS1="http:
//schemas.ggf.org/graap/2007/03/ws-agreement"></ServiceDescriptionTerm>
<ServiceProperties>
<VariableSet>
<Variable NS1:Metric="rpm" NS1:Name="throughput" xmlns:NS1="http://
schemas.ggf.org/graap/2007/03/ws-agreement"/>
<Variable NS1:Metric="ms" NS1:Name="responseTime" xmlns:NS1="http://
schemas.ggf.org/graap/2007/03/ws-agreement"/>
</VariableSet>
</ServiceProperties>
<GuaranteeTerm NS1:Name="termName" xmlns:NS1="http://schemas.ggf.org/graap
/2007/03/ws-agreement">
19
2.2. Service Component Architecture
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Kapitel 2. Grundlagen
<ServiceLevelObjective>
<CustomServiceLevel>
<qos xmlns="http://vs.cs.fh-wiesbaden.de/agreement/" xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance" xsi:type="or">
<qosElement max="150" min="100" unit="rpm" variable="throughput"
xsi:type="throughput"/>
<qosElement max="100.0" unit="ms" variable="responseTime" xsi:type
="responseTime"/>
</qos>
</CustomServiceLevel>
</ServiceLevelObjective>
</GuaranteeTerm>
</All>
</Terms>
<Terms xmlns="http://schemas.ggf.org/graap/2007/03/ws-agreement">
<All>
<ServiceReference>
<Location>http://sample.org:8080/calculatorService</Location>
</ServiceReference>
</All>
</Terms>
<CreationConstraints xmlns="http://schemas.ggf.org/graap/2007/03/ws-agreement"/>
<CreationConstraints xmlns="http://schemas.ggf.org/graap/2007/03/ws-agreement"/>
</wsag:Template>
</wsrf-rp:GetResourcePropertyResponse>
</soapenv:Body>
</soapenv:Envelope>
Quellcode 2.17: Webservice-Agreement-Beispiel
2.2
2.2.1
Service Component Architecture
Einleitung
Die Service Component Architecture (SCA) beschreibt ein Modell zum Entwurf von Anwendungen, basierend auf Konzepten von Service-Oriented Architectures (SOA). Grundlegende Idee der Service Component Architecture ist die Trennung von Implementierung
und Zusammenfügung (Assembly) der einzelnen Komponenten. Anforderungen an eine
Geschäftsanwendung werden durch das Zusammensetzen verschiedener Services erfüllt.
Eine solche Anwendung wird auch als Composite Application bezeichnet.
Neben der Nutzung neuer Funktionalität ist es möglich, bereits bestehende Funktionalität aus anderen Composite Applications wiederzuverwenden. Verwandte Formate sind
Java Business Integration (JBI) von Sun Microsystems und das Windows Communication
Foundation (WCF) Framework der Firma Microsoft. Die Organization for the Advance-
20
Kapitel 2. Grundlagen
2.2. Service Component Architecture
ment of Structured Information Standards (OASIS)1 , welche die Spezifikationen veröffentlicht, arbeitet zur Zeit mit den beteiligten Mitgliedern an einer Standardisierung der
Service Component Architecture.
2.2.2
Architektur
Das Assembly Model [BBB+ 07] der SCA beschreibt zwei verschiedene Modelle. Das
erste Modell definiert das Zusammenfügen von eng und lose gekoppelten Diensten. Das
zweite Modell beschreibt, wie Dienste um sicherheitsrelevante Funktionen, wie Authentifizierung und Transaktionen, erweitert werden.
Die Struktur einer SCA-Anwendung wird in einer XML-Datei, der composite-Datei,
festgelegt. Eine SCA-Anwendung kann dabei aus mehreren composites bestehen. Das
Assembly Model beinhaltet eine Reihe von Artefakten (Artifacts), die den Aufbau einer
SCA-Anwendung in Form von composites beschreiben. Im Folgenden werden die
verschiedene Artefakte kurz vorgestellt:
• policy
Regeln werden innerhalb der SCA über das policy-Element realisiert.
• implementation
Das implementation-Element legt fest, in welcher Technologie die Geschäftsfunktionalität einer Anwendung implementiert wird.
• interface
Das interface-Element definiert die Geschäftsfunktionalität einer Anwendung.
• property
Das property-Element ermöglicht es, extern konfigurierbare Eigenschaften einer
implementation zu definieren.
• component
Eine component ist die konfigurierte Instanz einer implementation. Die
component bietet und nutzt services.
• service
Das service-Element beschreibt die extern verfügbaren Schnittstellen einer Anwendung.
1
Homepage der OASIS Arbeitsgemeinschaft: http://www.oasis-open.org/
21
2.2. Service Component Architecture
Kapitel 2. Grundlagen
• reference
Abhängigkeiten einer implementation werden über ein reference-Element
realisiert.
• binding
Um den Zugriffsmechanismus eines service- oder reference-Elementes zu
beschreiben wird das binding-Element verwendet.
• wire
Mit Hilfe des wire-Elements werden service- und reference-Elemente miteinander verknüpft. Mit Hilfe der Verknüpfung können service- und reference-Elemente miteinander kommunizieren.
• composite
Eine composite gruppiert die aufgeführten Elemente logisch in einer XMLDatei.
Die aufgeführten Elemente sollen im folgenden näher erläutert werden und einen Überblick über den Aufbau einer SCA-Anwendung vermitteln. Anhand eines Beispiels wird
darauffolgend der Zusammenhang zwischen den Elementen verdeutlicht.
SCA Domain
Eine SCA Domain repräsentiert einen Menge von Services, die zusammen eine Geschäftsfunktionalität zur Verfügung stellen. Spezifiziert wird in einer SCA Domain die
Instanziierung, Konfiguration und Verknüpfung einer Menge von components, verteilt
auf eine oder mehrere composite-Dateien. Eine SCA Domain besteht damit aus einer Reihe von services, references, wires und components.
Policies
Policies erlauben es, Regeln für bestimmte Elemente einer SCA-Anwendung zu definieren. Elemente, auf die Policies anwendbar sind, verfügen über die Attribute require
und policySet. Das Attribut require beschreibt die Regel, die angewendet wird,
während policySet eine Liste von Regeln repräsentiert. Die Regeln werden üblicherweise in einer bekannten Form, wie zum Beispiel WS-Policy Assertions, ausgedrückt.
Policies werden im SCA Policy Framework [BBC+ 07a] beschrieben.
22
Kapitel 2. Grundlagen
2.2. Service Component Architecture
Properties
Ein property-Element repräsentiert eine extern konfigurierbare Eigenschaft einer
implementation. Eine implementation besitzt keine, eine oder mehrere property-Elemente. In Quellcode 2.18 ist das XML-Schema für ein property-Element
abgebildet. Jedes property-Element besitzt ein Attribut name, type oder element,
many und mustSupply. Über das Attribut name wird ein Name für die property
vergeben. Eine property hat einen Datentyp, der ein XML-Schema-Typ (type) oder
einem XML-Element (element) entspricht. Mit dem Attribut many wird festgelegt, ob
die property nur aus einem einzelnen Wert oder aus einer Vielzahl von Werten besteht. Über das Attribut mustSupply wird festgelegt, ob die property implementiert
werden muss.
1 <property name="xs:NCName" (type="xs:QName" | element="xs:QName")
2 many="xs:boolean"? mustSupply="xs:boolean"?>*
3 default-property-value?
4 </property>
Quellcode 2.18: Property-XML-Schema
Implementation
Eine implementation stellt die Geschäftsfunktionalität eines Service innerhalb einer
service-orientierten Anwendung zur Verfügung. Unterstützt wird eine Vielzahl von verschiedenen Sprachen und Frameworks wie Java, C++, XSLT, BPEL oder Spring. Eine
implementation wird durch ein implementation-Element beschrieben, wie es
in Quellcode 2.19 dargestellt ist. Um zwischen unterschiedlichen implementationTypen zu unterscheiden, wird das XML-Element um den Namen des Typs erweitert, zum
Beispiel implementation.java oder implementation.bpel.
1 <implementation requires="list of xs:QName"? policySets="list of xs:QName"?/>?*
Quellcode 2.19: Implementation-XML-Schema
Als konfigurierbare Bestandteile einer implementation werden services, references und properties in der SCA zum component-Typ zusammengefasst. In
Abbildung 2.3 ist die Beziehung zwischen dem component-Typ, component und
implementation dargestellt. Die properties und references einer Implementierung werden in der component, die eine entsprechende implementation
23
2.2. Service Component Architecture
Kapitel 2. Grundlagen
nutzt, konfiguriert. Der component-Typ wird durch Analyse der implementation
Abbildung 2.3: Beziehung von Component und Implementation (nach [BBB+ 07])
oder durch eine componentType-Datei bestimmt. Bei der Analyse wird der vorhandene Quelltext der Implementierung nach Annotationen durchsucht. Annotation entsprechen Anmerkungen im Quelltext, vergleichbar mit dem Konzept von Annotations
in Java. Für implementation-Typen, deren Quelltext nicht analysiert werden kann,
weil die Sprache oder das Framework Elemente wie Annotationen nicht kennt, werden entsprechende Informationen in der componentType-Datei, mit der Dateiendung
*.componentType, hinterlegt. Die componentType-Datei besteht dabei aus einem Element componentType. Das componentType-Element, in Quellcode 2.20,
kann service-, reference- oder property-Elemente enthalten. Das Attribut
constrainingType ermöglicht es, Einschränkungen für einen componentType zu
definieren.
1 <componentType xmlns="http://www.osoa.org/xmlns/sca/1.0" constrainingType="QName"?>
2
...
3 </componentType>
Quellcode 2.20: Component-Type-XML-Schema
Ein constrainingType definiert services, references und properties,
die implementiert werden müssen. In Quellcode 2.21 ist das XML-Schema für ein constrainingType dargestellt.
1 <?xml version="1.0" encoding="ASCII"?>
2 <constrainingType xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="xs:anyURI"?
24
Kapitel 2. Grundlagen
2.2. Service Component Architecture
3 name="xs:NCName" requires="list of xs:QName"?>
4 ...
5 </constrainingType>
Quellcode 2.21: ConstrainingType-XML-Schema
Ein constrainingType-Element besteht aus keinem, einem oder mehreren service-, reference- oder properties-Elementen. Das Attribut name definiert
einen Namen für den constrainingType. Der vergebene Name wird im constrainingType-Attribut der component referenziert. Über das Attribut targetNamespace wird auf einen Namensraum für den constrainingType verwiesen.
Binding
Um Zugriffsmechanismen in einer SCA-Anwendung zu beschreiben, wird das bindingElement verwendet. Dabei wird das binding-Element von services und references genutzt. Eine reference nutzt ein binding, um den Zugriffsmechanismus
zu beschreiben, der nötig ist, um den Service aufzurufen, mit dem sie verknüpft ist. Ein
service nutzt das binding, um zu beschreiben, wie ein Client einen Service aufzurufen hat. Ein binding wird durch ein binding-Element definiert, wie es in Quellcode
2.22 abgebildet ist.
1 <binding uri="xs:anyURI"? name="xs:QName"? requires="list of xs:QName"?
2 policySets="list of xs:QName"?/>*
Quellcode 2.22: Binding-XML-Schema
Für eine reference definiert das Attribut uri die Ziel-URI der reference. Im Fall
eines service beschreibt das Attribut die URI relativ zu einer component, die den
Service innerhalb einer SCA Domain zur Verfügung stellt. Im Attribut name wird optional ein Name für das binding definiert. Die Service Component Architecture unterstützt unterschiedliche bindings wie Webservices oder Enterprise Java Beans (EJBs).
Zusätzlich existiert die Möglichkeit, das SCA Framework um eigene bindings zu erweitern.
Interface
Geschäftsfunktionen werden durch ein interface definiert. Die in einem interface
beschriebene Geschäftsfunktion wird von einem service angeboten und von einer
25
2.2. Service Component Architecture
Kapitel 2. Grundlagen
component durch eine reference genutzt. Ein interface kann bidirektional sein.
Besitzt ein Service Operationen, die an beiden Enden der Service-Kommunikation bereitgestellt werden müssen, so spricht man von einem bidirektionalen Service. Ein Beispiel
für einen bidirektionalen Service wäre ein Service, der von einem Client ein Callback
Interface erwartet, das bei verschiedenen Service Requests aufgerufen wird.
1 <interface.java interface="NCName" ... />
Quellcode 2.23: Interface-Java-XML-Schema
Ein interface besteht aus ein oder mehreren Operationen, wobei jede Operation keine, eine oder mehrere Request Messages und Response Messages besitzt. In Quellcode 2.23 ist das XML-Schema für das Java-interface dargestellt. Im Fall eines Javainterface wird für das Attribut interface die Implementierung in Form einer JavaDatei im Attribut angegeben. Zur Zeit unterstützt die SCA neben Java, WSDL 1.1 portTypes und WSDL 2.0 Interfaces. Der Bezeichner java würde im Fall eines WSDL portTypes durch wsdl ersetzt werden, also interface.wsdl lauten. Weiterhin existiert
die Möglichkeit, das SCA Framework um eigene interface-Typen zu erweitern.
Service
Ein service beschreibt die extern verfügbaren Service-Schnittstellen einer implementation. Üblicherweise wird ein service durch eine component innerhalb eines
composite oder durch eine reference, definiert durch ein composite, zur Verfügung gestellt. Letztere Variante erlaubt es, einen service mit einer neuen Adresse und
beziehungsweise oder mit einem neuen binding wiederzuverwenden. Jedes serviceElement wird jeweils durch ein interface-Element beschrieben. In Quellcode 2.24
wird das XML-Schema für ein service-Element vorgestellt.
1 <service name="xs:NCName" promote="xs:anyURI" requires="list of xs:QName"?
2 policySets="list of xs:QName"?>*
3 <interface/>?
4 <binding uri="xs:anyURI"? name="xs:QName"? requires="list of xs:QName"
5 policySets="list of xs:QName"?/>*
6 <callback>?
7
<binding uri="xs:anyURI"? name="xs:QName"? requires="list of xs:QName"?
8
policySets="list of xs:QName"?/>+
9 </callback>
10 </service>
Quellcode 2.24: Service-XML-Schema
26
Kapitel 2. Grundlagen
2.2. Service Component Architecture
Das Attribut name vergibt einen Namen für den service. Mit dem Attribut promote
wird der offerierte service benannt, wobei der Wert der Form <component-name>
/<service-name> entsprechen muss. Das interface-Element definiert die Ge-
Service
Abbildung 2.4: SCA Service Symbol (nach [BBB+ 07])
schäftsfunktionalität oder einen Teil der Geschäftsfunktionalität, die durch den service
angeboten wird. Das callback-Element erlaubt es, optional einen Callback für den
service zu definieren, wobei ein callback-Element aus beliebig vielen bindingElementen besteht. Abbildung 2.4 zeigt die graphische Repräsentierung eines service
innerhalb einer SCA-Anwendung.
Wire
Um die Kommunikation zwischen einer reference und einem service zu ermöglichen, existiert in der SCA das Konzept der wire-Elemente. Innerhalb eines composite
wird eine reference mit einem service über ein wire verbunden. Ein wireElement leitet damit Aufrufe von Operationen an die jeweils angebundene andere Komponente weiter. Um ein wire zu erzeugen, existieren die folgenden Möglichkeiten:
• Über die Definition einer Zielkomponente im Attribut target im referenceElement
• Mit dem Autowire-Mechanismus werden reference und service-Elemente
automatisch verknüpft. Der Autowire-Mechanismus durchsucht das composite
nach einem service interface, das mit einem reference interface
übereinstimmt. Autowire muss explizit über das Attribut autowire innerhalb eines composite aktiviert werden.
• Über das Element wire, wie es in Quellcode 2.25 abgebildet ist.
1 <wire source="xs:anyURI" target="xs:anyURI" />*
Quellcode 2.25: Wire-XML-Schema
27
2.2. Service Component Architecture
Kapitel 2. Grundlagen
Das Attribut source definiert die Quellkomponente, target die Zielkomponente.
Reference
Eine reference repräsentiert die Abhängigkeit einer implementation von dem
service einer anderen implementation. Jede reference innerhalb einer SCAAnwendung muss zu mindestens einem service der Anwendung aufgelöst werden.
Eine reference wird durch das XML-Element reference beschrieben, wie es in
Quellcode 2.26 dargestellt ist.
1 <reference name="xs:NCName" target="list of xs:anyURI"? promote="list of xs:anyURI"
2 wiredByImpl="xs:boolean"? multiplicity="0..1 or 1..1 or 0..n or 1..n"?
3 requires="list of xs:QName"? policySets="list of xs:QName"?>*
4 <interface/>?
5 <binding uri="xs:anyURI"? name="xs:QName"? requires="list of xs:QName"
6 policySets="list of xs:QName"?/>*
7 <callback>?
8
<binding uri="xs:anyURI"? name="xs:QName"? requires="list of xs:QName"?
9
policySets="list of xs:QName"?/>+
10 </callback>
11 </reference>
Quellcode 2.26: Reference-XML-Schema
Der Name der Reference wird durch das Attribute name festgelegt. Im Attribut multiplicity wird definiert, mit wievielen wires man die Reference verbinden kann. Das
Attribut promote identifiziert den offerierten Service der reference, wobei der Wert
der Form <component-name>/<reference-name> entsprechen muss. Mit Hilfe
des Attributes wiredByImpl wird optional festgelegt ob eine implementation die
reference dynamisch verknüpft. Ist der Wert des Attributes true, so wird das Ziel
der reference zur Laufzeit durch die Implementierung bstimmt. Eine reference
kann zusätzlich ein Callback mit dem Element callback definieren, wobei eine variable
Anzahl von binding-Elementen innerhalb des Elementes den Zugriff auf den Callback
definiert. Das folgende Bild 2.5 ist die graphische Repräsentierung einer reference
innerhalb einer SCA-Anwendung.
Component
Ein weiteres Element in der SCA ist die component. Alle components innerhalb
eines composite bilden die Geschäftslösung. Eine component nutzt und offeriert
services und repräsentiert eine konfigurierte Instanz einer implementation. Die
28
Kapitel 2. Grundlagen
2.2. Service Component Architecture
Reference
Abbildung 2.5: SCA Reference Symbol (nach [BBB+ 07])
component wird als Element innerhalb einer composite definiert, dabei kann ein
component-Element aus keinem, einem oder mehrere implementation-, reference- oder service-Elementen bestehen. In Quellcode 2.27 ist das XML Schema
für ein component-Element zu sehen.
1 <component name="xs:NCName" autowire="xs:boolean"? requires="list of xs:QName"?
2 policySets="list of xs:QName"? constrainingType="xs:QName"?>*
3 ...
4 </component>
Quellcode 2.27: Component-XML-Schema
Das Attribut name legt den Namen der component fest. Das Attribut autowire definiert, ob references mit zugehörigen services automatisch verbunden werden.
Abbildung 2.6 zeigt die grafische Repräsentation einer component.
Abbildung 2.6: SCA Component Diagramm (nach [BBB+ 07])
29
2.2. Service Component Architecture
Kapitel 2. Grundlagen
Composite
Ein composite gruppiert logisch die Elemente einer SCA-Anwendung und ist die
grundlegendste Einheit im Entwurf einer solchen Anwendung. Es besteht dabei aus
components, services, references und wires, die diese verbinden, und
properties, die es ermöglichen, components zu konfigurieren. Eine composite
kann eine Implementierung einer component sein, was bedeutet, dass höherschichtige
composites components besitzen, die durch andere composites implementiert
werden. Eine composite wird in einer Datei mit der Endung *.composite abgelegt.
Quellcode 2.28 stellt das XML-Schemata einer composite vor.
1 <composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="xs:anyURI"
2 name="xs:NCName" local="xs:boolean"? autowire="xs:boolean"? constrainingType="QName"?
3 requires="list of xs:QName"? policySets="list of xs:QName"?>
4 <include name="xs:QName"/>*
5 ...
6 </composite>
Quellcode 2.28: Composite-XML-Schema
Mit dem Attribut name wird ein Name für das composite festgelegt. Teile einer SCAAnwendung können verteilt auf verschiedenen Nodes laufen. Um dieses Verhalten zu
unterbinden, existiert das Attribut local. Das Attribut constrainingTyp erlaubt es,
Einschränkungen für eine composite zu definieren, wie es bereits im Abschnitt 2.2.2
beschrieben wurde. Zusätzlich ist es möglich, components einer anderen composite
Datei durch das Element include einzubinden.
Contribution
Eine SCA-Anwendung kann von verschiedenen Komponenten abhängig sein. Für eine SCA-Anwendung könnte das ein composite oder eine componentType-Datei,
für einen BPEL-Prozess eine Workflow-Beschreibung sein. Das Assembly Model beschreibt, wie diese XML-Dokumente und andere Komponenten über einen Erweiterungsmechanismus in eine SCA Domain integriert werden können. Erweiterungen, sogenannte
contributions, werden über ein eigenes Paketformat in eine SCA-Anwendung eingebunden. Zusätzlich ist es möglich, Erweiterungen auch über andere Formate wie ein
einfaches Verzeichnis, ein OSGi Bundle oder auch eine JAR-Datei einzubinden. Ein Format für eine Erweiterung sollte mindestens die folgenden Anforderungen erfüllen:
30
Kapitel 2. Grundlagen
2.2. Service Component Architecture
• eine Datei sca-contribution.xml zur Verfügung stellen, die die lauffähigen
composites der Erweiterung enthält,
• ein Verzeichnis in der Wurzel der Hierarchie mit dem Namen META-INF,
• die Komponenten des Paketes müssen für eine SCA-Umgebung hierarchisch abbildbar sein.
Erweiterung der Architektur
Die SCA kann um eigene interface-, implementation- und binding-Typen
erweitert werden. Grundlage des Erweiterungsmodells ist das XML-Schema-Konzept
von substitution groups, wie sie in [FW04] beschrieben werden. Das Konzept der substitution groups erlaubt es, XML-Elemente durch andere XMLElemente zu ersetzen. Für eine substitution group wird ein head-Element
definiert, das ersetzt werden kann. Im SCA-Namensraum werden drei substitution-group-head-Elemente definiert und zwar jeweils für interface-, implementation- und binding-Typen. Die in der SCA definierten Typen für interface,
implementation und binding nutzen wiederum selbst substitution-grouphead-Elemente. In Quellcode 2.29 ist das XML-Schema für ein Interface zu sehen. In
Zeile 8 wird ein abstraktes Element definiert, das vom Typ Interface ist und den Namen interface trägt.
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<!-- (c) Copyright SCA Collaboration 2006 -->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.osoa.org/xmlns/sca/1.0"
xmlns:sca="http://www.osoa.org/xmlns/sca/1.0" elementFormDefault="qualified">
...
<element name="interface" type="sca:Interface" abstract="true"/>
<complexType name="Interface"/>
...
</schema>
Quellcode 2.29: SCA-Interface-XML-Schema
Der Typ wird in Zeile 9 definiert. Im Quellcode 2.30 ist dargestellt, wie das Element
interface.java implementiert wurde. Das Element interface.java in Zeile 5
ersetzt das head-Element sca:interface. Die Definition des Typs sca:JavaInterface
ist in Zeile 7 bis 13 abgebildet. Ein interface.java besteht demnach aus einem Attribut interface, das angegeben werden muss (Zeile 10).
31
2.2. Service Component Architecture
Kapitel 2. Grundlagen
1 <?xml version="1.0" encoding="UTF-8"?>
2 <schema xmlns="http://www.w3.org/2001/XMLSchema"
3 targetNamespace="http://www.osoa.org/xmlns/sca/1.0"
4 xmlns:sca="http://www.osoa.org/xmlns/sca/1.0">
5 <element name="interface.java" type="sca:JavaInterface"
6 substitutionGroup="sca:interface"/>
7 <complexType name="JavaInterface">
8
<complexContent>
9
<extension base="sca:Interface">
10
<attribute name="interface" type="NCName" use="required"/>
11
</extension>
12
</complexContent>
13 </complexType>
14 </schema>
Quellcode 2.30: SCA-Interface-Java-XML-Schema
Die Erweiterung für implementation- und binding-Typen folgt dem gleichen Prinzip. Eigene Erweiterungen für die SCA müssen in einem anderen namespace erfolgen.
Zum gegenwärtigen Zeitpunkt lässt das Assembly Model offen, wie eigene Erweiterungen in eine SCA-Laufzeitumgebung integriert werden.
2.2.3
Beispiel
Als Beispiel für eine SCA-Anwendung wird an dieser Stelle ein TaschenrechnerWebservice vorgestellt. Der Taschenrechner-Webservice entspricht dem im vorherigen
Abschnitt 2.1.4 vorgestellten Service. In Quellcode 2.31 ist das vollständige Composite
für den Taschenrechner zu sehen. In Zeile 4 wird eine Schnittstelle für den Taschenrechner definiert, über die ein Client den Taschenrechner in Form eines Webservice aufrufen kann. In Zeile 9 ist die component CalculatorServiceComponent definiert,
welche die Funktionalität des Taschenrechners zur Verfügung stellt. Die arithmetischen
Grundrechnarten werden als references angegeben und werden damit von anderen
composites implementiert. Das interface in Zeile 5 definiert die Schnittstellen für
den Taschenrechner, während in Zeile 10 die Implementierung für das interface zu
finden ist. Alle arithmetischen Grundrechenarten werden als Webservice implementiert
und aufgerufen, wie es in Zeile 13 am binding.ws-Element zu sehen ist. Das Attribut
uri des binding.ws-Element definiert die aufzurufende URL für den Webservice.
1 <composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="http://sample"
2 xmlns:sample="http://sample" name="Calculator">
3
4 <service name="CalculatorService" promote="CalculatorServiceComponent">
32
Kapitel 2. Grundlagen
2.2. Service Component Architecture
5
<interface.java interface="calculator.CalculatorService" />
6
<binding.ws/>
7 </service>
8
9 <component name="CalculatorServiceComponent">
10
<implementation.java class="calculator.CalculatorServiceImpl"/>
11
<reference name="addService" promote="">
12
<interface.java interface="calculator.AddService" />
13
<binding.ws uri="http://localhost:8080/sample-add-ws-webapp/AddService"/>
14
</reference>
15
<reference name="subtractService" promote="">
16
<interface.java interface="calculator.SubtractService" />
17
<binding.ws uri="http://localhost:8080/sample-sub-ws-webapp/SubtractService"/>
18
</reference>
19
<reference name="multiplyService" promote="">
20
<interface.java interface="calculator.MultiplyService" />
21
<binding.ws uri="http://localhost:8080/sample-mult-ws-webapp/MultiplyService"/>
22
</reference>
23
<reference name="divideService" promote="">
24
<interface.java interface="calculator.DivideService" />
25
<binding.ws uri="http://localhost:8080/sample-div-ws-webapp/DivideService"/>
26
</reference>
27 </component>
28 </composite>
Quellcode 2.31: Calculator Composite
2.2.4
Apache Tuscany SCA
Das Apache-Tuscany-SCA-Projekt, das eine Implementierung der SCA-Spezifikation 1.0
zur Verfügung stellt, soll im vorliegenden Abschnitt vorgestellt werden. Diese Diplomarbeit ist Teil des Projektes Selbstmanagement am Beispiel Service-orientierter Architekturen1 des Labors für Verteilte Systeme der FH Wiesbaden. Teile des Projektes wurden
bereits erfolgreich mit Apache Tuscany SCA realisiert. Darauf aufbauend soll Apache
Tuscany SCA Grundlage der Implementierung dieser Diplomarbeit sein.
Das Apache-Tuscany-SCA-Projekt (Tuscany) unterteilt sich in die Unterprojekte SCA
Java, SCA PHP und SCA Native. SCA Java und SCA PHP stellen Implementierungen
der Spezifikation in Java und PHP zur Verfügung. Das SCA-Native-Projekt ist eine in
C++ implementierte SCA-Umgebung, die es erlaubt, component-Implementierungen
in C++, Ruby und Python zu entwickeln.
Abbildung 2.7 fasst die Komponenten graphisch zusammen und repräsentiert das Architekturmodell von Tuscany. Die SCA-Laufzeitumgebung und -Schnittstellen zur Erwei1
Homepage des Projektes ”Selbstmanagement am Beispiel Service-orientierter Architekturen”:
http://wwwvs.informatik.fh-wiesbaden.de/projekte/selfman.html
33
2.2. Service Component Architecture
Kapitel 2. Grundlagen
terung befinden sich in der Core-Komponente in Tuscany. Die Core-Komponente ist so
aufgebaut, dass sie in einer Vielzahl von verschiedenen Umgebungen lauffähig ist. Beispielsweise ist es möglich, Tuscany in einem Web Container, als Java-Anwendung oder
als Java-EE-Anwendung in einem Applikationsserver zu betreiben. Diese Umgebungen
werden über das Hosting-Platform-Modul bereitgestellt.
Erweiterungen werden über das Extension-Modul in Tuscany eingebunden. Mit Hilfe des Extension-Modul, kann Tuscany um neue Typen wie implementation-,
binding- und interface-Typen erweitert werden. Weitere Erweiterungsmöglichkeiten sind Schnittstellen zum Umgang mit Daten (Data Binding), wie beispielsweise
JAXB. Die in der SCA-Spezifikation definierte API wird über ein seperate Komponente, dem SCA-Spec-API-Modul, zur Verfügung gestellt. Seit Mai 2008 ist das Apache-
Abbildung 2.7: Tuscany-SCA-Java-Architektur (nach [Fou08])
Tuscany-Projekt ein offizielles Projekt der Apache Software Foundation. Erweiterungen
für SCA werden über das Tuscany Contribution Modell (Abbildung 2.8) eingebunden.
Das Contribution Modell integriert Erweiterungen über zwei Erweiterungspunkte (Extension Points). Zum einen der PackageProcessorExtensionPoint und zum anderen der ArtifactProcessorExtensionPoint. Der PackageProcessorExtensionPoint verarbeitet Erweiterungen, die als JAR oder als Datei/Verzeichnis vorliegen. Formate wie WSDL, XSD, Composite, BPEL oder Java-Klassen werden über den ArtifactProcessorExtensionPoint verarbeitet. Der Package
Processor durchsucht die zu installierende Erweiterung und erzeugt eine Liste von
34
Kapitel 2. Grundlagen
2.3. Queueing-Strategien
Abbildung 2.8: Tuscany-SCA-Contribution-Modell (nach [Fou08])
sogenannten artifacts, die verarbeitet werden müssen. Ein eigener PackageProcessor, der Formate wie EAR, WAR oder ZIP unterstützt, muss sich an der
Package Processor Extension registrieren. Über den Artifact Processor werden die artifacts verarbeitet. Eigene Artifact Processors müssen
sich an der Artifact Processor Extension registrieren. Der Artifact Processor wird für jedes artifact in zwei Phasen aufgerufen. In der ersten, lesenden
Phase wird ein Modell erzeugt, dass das artifact repräsentiert. Dabei ruft der SCA
Contribution Service für jeden registrierten Artifact Processor eine entsprechende Methode auf. In der zweiten Phase werden Referenzen auf andere Modells aufgelöst,
eine solche Referenz kann beispielsweise eine WSDL-Datei oder eine andere Klasse sein.
Nach der zweiten Phase sind alle artifacts verarbeitet und bereit für das Deployment
in eine SCA Domain.
2.3
2.3.1
Queueing-Strategien
Einleitung
Um komplexe Vorgänge in realen Systemen untersuchen zu können, werden häufig Modelle benötigt, die eine quantitative und qualitative Beschreibung der Systeme erlauben
35
2.3. Queueing-Strategien
Kapitel 2. Grundlagen
[TG05, Hof00]. Von besonderer Bedeutung ist dabei die Möglichkeit, Systemreaktionen
zu beurteilen. Ein solches Modell wird durch die Bedientheorie bereitgestellt.
Begriffe aus der Bedientheorie erlauben es, Queueing-Strategien (Warteschlangen-Strategien) unabhängig von der konkret implementierten Technologie zu betrachten.
• Auftrag
Ein Auftrag ist eine Einheit zur Bearbeitung.
• Bedienzeit
Die Bedienzeit entspricht der Zeitdauer für die reine Bearbeitung eines Auftrags
durch ein System.
• Antwortzeit/Verweilzeit
Die Antwortzeit beschreibt die Zeitdauer vom Eintreffen eines Auftrags bis zur
Fertigstellung.
• Wartezeit
Die Wartezeit entspricht der Antwortzeit abzüglich der Bedienzeit.
• Durchsatz
Der Druchsatz entspricht der Anzahl der Aufgaben, die von einem System pro Zeiteinheit erledigt wurden.
• Warteraum
Wird ein Auftrag nicht direkt bearbeitet, so verbleibt er in einem Warteraum.
• Quelle
Als Quelle wird das System definiert, das einen Auftrag erteilt.
Abbildung 2.9 stellt die graphische Repräsentation einiger der voher aufgeführten Begriffe vor. Queueing-Strategien sind von zentraler Bedeutung zur Umsetzung von Quality-ofService-Anforderungen [Tan07]. Im Folgenden werden verschiedene Queueing-Strategien
des Linux 2.6 Kernels1 vorgestellt.
2.3.2
Strategien
2.3.2.1
Multi Band Priority Queueing
Der Multi-Band-Priority-Queueing-Algorithmus (MBPQ-Algorithmus) ist eine Erweiterung des Priority-Queuing-Algorithmus (PQ-Algorithmus) [Knu98]. Im MBPQ-Algorith1
Homepage des Linux Kernel Projekts: http://www.kernel.org/pub/linux/kernel/v2.6/
36
Kapitel 2. Grundlagen
Klassifizierung
Auftrag
2.3. Queueing-Strategien
System/Bedienungsstation
Warteraum
Erledigter Auftrag
Ankünfte
Abgänge
Abbildung 2.9: Graphische Repräsentation der Begriffe der Bedientheorie
mus werden Queues mit unterschiedlichen Prioritäten zu Bändern zusammengefasst und
nach einem FIFO-Prinzip abgearbeitet. Jedes Band wird nach einem Round-RobinVerfahren bearbeitet. In Abbildung 2.10 ist der Algorithmus dargestellt. Der MPBQAlgorithmus versucht, Nachteile des PQ-Algorithmus abzuschwächen. Liegen für eine
Queue mit hoher Priorität viele Aufträge vor, so kann das bei einem PQ-Algorithmus
dazu führen, dass Queues mit Aufträgen mit niedriger Priorität nie bearbeitet werden.
Man spricht auch davon, dass Aufträge verhungern (starvation). Durch das Zusammenfassen von Queues zu einem Band wird sichergestellt, dass Aufträge von mehreren unterschiedlichen Quellen berücksichtigt werden, allerdings wird damit nicht sichergestellt,
dass Aufträge aus anderen Bändern nicht verhungern.
Band
Klassifizieren der
Aufträge
Bedienungsstation
...
Abgänge
Ankünfte
Abbildung 2.10: Multi Band Priority Queueing
2.3.2.2
Stochastic Fairness Queueing
Der Fairness-Queueing-Algorithmus (FQ-Algorithmus) sortiert Aufträge einer Quelle in
jeweils eine eigene Queue ein. Die Queues werden nach dem FIFO-Prinzip abgearbeitet.
Aufträge werden nach einem Round-Robin-Verfahren bearbeitet. Pro Queue wird immer
genau ein Auftrag entnommen. Der FQ-Algorithmus versucht damit, jeder Quelle den
gleichen Anteil an der Gesamtbandbreite zuzusichern.
Mit dem FQ-Algorithmus ergibt sich allerdings ein Ungleichgewicht bei unterschiedlich
großen Aufträgen. Große Aufträge, also Aufträge die mehr Bearbeitungszeit in Anspruch
37
2.3. Queueing-Strategien
Kapitel 2. Grundlagen
nehmen, werden vom FQ-Algorithmus indirekt durch eine längere Bearbeitungszeit bevorzugt. Der Stochastic-Fairness-Queueing-Algorithmus (SFQ-Algorithmus) [McK90]
versucht, dieses Ungleichgewicht einzuschränken, indem der Algorithmus Aufträge einer
Quelle in unterschiedliche Queues ablegt. Die Klassifizierung erfolgt dabei durch eine
Hash-Funktion. Parameter der Hash-Funktion sind Eigenschaften von Aufträgen. Durch
den Einsatz der Hash-Funktion ist es möglich, dass mehrere Aufträge einer Quelle in die
gleiche Queue abgelegt werden. Um dies zu vermeiden, ändert sich der Hash-Algorithmus
einer SFQ-Implementierung innerhalb eines Zeitraums mehrmals. Die Queues werden,
wie auch beim FQ-Algorithmus, nach einem Round-Robin-Verfahren abgearbeitet. Abbildung 2.11 zeigt das Prinzip des SFQ-Algorithmus. Eingehende Aufträge werden nach
einer Hash-Funktion klassifiziert und in verschiedene Queues abgelegt. Die unterschiedlichen Aufträge sind mit unterschiedlichen Farben markiert.
Klassifizieren der
Aufträge durch eine
Hash Funktion
Bedienungsstation
Abgänge
Ankünfte
Abbildung 2.11: Stochastic Fairness Queueing
2.3.2.3
Weighted Fair Queuing
Der Weighted-Fair-Queueing-Algorithmus (WFQ-Algorithmus) oder auch WeightedRound-Robin-Algorithmus erweitert den FQ-Algorithmus (vergleiche 2.3.2.2) um Gewichte [DKS89, PG93]. Jeder Auftrag wird anhand seiner Priorität in eine Queue abgelegt. Jede Queue i verfügt über ein Gewicht wi das einem Anteil vom Gesamtgewicht
entspricht. Das Gesamtgewicht entspricht der Bearbeitungsrate. Über das Gewicht wird
damit einer Queue eine entsprechende Bearbeitungszeit zugesichert. In Abbildung 2.12 ist
ein Beispiel für den WFQ-Algorithmus dargestellt. Das Beispiel besteht aus vier Queues. Jede Queue ist ein Gewicht (w1, w2, w3 und w4) zugeordnet. Nimmt man an dass
pro Gewicht ein Auftrag verarbeitet werden kann, so kann die erste Queue vier Aufträge, die zweite drei Aufträge, die dritte zwei Aufträge und die letzte Queue einen Auftrag
bearbeiten, bevor die Queue wieder von vorne anfängt
38
Kapitel 2. Grundlagen
2.3. Queueing-Strategien
w1 = 4
Klassifizieren der
Aufträge nach
Priorität
w2 = 3
Bedienungsstation
w3 = 2
Abgänge
Ankünfte
w4 = 1
Abbildung 2.12: Weighted Fair Queuing
2.3.2.4
Class Based Queueing
Der Class-Based-Queueing-Algorithmus (CBQ-Algorithmus) [FJ95] klassifiziert eingehende Aufträge und legt sie und in einer baumartigen Hierarchie ab. Die Wurzel des Baumes definiert die Gesamtbandbreite. Alle Nachfahren der Wurzel besitzen Anteile an der
Gesamtbearbeitungsrate. Die Summe aller Anteile ist nicht größer als die Gesamtbearbeitungsrate. Über die Anteile wird eine Priorität für Aufträge einer Quelle ausgedrückt.
Nutzt ein Blatt die ihm zugesicherte Bearbeitungsrate nicht, so kann sich ein anderes
Blatt auf der gleichen Ebene Teile der Bearbeitungsrate ausleihen. Benötigt das beliehene
Blatt seine Bearbeitungsrate wieder, so wird die Bearbeitungsrate an das Blatt zurückgegeben. Der Algorithmus sieht vor, dass die Blätter des Baumes von unterschiedlichen
Scheduling-Algorithmen bearbeitet werden, allerdings nutzt der CBQ-Algorithmus im
Linux Kernel nur eine einzigen Algorithmus und zwar den WFQ-Algorithmus.
2.3.2.5
Leaky Bucket
Stellt man sich einen Eimer mit einem Loch vor, so lässt sich beobachten, dass egal in
welcher Geschwindigkeit man Wasser in den Eimer gießt, das Wasser in einer konstanten
Rate r abfließt. Ist der Eimer voll, läuft überschüssiges Wasser über den Rand des Eimers und geht verloren. Das gleiche Konzept kann auf Aufträge angewendet werden und
heißt Leaky-Bucket-Algorithmus (LB-Algorithmus, Algorithmus des undichten Eimers)
[Tur02].
Der LB-Algorithmus besteht aus einem Bucket (Eimer), der bis zu n Aufträge aufnehmen
kann. Jeder Auftrag benötigt einen Token, um bearbeitet zu werden. Treffen mehr Aufträge ein als der Bucket aufnehmen kann, so werden Aufträge verworfen. Token werden in
einer Rate von r Token erzeugt. Ist der Bucket mit weniger als n Aufträgen gefüllt, so werden die neu erzeugten Token zu den bestehenden Tokens hinzugefügt. Da in einem Bucket
39
2.3. Queueing-Strategien
Kapitel 2. Grundlagen
maximal n Aufträge und damit auch n Token verfügbar sind, beträgt die Burst-Größe n
Aufträge. Die Burst-Größe beschreibt die maximale Anzahl der Aufträge die innerhalb
eines Zeitintervalls ohne Verzögerung bearbeitet werden können. Es können pro Zeitintervall, mit der Dauer t, maximal rt + n Token zur Verfügung gestellt und damit Aufträge
verarbeitet werden. Über die Erzeugungsrate der Token lässt sich die Durchschnittsrate,
mit der Aufträge verarbeitet werden, regulieren.
2.3.2.6
Hierarchical Token Bucket
Der Hierarchical-Token-Bucket-Algorithmus (HTB-Algorithmus) [VMSE+ 04] ist eine
Erweiterung des LB-Algorithmus. Eingehende Aufträge werden klassifiziert und in eine baumartige Struktur abgelegt. Die Klassifizierung erfolgt auf Basis von Filterfunktionen. Eine Klasse entspricht einem Knoten im Baum. Jede Klasse besitzt eine zugesicherte
Bandbreite AR (Assured Rate), eine obere Bandbreite CR (Ceil Rate), eine Priorität P
und ein Quantum Q. Das Quantum bestimmt die Menge der Tokens, die ein Blatt sich von
seinem Vorfahren leihen kann. Die Priorität definiert die Wichtigkeit einer Klasse innerhalb des Baumes. Die aufgeführten Parameter werden über ein Programm einmalig von
einem Anwender konfiguriert.
Die Blätter werden mit dem Deficit-Round-Robin Verfahren (DRR-Algorithmus), beginnend mit der niedrigsten Ebene im Baum, abgearbeitet. Der DRR-Algorithmus berücksichtigt unterschiedlich große Aufträge [SV95]. Jeder Queue im DRR wird eine Anzahl
übertragbarer Einheiten (deficit count) zugestanden. Ist der zu bearbeitende Auftrag kleiner als der deficit count, so wird der Auftrag bearbeitet und der deficit count um die Größe
des Auftrags dekrementiert. Ist der Auftrag zu groß, so wird der deficit count um den Wert
eines festgelegten Quantums erhöht. Nach mehreren Durchläufen wird der deficit count
die Größe des wartenden Auftrags erreicht haben. Der deficit count leerer Queues wird
stets auf Null gesetzt. Innerhalb einer Ebene arbeitet der Algorithmus die Blätter nach
Priorität ab.
Verbraucht ein Auftrag in einem Blatt seine zugesicherte Bandbreite (AR), muss es sich
Bandbreite von seinem Vorfahren leihen. Erreicht das Blatt die obere Bandbreite (CR)
sortiert sie Aufträge in eine Queue ein, solange bis Tokens verfügbar sind. Die Ausgangsbandbreite wird anhand der Priorität einer Klasse geteilt. Klassen mit einer hohen Priorität
können sich mehr Anteile der Bandbreite sichern als Klassen mit einer niedrigen Priorität.
40
Kapitel 3
Analyse
Aktuelle Web-Service-Anwendungen berücksichtigen Dienstgüteanforderungen wenig
bis gar nicht. In einigen speziellen Fällen ist es möglich, über zusätzliche Sprachen in einer festen Anwendungsumgebung Dienstgüteanforderungen zu formulieren und zu überwachen. Unabhängig von einer solchen festen Anwendungsumgebung soll ein generischer QoS-Proxy für Web Services entwickelt werden, der Dienstgüteanforderungen an
Web Services umsetzt. Im vorliegenden Kapitel werden Anforderungen herausgearbeitet und auf mögliche Lösungsansätze untersucht, die zu einem Entwurf der Architektur
führen.
3.1
Anforderungen
Das Ziel des QoS-Proxys ist es, Dienstgüteanforderungen (QoS-Anforderungen) an
Web Services umzusetzen. Abbildung 3.1 modelliert das Ziel als Anwendungsfalldiagramm. Ein Client ruft einen Web Service mit dem Anwendungsfall Web Service
Request auf. Der Web Service Request wird unter Berücksichtigung des Anwendungsfalls QoS-Anforderungen an Web Service Request umsetzen ausgeführt. Verantwortlich für das Umsetzen der QoS-Anforderungen ist der Proxy. Im Anwendungsfalldiagramm wird über die Erweiterungsbeziehung angedeutet, dass eine bestehende Web-Service-Anwendung um eine Komponente erweitert wird. Der Proxy soll
leicht in eine Web-Service-Anwendung integrierbar sein. Vorteile der leichten Integrierbarkeit sind das einfache Hinzufügen und Entfernen der Proxy-Komponente und das
Vermeiden unnötiger Anpassungen am Quelltext der Anwendung. Der Anwendungsfall QoS-Anforderungen an Web Service Request umsetzen lässt sich
41
3.1. Anforderungen
Kapitel 3. Analyse
Web Service
Request
<<include>>
Proxy
Client
QoS-Anforderungen an
Web Service Request
umsetzen
Abbildung 3.1: Anwendungsfalldiagramm: Berücksichtigen von QoS-Anforderungen an
Web Services
als Anwendungsfalldiagramm modellieren. In Abbildung 3.2 ist das Diagramm dargestellt. Akteure sind der Proxy und der Queueing-Algorithmus. Der Proxy klassifiziert den
eingehenden Web Service Request auf Grundlage von Dienstgüteparametern. Die Dienstgüteparameter werden über eine zu definierende Schnittstelle, angedeutet durch den Anwendungsfall Bestimmen der QoS-Anforderungen, ermittelt. Je nach Priorität
des Requests wird der Web Service Request in eine Queue abgelegt. Es existieren eine
Reihe von Queues, die unterschiedliche Dienstgüteklassen repräsentieren. Der QueueingAlgorithmus arbeitet die Queues nach einer festgelegten Strategie ab. Nachdem der Web
Service Request in der Queue abgearbeitet wurde, wird er vom Proxy weitergeleitet. Der
Klassifizieren der
Web Service
Requests
<<include>>
Einsortieren in
Queue
Bestimmen der
QoS-Anforderung
en
Bearbeiten der
Queue
Proxy
Queueing-Strategie
Weiterleiten des
Web Service
Requests
Abbildung 3.2: Anwendungsfalldiagramm: Umsetzen von QoS-Anforderungen an Web
Services
Anwendungsfall Bestimmen der QoS-Anforderungen lässt sich in einem weiterem Anwendungsfalldiagramm, in Abbildung 3.3 dargestellt, modellieren. Der Proxy soll
von außen über eine definierte Schnittstelle erreichbar sein. Die Schnittstelle soll es erlau-
42
Kapitel 3. Analyse
3.1. Anforderungen
Vereinbaren
eines SLA zu
einem Service
SLA Server
Einhalten der SLAs
Client
Abfragen von SLAs
zu einem Service
Proxy
Abbildung 3.3: Anwendungsfalldiagramm: Service Level Management
ben, den Proxy zu konfigurieren und die Queueing-Strategie festzulegen. Die Konfiguration des Proxys kann implizit über ein SLA erfolgen, das ein Client mit einem SLA-Server
vereinbart hat. Die im SLA enthaltenen SLOs definieren die Parameter, die der Proxy
für einen Service einhalten muss. Damit definieren die SLOs Richtwerte nach denen der
Proxy arbeitet. Eine weitere Schnittstelle für Statistiken soll Informationen über den Betrieb des Proxys liefern. Vorrangiges Ziel der Statistik-Schnittstelle ist es, den Erfolg der
Proxy-Strategie zu überprüfen.
Apache Tuscany soll als Rahmen für Web-Service-Anwendungen genutzt werden. Bestehende Web-Service-Anwendungen können leicht in eine Tuscany-Anwendung umgewandelt werden. Der QoS-Proxy soll mit der bereits im vorherigen Anwendungsfall angedeuteten Funktionalität in eine SCA-Anwendung beziehungsweise Tuscany integriert
werden. Für die Integration stehen verschiedene Ansätze zur Verfügung, die in den spätereren Abschnitten diskutiert werden. Die einzelnen Anforderungsbereiche lassen sich in
die folgenden Punkte zusammenfassen.
3.1.1
Integration
Grundlegende Idee der SCA, wie in Kapitel 2.2 erläutert, ist die Trennung von Implementierung und dem Zusammenfügen der Komponenten einer Anwendung während der
Entwicklung. Darauf aufbauend soll der Proxy als Komponente leicht zu einer SCAAnwendung hinzugefügt, aber auch entfernt werden können. Mögliche Ansätze zur Erweiterung der SCA wurden in Kapitel 2.2 vorgestellt und sollen für die Analyse berücksichtigt werden.
43
3.1. Anforderungen
3.1.2
Kapitel 3. Analyse
Queueing
In Kapitel 2.3 wurden verschiedene Queueing-Strategien vorgestellt. Die Vor- und Nachteile der einzelnen Queueing-Strategien sollen betrachtet und auf ihre Eignung zur Umsetzung von Dienstgüteanforderungen untersucht werden.
3.1.3
Monitoring und Konfiguration
Das Monitoring des QoS-Proxys erlaubt es, zur Laufzeit Abläufe im Proxy zu untersuchen
und zu beobachten. Notwendige Anpassungen sollen über eine Konfigurationskomponente erfolgen.
Monitoring
In Kapitel 2.1 wurde eine QoS-Erweiterung für WS-Agreement vorgestellt. Mit Hilfe der
Erweiterung können die Dienstgüteeigenschaften Durchsatz und Antwortzeit für einen
Service beschrieben werden. Beide Eigenschaften sind von verschiedenen Faktoren abhängig. Um sicherzustellen, dass vereinbarte SLAs nicht verletzt werden, muss der Proxy
instrumentiert werden. Im Rahmen der Analyse sollen Kenngrößen für den Proxy bestimmt und Instrumentierungspunkte im Proxy herausgearbeitet werden.
Konfiguration
Parameter des Proxys sollen über eine einheitliche Schnittstelle konfigurierbar sein. Mit
Hilfe der Schnittstelle sollen Queueing-Strategien festgelegt und ausgetauscht werden
können. Zusätzlich ist die Konfigurations-Schnittstelle für die Bestimmung der Dienstgüteanforderungen verantwortlich. Intern verfügt der Proxy über verschiedene Queues
unterschiedlicher Dienstgüteklassen. Verschiedene Clients, mit unterschiedlichen SLAs
können in der gleichen Queue bearbeitet werden. Eine beliebig hohe Anzahl von Dienstgüteklassen ist zu vermeiden, um die Effektivität des QoS-Proxy nicht einzuschränken.
Im Folgenden sollen für die vorangegangenen Anforderungen mögliche Lösungsansätze
untersucht werden, die zum Entwurf eines QoS-Proxys führen.
44
Kapitel 3. Analyse
3.2
3.2. Integration
Integration
Zu den grundlegendsten Anforderungen gehört die Integration des QoS-Proxys in Tuscany. Von besonderer Bedeutung ist dabei eine möglichst einfache Einbindung in eine
bestehende Tuscany-Installation und ein leichtes Hinzufügen und Entfernen in eine SCAAnwendung. Der Proxy soll auch in späteren Versionen von Tuscany integrierbar sein
unter der Vorausetzung, dass der Kern der Tuscany-Architektur nicht zu großen Änderungen unterworfen wird. Zu den Integrationsanforderungen des QoS-Proxys zählt die
Möglichkeit, Web Service Requests mitzuverfolgen und zu beeinflussen.
Es existieren verschiedene Ansätze zur Integration eines QoS-Proxys in Tuscany. Im Rahmen der Architektur der SCA wurden in Abschnitt 2.2 mehrere Erweiterungsmöglichkeiten vorgestellt. Weiterhin bietet Tuscany unabhängig von der Architektur der SCA eigene
Integrationsansätze. In den nachfolgenden Abschnitten sollen die unterschiedlichen Ansätze auf ihre Fähigkeit zur Integration eines QoS-Proxys in Tuscany untersucht werden.
3.2.1
Erweiterung der SCA
Die SCA lässt sich um eigene binding-, implementation- oder interfaceTypen erweitern. Zusätzlich ergibt sich mit dem contribution-Mechanismus die
Möglichkeit, funktionale Abhängigkeiten einer SCA-Anwendung auszulagern. Integriert
in Tuscany wird eine contribution über die in 2.2.4 vorgestellten Erweiterungspunkte.
Tuscany arbeitet intern mit einem Metadaten-Konzept, das in einem Model (Modell)
beschrieben wird. Jeder neue Typ muss Methoden zur Erzeugung des Modells zur Verfügung stellen. Instanzen werden in Tuscany üblicherweise nach der Fabrikmethode erzeugt
[Blo08].
In einem ersten Schritt werden die Erweiterungsmöglichkeiten über die verschiedenen
SCA-Elemente untersucht. Im weiteren wird der Ansatz, den Proxy als contribution
zu implementieren, betrachtet. Grundlage der Analyse bildet die Präsentation eines
Tuscany-Entwicklers [Fen08] und die Untersuchung des Tuscany-Quelltextes.
Realisierung als binding-, implemenation- oder interface-Typ
Entscheidend für die Integration eines QoS-Proxys in ein SCA-Element ist die Möglichkeit, Web Service Requests mitzuverfolgen und zu beeinflussen. Dabei sollte der QoS-
45
3.2. Integration
Kapitel 3. Analyse
Proxy die eigentlichen Aufgaben des SCA-Elementes ergänzen und keinesfalls verfremden. Im Folgenden werden die neuen möglichen Elemente aufgeführt und kurz vorgestellt:
• binding.proxy
Ein binding-Element beschreibt einen Zugriffsmechanismus für service- und
reference-Elemente einer Anwendung. Der Typ binding.proxy-Typ würde
auf dem Element binding.ws aufbauen und damit bereits über das Element auf
Web-Service-basierte Anwendungen einschränken.
• implementation.proxy
Ein implementation-Typ definiert die Technologie in der eine oder Teile einer Anwendung implementiert werden. Als Grundlage für einen eigenen
implementation.proxy-Typ müsste ein bestehendes implementationElement verändert werden und um die Proxy-Funktionalität ergänzt werden.
• interface.proxy
Ein interface definiert die Geschäftsfunktionalität einer Anwendung. Der
interface.proxy-Typ setzt voraus das ein zugehöriger Typ implementation.proxy existiert. Grundlage für diese Verknüpfung ist die Definition durch
den implementation-Typ und die Realisierung durch einen interface-Typ.
In der SCA ist es nicht möglich unterschiedliche Konstellationen mit implementation-/interface-Typen zu bilden.
Das binding.proxy-Element bietet den vielversprechensten Ansatz, da es nur auf
einen Zugriffsmechanismus einschränkt, allerdings hat das Element keine eigentliche Logik, da es im Grunde nur die Information zum Aufruf eines service- oder
reference-Elementes bietet.
Sowohl das implementation.proxy- als auch das interface.proxy-Element
verletzen die Anforderung an einen generischen Proxy. Beide Elemente müssten jede
durch ein implementation-Element in Tuscany verfügbare Technologie unterstützen,
um nicht auf ein implementation-Element einzuschränken.
Unabhängig von bereits festgestellten Nachteilen sollen für die einzelnen Typen, die nötigen Implementierungsschritte betrachtet werden um festzustellen, ob in einem der vorgestellten Elemente die Möglichkeit besteht, Einfluss auf Web-Service-basierte Aufrufe zu
nehmen.
Um einen neues SCA-Element in Tuscany zu integrieren, sind eine Reihe von verschiedenen Schritten notwendig. Zu diesen Schritten gehört:
46
Kapitel 3. Analyse
3.2. Integration
• Erweiterung der zum Element zugehörigen Interfaces.
• Implementierung einer Klasse zum Lesen, Schreiben und Verarbeiten der Modelldaten.
• Implementierung der Logik des neuen Elements in Provider- und Factory-Klassen.
• Registrieren der Komponenten in Tuscany.
Aus der Analyse der notwendigen Implementierungsschritte ergibt sich kein Ansatz für
ein neues Element Web Service Requests entgegenzunehmen und zu bearbeiten. Der einzig mögliche Ansatzpunkt für jedes Element bilden die Klassen, die die Logik des Elementes implementieren. Keine für die Logik verantwortlichen Klassen eines Elementes
bieten die Möglichkeit, Einfluss auf Web Service Requests zu nehmen. Weiterhin stimmt
inhaltlich keines der untersuchten Elemente mit dem Aufgaben eines QoS-Proxys überein. Keines der untersuchten Elemente eignet sich damit zur Integration des Proxys in die
SCA.
Realisierung als contribution
Mit Hilfe einer contribution werden funktionale Abhängigkeiten einer SCA-Anwendung in ein definiertes Format ausgelagert. Eine contribution kann dabei verschiedene XML-Dokumente oder auch eine komplette SCA-Anwendung beinhalten. Der QoSProxy würde als contribution implementiert werden, die über die in 2.2.4 vorgestellten Erweiterungspunkte in Tuscany integriert wird. Die Funktionalität des Proxys würde
dabei als SCA-Anwendung modelliert werden.
Eine SCA-Anwendung, auf die das Dienstgütemanagement angewendet wird, muss angepasst werden. Die Aufrufe der SCA-Anwendung müssen auf die durch den Proxy definierten reference-Elemente umgesetzt werden. Die Umsetzung geschieht unter anderem durch das Anpassen der composite-Datei. Daraus ergibt sich allerdings auch
das Problem, dass nicht sichergestellt werden kann, ob die reference-Schnittstelle
des Proxys derart generisch ist, dass das Dienstgütemanagement ohne Probleme immer
umgesetzt werden kann. Betrachtet man das Beispiel in 3.5, so ist ersichtlich, dass der
CalculatorService abhängig von den vier aufgeführten reference-Elementen
ist. Abbildung 3.5 stellt die Integration des Proxys in eine bestehende Anwendung, als
weitere Component, vor. Unabhängig von der Problematik einer generischen Schnittstelle
muss der Quelltext des Proxys für jede neue Anwendung angepasst werden, da die Aufrufe an einen Web Service für jede Anwendung unterschiedlich sind. Die contribution
47
3.2. Integration
Kapitel 3. Analyse
Abbildung 3.4: Calculator Service Component
bietet bisher den interessantesten Ansatz, scheitert allerdings an den Rahmenbedingungen der SCA. Der Proxy lässt sich damit nicht als contribution implementieren. Für
die weitere Analyse sollte die Möglichkeit betrachtet werden, die contribution als
Container-Format zu verwenden. Die contribution bietet ein Schnittstelle zur Integration in Tuscany.
Zusammenfassung
Keine der bisher vorgestellten Möglichkeiten eignet sich zur Integration des QoS-Proxy
in eine SCA-Anwendung. Der binding-Typ bietet den einfachsten Ansatz zur Integration, da er es erlaubt, auf Web Services als Zugriffsmechanismus einzugrenzen. Sowohl der
implementation- als auch der interface-Typ eignen sich nicht für die Integration
des Proxys, da für jede implementation- und interface-Technologie ein eigener Proxy entworfen werden müsste. Der generischen Ansatz des Proxys wird mit dieser
Einschränkung verletzt. Der Ansatz, den Proxy als contribution zu implementieren,
scheitert an den Rahmenbedingungen der SCA-Architektur.
48
Kapitel 3. Analyse
3.2. Integration
Abbildung 3.5: Calculator Service Component mit QoS-Proxy Component
3.2.2
Erweiterung von Tuscany
Das Apache-Tuscany-SCA-Runtime-Wire-Modell beschreibt den Vorgang der Integration und Konfiguration einer SCA-Anwendung in eine SCA Domain. In Abbildung 3.6
ist das Modell dargestellt. Die Integration und Konfiguration erfolgen in Form einer
oder mehrerer composite-Dateien. Ein composite wird erst nach seiner Konfiguration in der SCA Domain aktiviert. In einem ersten Schritt wird das composite
verarbeitet, um Interaktionen zur Laufzeit zu vereinfachen. Metadaten werden nach dem
promote-Attribut von services und references zusammengefasst. Im reduzierten Modell sind nun alle Informationen auf der Ebene von components verfügbar.
Der nächste Schritt verarbeitet alle Elemente unterhalb der composite-Hierarchie.
Zu den Elementen gehören component-implementation, reference- und
service-bindings. Die Elemente werden konfiguriert, um sie anschließend mit
components und externen Services zu verknüpfen (wire-Mechanismus). Im vorletzten Schritt werden references und services einer component über entsprechende bindings verknüpft. Die zur Laufzeit existierende Verknüpfung (runtime-wire)
besteht aus einer Reihe von invocation chains (Aufrufketten), die in einzelne Operationen unterteilt sind. Jede Aufrufkette besteht dabei aus einer Menge von invokers
49
3.2. Integration
Kapitel 3. Analyse
Runtime Wire
Invocation Chain
Invocation Chain
Runtime
Component
I
I
Runtime
Component
I
Service
Reference
SCA
Binding
SCA
Binding
Callback Invocation Chain
Callback Invocation Chain
I
I
I
Abbildung 3.6: Tuscany-SCA-Runtime-Wire-Modell (nach [Fou08])
und interceptors. Ein invoker stellt die Aufruflogik für binding-Protokolle und
implementation-Technologien zur Verfügung. Ein interceptor ist ein besonderer Typ von invoker, der zusätzliche Logik und Funktionalität bereitstellt. Das kann
beispielsweise die Umwandlung von Daten oder eine Art Transaktionskontrolle sein. Für
ausgehende Aufrufe wird eine Verknüpfung für eine component reference über
ein entsprechendes binding realisiert. Für eingehende Aufrufe wird eine Verknüpfung für ein component service über eine entsprechende implementation erzeugt. Ein callback wire (Callback-Verknüpfungen) wird mit einem component
service verknüpft um den Aufruf eines services als Callback zu realisieren. Der
letzte Schritt ist der Start des composites. Dabei werden die start()-Methoden des
ImplementationProvider, ReferenceBindingProvider und ServiceBindingProvider aufgerufen. Am Ende sind components, component references und component services initialisiert und bereit, miteinander zu interagieren.
In [BBC+ 07a] wird das Policy Framework der SCA beschrieben. Über die Attribute requires und policySet werden Policies in die SCA integriert. Das Attribut
requires benennt die entsprechende Policy, während das Attribut policySet eine
Liste von Regeln für die Policy repräsentiert. Tuscany bietet mehrere nach dem Policy
Framework implementierte Beispiele für SCA Policy. Eine der angebotenen Policys ist
die JDKLoggingPolicy. Der nächste Abschnitt soll die Möglichkeit der Integration des
QoS-Proxy als Policy-Erweiterung am Beispiel der JDKLoggingPolicy untersuchen.
50
Kapitel 3. Analyse
3.2. Integration
Realisierung als Policy-Erweiterung
Die Policy JDKLoggingPolicy ermöglicht es, Aufrufe von services und references
zu protokollieren. Die Protokollierung wird über das Setzen des Attributes require
aktiviert. Als Beispiel dient der bereits in Abschnitt 2.2.3 vorgestellte TaschenrechnerService. In Quellcode 3.1 ist ein Auszug aus der composite-Datei des TaschenrechnerServices abgebildet. Für die reference-Elemente addService und subtractService wird die Policy explizit über das Attribute requires eingebunden.
1 <composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="http://sample"
2 xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0" xmlns:sample="http://sample"
3 name="Calculator">
4
5 <service name="CalculatorService" promote="CalculatorServiceComponent">
6
<interface.java interface="calculator.CalculatorService" />
7
<binding.ws/>
8 </service>
9
10 <component name="CalculatorServiceComponent">
11
<implementation.java class="calculator.CalculatorServiceImpl"/>
12
<reference name="addService" promote="" requires="tuscany:logging">
13
<interface.java interface="calculator.AddService" />
14
<binding.ws uri="http://localhost:8080/sample-add-ws-webapp/AddService"/>
15
</reference>
16
<reference name="subtractService" promote="" requires="tuscany:logging">
17
<interface.java interface="calculator.SubtractService" />
18
<binding.ws uri="http://localhost:8080/sample-sub-ws-webapp/SubtractService"/>
19
</reference>
20
...
21 </component>
22 </composite>
Quellcode 3.1: Beispiel-composite mit JDKLoggingPolicy
Zusätzlich existiert eine Datei definitions.xml, in der sich Einstellungen für die
Policy befinden. In Quellcode 5.4 ist ein Teil der Datei dargestellt. Über das Element intent wird der Name der Policy vergeben. Im Element constrains wird
eine Einschränkung auf einen Typ der SCA gesetzt. Im Beispiel wird auf den Typ
sca:implementation.java eingeschränkt. Eine kurze Beschreibung der Policy
findet sich im Element description. Das policySet-Element definiert eine Reihe
von konkreten Policies, auf die ein implementation- oder binding-Typ angewandt
wird. Das Attribut provides bestimmt den Bezug auf das intent-Element. Innerhalb
des policySet-Elementes befindet sich das Element jdkLogger, welches es erlaubt
ein Log-Level einzustellen.
51
3.2. Integration
Kapitel 3. Analyse
1 <?xml version="1.0" encoding="ASCII"?>
2 <definitions xmlns="http://www.osoa.org/xmlns/sca/1.0"
3 targetNamespace="http://tuscany.apache.org/xmlns/sca/1.0"
4 xmlns:sca="http://www.osoa.org/xmlns/sca/1.0"
5 xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0" xmlns:pol="PolicyExample">
6
7 <intent name="logging" constrains="sca:implementation.java">
8
<description>
9
All messages to and from this implementation must be logged
10
</description>
11 </intent>
12 ...
13 <policySet name="JDKLoggingPolicy" provides="tuscany:logging"
14
appliesTo="sca:implementation.java"
15
xmlns="http://www.osoa.org/xmlns/sca/1.0">
16
<tuscany:jdkLogger name="PolicyExample">
17
<logLevel>FINER</logLevel>
18
</tuscany:jdkLogger>
19 </policySet>
20 </definitions>
Quellcode 3.2: Beispiel-defintions.xml der JDKLoggingPolicy
Die Implementierung der JDKLoggingPolicy besteht aus den folgenden Dateien:
• JDKLoggingPolicyDefinitionsProvider
Die Klasse JDKLoggingPolicyDefinitionsProvider lädt die Policyeigene Datei definitions.xml. In der Datei befindet sich ein intentElement das die JDKLoggingPolicy beschreibt und auf den Typ implementation.java einschränkt. Die Klasse implementiert das Interface SCADefinitionsProvider. Der SCADefinitionsProvider ist verantwortlich für
das Laden der Datei und das Erzeugen eines SCA Definition Models.
• JDKLoggingImplementationPolicyProvider
Die Klasse implementiert das Interface PolicyProvider für eine implementation. Das Interface enthält zwei Methoden createInterceptor() und
getPhase(). Die erste Methode erzeugt einen Interceptor für eine Operation,
die zweite Methode legt fest, in welcher Phase der Interceptor hinzugefügt werden
soll.
• JDKLoggingPolicyInterceptor
Die Klasse JDKLoggingPolicyInterceptor realisiert den Interceptor. Der
Interceptor ist eine Art Vermittler zwischen dem Client und einem entsprechendem
Ziel.
52
Kapitel 3. Analyse
3.2. Integration
• JDKLoggingPolicy
Die Klasse implementiert Policies, die als Parameter für Axis 2, einer SOAP Engine, angewandt werden können.
• JDKLoggingPolicyProcessor
Um XML-Dateien auszuwerten, implementieren Teile von Tuscany einen eigenen
StAXArtifactProcessor. Die Klasse JDKLoggingPolicyProcessor
implementiert den StAXArtifactProcessor für die JDKLoggingPolicy. Die
Klasse wertet die Datei definitions.xml einer SCA-Anwendung aus, in der
unter anderem das Log-Level eingestellt wird.
• JDKLoggingPolicyProviderFactory
In der Klasse JDKLoggingPolicyProviderFactory werden die Policy
Provider für die Typen implementation, service und binding definiert.
• JDKLoggingReferencePolicyProvider
Die Klasse JDKLoggingReferencePolicyProvider implementiert das Interface PolicyProvider für eine reference.
• JDKLoggingServicePolicyProvider
Wie auch die Klasse JDKLoggingReferencePolicyProvider implementiert die Klasse das Interface PolicyProvider, allerdings für einen service.
Von zentraler Bedeutung ist die Klasse JDKLoggingPolicyInterceptor, die den
Interceptor der Policy implementiert. Der Interceptor der Policy wird in die bestehende
Aufrufkette einer SCA-Anwendung integriert (vergleiche Abbildung 3.7). Alle Web Service Requests passieren den Interceptor der Policy. Der Interceptor kann alle Aufrufe mitverfolgen und auf eine Konsole ausgeben oder in eine Log-Datei schreiben. Für den Fall
der JDKLoggingPolicy wird die Funktionalität durch die Anpassung der compositeDateien einer SCA-Anwendung und das Erzeugen einer zusätzlichen Datei mit Informationen über das Log Level und der Policy bereitgestellt.
Aus der Analyse der JDKLoggingPolicy ergeben sich eine Reihe von interessanten Ansätzen zur Integration des QoS-Proxys mit der SCA. Die in Bild 3.8 angedeutete Einbettung des QoS-Proxy in die Aufrufkette erlaubt es, Web Service Requests auszuwerten. Diese Auswertung ist die Grundlage für das Queueing. Zum anderen existiert mit
dem StAXArtifactProcessor die Möglichkeit, eine Konfiguration aus einer XMLDatei nach einem bekannten Schema auszuwerten. Jeder Interceptor implementiert eine
53
3.2. Integration
Kapitel 3. Analyse
Invocation Chain
MSG
MSG
MSG
MSG
Policy
MSG
Nachricht in der Invocation Chain
Invoker/Interceptor in der Invocation Chain
Interceptor der JDKLoggingPolicy in der Invocation Chain
Abbildung 3.7: Integration Policy
Abbildung 3.8: Integration Proxy
Methode getNext(). Über diese Methode wird eine Nachricht, im Bild durch die weiße Box an den Pfeilen angedeutet, an den nächsten Interceptor in der Aufrufkette weitergereicht. Ein erster Ansatz ist es, die Nachrichten des vorhergehenden Interceptors in
eine Queue einzusortieren und diese nach einem entsprechenden Algorithmus, zur Sicherung von Dienstgüte-Eigenschaften, abzuarbeiten. Aus diesem Ansatz ergibt sich das
folgende Bild 3.9. Das Ablegen von Nachrichten in eine Queue und die damit verzögerte
Bearbeitung führt unter Umständen zu Problemen. Der Queueing-Algorithmus arbeitet
seine Pakete in der Queue unabhängig von dem zugrunde liegenden Protokoll ab. Unter
Umständen können durch das Queueing Timeouts oder andere unerwünschte Effekte auftreten. Eine Untersuchung des Laufzeitverhaltens der JDKLoggingPolicy ergab, dass für
jeden Web Service Request ein Thread pro Interceptor gestartet wird. Ein auf JSR 236
[JN06] basierender Thread Pool Manager verwaltet die Threads innerhalb von Tuscany.
Ist ein Web Service Request fertig bearbeitet, wird der nicht mehr benötigte Thread zurück
in den Pool gelegt. In einem Test wurden die einzelnen Threads für eine Zeit von mehreren Sekunden pausiert. Das Ziel des Testes war es, zu beobachten, ob ein unerwünschtes
54
Kapitel 3. Analyse
3.2. Integration
Abbildung 3.9: Integration Proxy mit Nachrichten-Queue
Abbildung 3.10: Integration Proxy mit Thread-Queue
Verhalten eintritt. Je nach Zeitpunkt des Aufrufes wurden die Web Service Requests, wie
erwartet, verzögert beantwortet. Aus den Beobachtungen ergibt sich ein neuer Ansatz zur
Implementierung des QoS-Proxy, dargestellt in Bild 3.10.
Der Web Service Request wird mit dem Interceptor Thread pausiert und in eine entsprechende Queue des Proxys eingefügt. Der Ansatz fügt damit nicht einzelne Datenpakete
eines Web Services in Queues ein, sondern einen vollständigen Web Service Request.
Zuätzlich wurde untersucht, ob die Antwort auf eine Web Service Request im selben
Thread erfolgt. Wird ein Interceptor Thread wieder aktiv und stellt den Web Service
Request, so erfolgt die Antwort auf den Web Service Request im gleichen Interceptor
Thread. Eine Analyse eines geeigneten Paketformats entfällt mit dem vorliegenden Ansatz.
Mit der vorgestellten Lösung muss eine SCA-Anwendung geringfügig angepasst werden. Um den Proxy als Policy-Erweiterung zu integrieren, müssen in den compositeDateien der Anwendung die jeweiligen require-Attribute gesetzt werden. Für diese
Aufgabe könnte man ein graphisches Werkzeug entwickeln, welches die bestehenden
composite-Dateien analysiert und dem Anwender erlaubt services und references auszuwählen, deren Aufruf vom QoS-Proxy bearbeiten werden soll. Zusätzlich
könnte eine definitions.xml-Datei erzeugt werden, die die in dem Werkzeug gesetzten Einstellungen berücksichtigt.
55
3.3. Queueing
3.2.3
Kapitel 3. Analyse
Zusammenfassung
In einem ersten Ansatz wurden die Möglichkeiten der Integration in eine SCA-Anwendung
und Tuscany mit eigenen, neuen Typen und Erweiterungen untersucht. Eigene Typen eignen sich nicht zu Integration, da keine Möglichkeit besteht, zur Laufzeit direkt Einfluss
auf einen Web Service Request zu nehmen. Der Proxy müsste für jede individuelle SCAAnwendung angepasst werden. Darauf aufbauend wurden interne Mechanismen von Tuscany betrachtet und untersucht. Policy-Erweiterungen bieten die Möglichkeit den Proxy in
Tuscany zu integrieren und individuell für jede Anwendung zu konfigurieren. Der Proxy
soll als Policy-Erweiterung für Tuscany implementiert werden.
3.3
Queueing
Im Folgenden sollen die in Abschnitt 2.3 vorgestellten Queueing-Strategien auf ihre Eignung für den QoS-Proxy untersucht werden. Grundlage für die Bewertung ist, neben den
spezifischen Eigenschaften der Algorithmen, die Möglichkeit, Dienstgüteanforderungen
wie Durchsatz oder Antwortzeit umzusetzen. Alle Queueing-Strategien werden zusammen mit dem Leaky-Bucket-Verfahren zur Umsetzung von Durchsatzanforderungen betrachtet.
3.3.1
Untersuchung der Queueing-Strategien
Multi Band Priority Queueing
Der MBPQ-Algorithmus ist ein Priority-Queueing-Algorithmus der n Queues zu Bändern zusammenfasst. Dabei schwächt der Algorithmus bekannte Nachteile des PriorityQueueing-Algorithmus ab. Unter der Annahme einer enstprechenden Last, kann es dennoch dazu kommen, dass Aufträge in niedrigprioren Queues nicht mehr bearbeitet werden. Der Algorithmus eignet sich nicht zur Umsetzung von Anforderungen an die Antwortzeit, da im Zweifelsfall immer hochpriore Bänder gegenüber niedrigprioren Queues
bevorzugt werden. Zusammen mit dem Leaky-Bucket-Algorithmus lassen sich Anforderungen an den Durchsatz umsetzen. Dabei wird sichergestellt dass der Algorithmus eine
geforderte Bandbreite nicht überschreitet. Der Algorithmus kann allerdings nicht sicherstellen, dass jedes Band einen Anteil jederzeit an der Gesamtbandbreite erhält.
56
Kapitel 3. Analyse
3.3. Queueing
Stochastic Fairness Queueing
Der SFQ-Algorithmus erweitert den einfachen Fairness-Queueing-Algorithmus. Der Algorithmus eignet sich nicht zur Umsetzung von Antwortzeitverhalten, da das Einsortieren
in die Queues nach einer stochastischen Funktion erfolgt. Damit kann nicht sichergestellt
werden, dass Aufträge in eine bestimmte Queue abgelegt und entsprechend abgearbeitet werden. Zusammen mit dem Leaky-Bucket-Algorithmus kann der Durchsatz reguliert
werden. Im Gegensatz zum MBPQ-Algorithmus erhält jede Queue Anteil am Durchsatz,
allerdings kann kein Durchsatz für Aufträge einer bestimmten Quelle definiert werden.
Weighted Fairness Queueing
Der WFQ-Algorithmus ist eine Erweiterung des Fairness-Queueing-Algorithmus um Gewichte. Je höher das Gewicht einer Queue, desto höher die Priorität der Aufträge die darin
abgelegt werden. Das Gesamtgewicht entspricht der maximal verfügbaren Bandbreite in
einer Zeiteinheit. Der Algorithmus erlaubt eine Priorisierung und garantiert eine Bearbeitung der Aufträge. Damit eignet sich der Algorithmus zur Umsetzung von Antwortzeitanforderungen. Zusammen mit dem Gewicht einer Queue und dem Leaky-BucketAlgorithmus kann sichergestellt werden dass eine Queue nie mehr als dem Gewicht entsprechende Anzahl von Tokens entnehmen kann. Jeder Queue wird damit ein Anteil an
der Gesamtbandbreite zugesichert.
Class Based Queueing
Der CBQ-Algorithmus klassifiziert eingehende Aufträge und legt sie in eine baumartige
Struktur ab. Die Blätter des Baumes werden von verschiedenen Queueing-Algorithmen
abgearbeitet. Parameter zum Bilden der Äste in diesem Baum können Prioritäten sein.
Jeder Ast im Baum hat ein Gewicht. Die Gewichte sind entsprechend Anteile an der Gesamtbearbeitungsrate. Sind in einem Blatt keine Aufträge, so kann sich ein benachbartes
Blatt in der Baumstruktur Teile der Bandbreite leihen. Der Algorithmus bietet damit eine
recht hohe Flexibilität und erlaubt es, zur Laufzeit Bandbreitenanforderungen dynamisch
zu ändern. Der Algorithmus eignet sich zur Umsetzung von Antwortzeit und Durchsatz,
ist allerdings relativ komplex. Das Konzept des Leihens von Bandbreite ist nur in besonderen Anwendungsszenarien von Interesse.
57
3.3. Queueing
Kapitel 3. Analyse
Queueing Strategie
Multi Band Priority Queueing
Stochastic Fairness Queueing
Weighted Fairness Queueing
Class Based Queueing
Hierarchical Token Bucket
Antwortzeit
−−
−−
++
++
++
Durchsatz
−
−−
+
++
++
Summe
−−−
− − −−
+++
+ + ++
+ + ++
Tabelle 3.1: Bewertung der Queueing-Strategien
Hierarchical Token Bucket
Der HTB-Algorithmus repräsentiert einen erweiterten Token-Bucket-Algorithmus und
stellt eine Alternative zum CBQ-Algorithmus dar. Aufträge werden nach einer FilterFunktion in die Blätter eines Baumes einsortiert.
Der wichtigste Mechanismus im Algorithmus ist das Prinzip des Leihens. Die Blätter
leihen sich Tokens von ihrem Vorfahren. Erreichen die Blätter einen festgelegten Wert, so
werden die Aufträge in einer Queue abgelegt und zwar solange, bis wieder eine festgelegte
Menge von Tokens verfügbar ist. Legt man die verfügbare Anzahl der Tokens pro Vorfahre
fest, so lassen sich Gewichte auf einzelne Äste des Baumes abbilden.
Der Algorithmus kann über Gewichte, ähnlich wie der WFQ-Algorithmus, Prioritäten
nachbilden. Der Algorithmus ist ähnlich wie der CBQ-Algorithmus relativ komplex. Das
Prinzip des Leihens von Bandbreite ist wie auch beim CBQ-Algorithmus nur für spezielle
Anwendungsszenarien von Interesse.
3.3.2
Zusammenfassung
Die Tabelle 3.1 gibt einen Überblick über die untersuchten Queueing-Strategien. Als
besonders ungeeignet haben sich der SFQ- und der MBPQ-Algorithmus erwiesen. Von
den vorgestellten Queueing-Strategien soll der kombinierte WFQ-/LB-Algorithmus implementiert werden. Das vorgestellte Verfahren bietet die einfachste Möglichkeit, Dienstgüteanforderungen wie Antwortzeit und Durchsatz umzusetzen. Die hohe Flexibilität von
CBQ und HTB bringen mehr Punkte in der Bewertung bei der Umsetzung von Durchsatzanforderungen, allerdings sind beide Algorithmen relativ komplex und es ist ungewiss ob
sich die Algorithmen auch außerhalb des Linux-Kernel-Umfeld beim berücksichtigen von
Web-Service-Anfragen bewähren.
Nach einer erfolgreichen Implementierung des WFQ-/LB-Algorithmus sollte der CBQAlgorithmus implementiert werden. Die Komplexität des Algorithmus entsteht zum ei-
58
Kapitel 3. Analyse
3.4. Monitoring und Konfiguration
nem durch die Gewichte, die in Form von Anteilen der Bearbeitungsrate abgebildet werden und zum anderen durch Blätter einer Ebene, die sich Anteile an der Bearbeitungsrate
von Nachbarblättern leihen können. Die Bearbeitungsrate ist variabel und von verschiedenen Faktoren abhängig. Die Funktionalität des Algorithmus ist wiederum abhängig von
der Bearbeitungsrate. Ist die Bearbeitungsrate zu niedrig, so arbeitet der Algorithmus ineffizient, ist die Bearbeitungsrate zu hoch so verletzt der Algorithmus unter Umständen
die Dienstgüteanforderungen.
Im Linux Kernel entspricht die Bearbeitungsrate des CBQ-Algorithmus der Bandbreite eines Netzwerkgerätes deren Zugriff von mehreren Diensten und Anwendungen geteilt
wird. Über einen gewissen Zeitraum betrachtet lässt sich die Bearbeitungsrate immer besser bestimmen. Der Algorithmus sollte implementiert werden um verschiedene Aufträge
einer Dienstgüteklasse in eine baumartige Struktur ablegen zu können. Von besonderem
Interesse dabei ist es zu beobachten, wie sehr sich die Berücksichtigung von Hierarchien
auf die Fähigkeit Dienstgüteanforderungen umzusetzen auswirkt. Für eine bessere Bewertung sollte zusätzlich der HTB-Algorithmus implementiert werden, da er ähnliche Ziele
verfolgt, aber einen anderen Ansatz zur Lösung wählt.
3.4
Monitoring und Konfiguration
Der QoS-Proxy soll eine einheitliche Schnittstelle zum Monitoring und zur Konfiguration des Proxys anbieten. Die Implementierung des QoS-Proxys erfolgt in Java. Zu
den bekannten Standards für IT-Management gehören das Simple-Network-ManagementProtokoll (SNMP) [CFSD90] und das Common Information Model (CIM) [Dis05].
SNMP hat seinen Ursprung im Management von Netzwerken. CIM ist das Informationsmodell für das Web-based Enterprise Management (WBEM) der Distributed Management
Task Force (DMTF)1 , das einen Standard für das Management von verteilten Anwendungen spezifiziert. Mit den Java Management Extensions (JMX) [Sun02] hat sich in den
letzten Jahren eine weitere Technologie zum Management etabliert. Bekannte Implementierungen von JMX zum Management von Java-Anwendungen finden sich zum Beispiel
in JBoss, BEA Weblogic und IBM Websphere.
Grundlage für die Integration des QoS-Proxys in SCA ist das Apache-Tuscany-Projekt.
Für SNMP und CIM existieren Umsetzungen in Java, allerdings ist JMX vorzuziehen,
da es Bestandteil der Java API ist und leicht in Java-Umgebungen zu integrieren ist. Im
folgenden Abschnitt soll die Architektur von JMX kurz vorgestellt werden.
1
Homepage der DMTF: http://www.dmtf.org/
59
3.4. Monitoring und Konfiguration
3.4.1
Kapitel 3. Analyse
Java Management Extensions
Die Java-Management-Extensions-Spezifikation (JMX) [Sun02, Sun06] beschreibt einen
Ansatz zur Instrumentierung von Java-Anwendungen. JMX führt das Konzept der Manageable Bean oder auch MBean in Java ein. MBeans sind Java Beans, die um eine
Management-Funktionalität erweitert wurden. Externe Management-Werkzeuge können
über MBeans die Zustände eines Java-Objektes abfragen und steuern. Die Architektur,
dargestellt in Abbildung 3.11, ist in drei Schichten unterteilt. Im Instrumentation Level
Java Virtual Machine
JMX Management Application
Distributed
Services
Level
C
C
PA
C
MBean Server
Agent
Level
Agent
Services
Agent
Services
Instrumentation
Level
Ressource 2
Ressource 4
Ressource 1
Ressource 3
PA
C
Protocol Adaptor
Ressource (MBean)
Connector
Abbildung 3.11: Java-Management-Extension-Architektur
werden die Rahmenbedingungen definiert, wie eine MBean zu implementieren ist, damit
diese eine Verbindung zwischen Ressource und einer Management-Anwendung herstellen kann. Kern des Agent Level ist der MBean Server. Der MBean Server ist für die Kommunikation zwischen der Management-Anwendung und dem entsprechenden MBean verantwortlich. Intern verfügt der MBean Server über ein Repository, an das sich eine MBean
registriert. Die Agent Services sind verantwortlich für die Ressource und stellen diese
über den MBean Server einer Management-Anwendung zur Verfügung. Das Distributed
Services Level bietet Interfaces zur Entwicklung von Management-Anwendungen. Zu
60
Kapitel 3. Analyse
3.4. Monitoring und Konfiguration
den Aufgaben des Distributed Services Level gehört die semantische Umsetzung einer
MBean auf Auszeichnungssprachen wie HTML oder Protokolle wie SNMP.
Die JMX-Spezifikation kennt vier verschiedene MBean-Typen:
• Standard MBean
• Dynamic MBean
• Open MBean
• Model MBean
Die Standard MBeans verfolgen den einfachsten Implementierungsansatz, um die Management-Funktionalität zur Verfügung zu stellen. Alle relevanten Management-Funktionen werden in einem Interface exportiert, das der Namenskonvention KlassenameMBean folgt. Die Methoden werden durch eine Klasse implementiert. Dynamic MBeans
bieten eine höhere Flexibilität in der Repräsentation von Datenstrukturen. Während bei
Standard MBeans bereits vor der Laufzeit der Typ eines Attributs feststeht, erlauben Dynamic MBeans den Einsatz von dynamischen Strukturen, also Strukturen, deren Aussehen erst zur Laufzeit feststeht oder sich beständig ändert. Für eine Dynamic MBean muss
eine Klasse das DynamicMBean-Interface implementieren. Open MBeans bieten Möglichkeiten, den Aufbau einer MBean näher für eine Management-Anwendung oder für den
Anwender einer Management-Anwendung zu beschreiben. Eine Open MBean implementiert das DynamicMBean-Interface und stellt weitere Methoden zur Beschreibung der
Klasse zur Verfügung. Zusätzlich ist die Anzahl der Datentypen, im Gegensatz zu einer
Dynamic MBean, eingeschränkt. Die Model MBean ist eine generische, konfigurierbare
MBean, mit der jede Ressource instrumentiert werden kann. Model MBeans entsprechen
Dynamic MBeans, die zusätzlich weitere Interfaces implementieren. Die Interfaces exportieren Funktionen, die zu einer instanziierbaren MBean führen. Alle JMX-konformen
JMX Agents müssen eine Model MBean implementieren. Mit dieser Voraussetzung ist
garantiert, dass Model MBeans in jeder Umgebung, die die JMX-Spezifikation umsetzt,
lauffähig sind.
Mit JMX ist es möglich interne Zustände des QoS-Proxys zur Laufzeit zu beobachten und zu steuern. Von besonderem Interesse ist es dabei mittelfristig, das Verhalten
der Queueing-Strategien und das Einhalten von Service Level Agreements zu überprüfen. Langfristig lassen sich bequem Statistiken erstellen. Ein weiterer Vorteil von JMX
ist die Möglichkeit, den QoS-Proxy ohne viel Aufwand in bestehende JMX-basierte
Management-Umgebungen zu integrieren.
61
3.4. Monitoring und Konfiguration
3.4.2
Kapitel 3. Analyse
Monitoring
Das Monitoring des Proxys versucht sicherzustellen, dass SLAs nicht verletzt werden.
Dazu muss der Proxy instrumentiert werden. Die Instrumentierungspunkte und die daraus
ermittelten Ergebnisse sind relevant für die Durchsetzung von SLOs. Die Ergebnisse des
Monitorings sollen über eine einheitliche Schnittstelle verfügbar gemacht werden.
3.4.2.1
Kenngrößen
Kenngrößen sind quantitative Größen, die Leistungsmerkmale eines Systems beschreiben [KS93]. Mit Hilfe von Kenngrößen sollen objektive Aussagen über die Leistung des
Proxys getroffen werden. Kenngrößen stimmen nicht unbedingt mit beobachtbaren Merkmalen des Systems überein und ergeben sich daher oft aus mehreren Messgrößen. Messgrößen sind Eigenschaften, die direkt im System feststellbar sind. Die einzelne Instanz
einer Messgröße wird Messwert genannt.
Für den Proxy sind die folgenden Kenngröße von besonderem Interesse:
• Verweilzeit
Die Verweilzeit entspricht der Zeit in der ein Web-Service-Anfrage im System ist.
Damit beschreibt sie die Zeitspanne vom Eintreffen der Web-Service-Anfrage im
Interceptor bis zur Antwort des Web-Services auf die Anfrage.
• Bearbeitungszeit
Die Bearbeitungszeit entspricht der Zeit in der eine Web-Service-Anfrage bearbeitet wird.
• Wartezeit
Die Wartezeit beschreibt den Zeitraum in dem der Interceptor einer Web-ServiceAnfrage nicht aktiv ist. Innerhalb der Architektur des QoS-Proxys ist das insbesondere die Zeit in der der Thread in einer Queue ist.
Betrachtet man mehrere Instanzen dieser Kenngrößen, so lassen sich eine Reihe von Werten bilden. Neben dem Minima und Maxima einer Kenngröße ist der Mittelwert und die
Standardabweichung für die Beurteilung des Systems relevant. Die zu den Kenngrößen
zugehörigen Messgrößen sollen im folgenden Abschnitt vorgestellt werden.
62
Kapitel 3. Analyse
3.4.2.2
3.4. Monitoring und Konfiguration
Instrumentierung
Abbildung 3.12 zeigt das bereits aus 3.2.2 bekannte Modell einer Aufrufkette. Zum Zeitpunkt (1) übergibt sich der Interceptor selbst als Parameter an den Proxy, der ihn schlafen
legt und in eine interne Queue ablegt. Nach einer gewissen Zeit wird der Interceptor wieder aufgeweckt (2). Der Interceptor führt seine eigentliche Funktionalität fort und ruft den
Service auf (3). Der Service antwortet dem Interceptor (4). Zur Berechnung der Kenngrößen ergeben sich eine Reihe von Messgrößen, die im Folgenden eingeführt werden.
Der Zeitpunkt zum Aufruf des Interceptors wird tInterceptorAuf ruf und der Zeitpunkt des
Proxyaufrufs wird tP roxyAuf ruf genannt. Mit tInterceptorAktiv ist der Zeitpunkt definiert in
Invocation Chain
MSG
3
MSG
MSG
MSG
MSG
Proxy
1
2
MSG
MSG
4
Abbildung 3.12: Instrumentierung von Apache Tuscany
dem der Interceptor Thread wieder aktiv wird. Der Service wird erst aufgerufen, nachdem
der Interceptor Thread wieder aktiv wurde. Der Aufruf-Zeitpunkt wird tServiceAuruf , der
Zeitpunkt zu dem die Antwort zugestellt wird tServiceAntwort genannt. In Tabelle 3.2 werden die im vorherigen Abschnitt vorgestellten Kenngrößen den Messgrößen zugeordnet.
Wie in Abschnitt 3.3 vereinbart, setzt ein Token-Bucket-Algorithmus die durch die
Dienstgüteigenschaft Durchsatz vereinbarte Bandbreite-Anforderungen um. Der Durchsatz, also die Anzahl der Web Service Requests pro Zeiteinheit, muss gemessen werden
und auf die im SLO vereinbarte Zeiteinheit umgerechnet werden. Der gemessene Durchsatz dient der Anpassung der Parameter des Token-Bucket-Algorithmus. Die Dienstgüteeigenschaft Antwortzeit entspricht der Kenngröße Bearbeitungszeit. Abweichungen in
der Antwortzeit mit den vereinbarten Werten im SLA sind damit eindeutig und schnell
identifizierbar.
Bei der Wahl der Methode zur Messung der Zeit sollte eine zuverlässige und möglichst
63
3.4. Monitoring und Konfiguration
Kenngröße
Verweilzeit
Bearbeitungszeit
Wartezeit
Kapitel 3. Analyse
Berechnung
tServiceAntwort − tInterceptorAuf ruf
tServiceAntwort − tServiceAuruf
Verweilzeit − Bearbeitungszeit − tP roxyAuf ruf
Tabelle 3.2: Berechnung der Kenngrößen im QoS-Proxy
genaue Bibliothek genutzt werden. Unterschiedliche Implementierungen nutzen unterschiedliche Ansätze zur Bestimmung der Zeit. Die Art der Implementierung sollte berücksichtig werden, um eine interferenzarme Messung zu gewährleisten und korrekte Ergebnisse zu garantieren. Die Java API stellt mit System.currentTimeMili() und
System.nanoTime() geeignete Methoden zur Zeitmessung bereit. Mit der in 3.4.1
vorgestellten JMX-Spezifikation kann eine einheitliche und verbreitete Schnittstelle für
externe Management-Anwendungen zur Verfügung gestellt werden.
3.4.3
Konfiguration
Der Proxy soll über eine einheitliche Schnittstelle konfigurierbar sein. Dabei soll eine
Konfiguration sowohl vor dem Start des QoS-Proxys, als auch zur Laufzeit möglich sein.
Ein Ansatzpunkt zur Integration einer Konfigurationsdatei besteht im hinzufügen eines
Attributs im policySet der definitions.xml-Datei einer SCA-Anwendung. Die
Konfigurationsdatei sollte es erlauben Parameter für die Queueing-Strategie oder die
Dienstgüteklasse zu setzen. Über JMX sollten ein Teil der gesetzten Parameter veränderbar sein um Anpassungen an den QoS-Proxys während des Betriebes zu ermöglichen.
Service Level Management
Zusätzlich zur Konfiguration des QoS-Proxys zum Zeitpunkt des Startes und zur Laufzeit, ist der Proxy verantwortlich für das Bestimmen der Service Level Agreements zu
einem Service. Die Service Level Agreements beschreiben die Zusicherungen an einen
Service in Form von Service Level Objectives. Von besonderem Interesse sind dabei Zusicherungen in Form von Dienstgüteeigenschaften wie Durchsatz oder Antwortzeit. Diese
Dienstgüteeigenschaften definieren den Rahmen in dem eine Queueing-Strategie arbeitet.
Abbildung 3.13 beschreibt einen möglichen Vorgang zur Bestimmung der Service Level Agreements. Der QoS-Proxy erzeugt in einem ersten Schritt initial verschiedene
Agreement Templates zu einem Service. Die erzeugten Agreement Templates
64
Kapitel 3. Analyse
3.4. Monitoring und Konfiguration
werden in einem WSAG4J-System gespeichert und verschiedenen Clients angeboten, die
an einem SLA mit diesem Service interessiert sind. Ein Client erzeugt auf Basis der
Agreement Templates einen Agreement Offer, der vom WSAG4J-System geprüft wird. Für den Fall einer positiven Überprüfung wird ein Agreement erzeugt und
dem Client zugeschickt. Der QoS-Proxy wird über das Agreement zu einem seiner Services informiert.
Proxy
Registrieren von
Agreement
Templates
WSAG4J
Client
Erzeugen eines
Agreement
Offer
Übertragen des
neu erzeugten
Agreements
Agreement Template
Offerieren der
Agreement
Templates
Agreement Offer
Agreement
Abbildung 3.13: Kommunikation zwischen QoS-Proxy, WSAG4J und einem Client
Neben einem Mechanismus zur Registrierung von Agreement Templates benötigt
der QoS-Proxy einen Art Callback-Mechanismus der es dem WSAG4J-System erlaubt
den QoS-Proxy zu informieren sobald ein Agreement zu einem seiner Services erzeugt
wurde. Weiterhin muss der QoS-Proxy das WSAG4J-System darüber informieren, wenn
ein SLA nicht eingehalten werden konnte. Die vorhandene Web-Service-Schnittstelle
sieht diese Operationen nicht vor.
Ein Ansatz für die Implementierung der SLM-Komponente in die Konfigurations-Komponente ist die Java Remote Method Invocation (RMI). RMI realisiert eine Art von
Remote-Procedure-Call für Java-Objekte. In Abbildung 3.14 ist die RMI-Architektur
[Sun04] dargestellt. Die Architektur besteht aus den drei Komponenten Client, Server
und Registry. In der Registry werden im Server lebende Objekte registriert und mit einem
eindeutigem Namen versehen. Der Client erhält durch eine Anfrage an die Registry eine
Objekt-Referenz und kann Methoden der Objekte im Server aufrufen. WSAG4J würde
den RMI Server und der Proxy den RMI Client implementieren.
Die Nutzung von RMI für die SLM-Komponente erlaubt es, die einzelnen Komponenten
klar voneinander zu trennen. JMX wird eingesetzt, um die Ergebnisse der Instrumentierung nach außen darzustellen und den Proxy zu parametrisieren. Web Services wer-
65
3.4. Monitoring und Konfiguration
Kapitel 3. Analyse
Abbildung 3.14: Remote-Method-Invocation-Architektur (nach [Sun04])
den von WSAG4J zur Kommunikation mit dem Client genutzt. Die Kommunikation der
SLM-Komponente mit WSAG4J über RMI, vervollständigt die Trennung der einzelnen
Aufgabenbereiche.
3.4.4
Zusammenfassung
Kenngrößen erlauben es, das Zeitverhalten des QoS-Proxys zu beurteilen. Die MonitoringKomponente ist verantwortlich für das Sammeln von Messgrößen, aus denen sich die
Kenngrößen bestimmen lassen. Einstellungen vor und zur Laufzeit erfolgen über die Konfigurationskomponente. Neben der Konfiguration der Queueing-Strategie, ist die Konfigurationskomponente für die Bestimmung der SLAs eines Services verantwortlich.
Die Kommunikation zwischen Konfigurationskomponente und einem WS-AgreementServer erfolgt auf Basis von RMI. Über JMX wird es einem Anwender ermöglicht, zur
Laufzeit Statistiken aus der Monitoring-Komponente abzurufen und Parameter in der
Management-Komponente zu setzen. Eine XML-Datei-Schnittstelle stellt optional initial
Informationen in Form von SLAs eines Service zur Verfügung.
66
Kapitel 4
Design
Das Kapitel stellt einen konkreten Entwurf für den generischen QoS-Proxy für SOADienste vor. Dabei werden die in Kapitel 3 getroffenen Entscheidungen berücksichtigt
und dienen als Grundlage für den Entwurf.
4.1
Architekturüberblick
AgreementDatei
WS-Agreement
WS
RMI
Business Layer
SCA
Proxy
RMI
JMX
Monitoring
WS
JMX XML
Konfiguration
Queueing
...
Integration
Tuscany
Service Layer
JMX
Schnittstelle (JMX, RMI, WS, XML)
Dienstgüteklasse
Client
Web Service
Kommunikation
Wire (Verknüpfung)
Abbildung 4.1: Grobarchitektur des QoS-Proxy
67
Konfigurationsdatei
4.1. Architekturüberblick
Kapitel 4. Design
Abbildung 4.1 fasst die einzelnen Komponenten des QoS-Proxys zur Grobarchitektur zusammen und verdeutlicht die für die einzelnen Schnittstellen eingesetzten Technologien.
Die Architektur unterscheidet zwischen einem Business und einem Service Layer. Innerhalb der Abbildung heben schwarze Pfeile mögliche Kommunikationswege hervor.
Der QoS-Proxy erzeugt aus ausgewählten Services einer SCA-Anwendung Services, die
unterschiedliche Dienstgüteklassen repräsentieren. Dienstgüteklassen werden im Diagramm durch die bereits aus Abschnitt 2.2.2 bekannten grünen Pfeilspitzsymbole dargestellt. Eine Dienstgüteklasse entspricht einer Web-Service-Schnittstelle. Die Dienstgüteklassen unterscheiden sich in ihrer Leistungsfähigkeit. Eine Dienstgüteklasse mit kritischen Anforderungen hat eine höhere Priorität als eine Dienstgüteklasse mit niedrigeren
Anforderungen.
Auf der Ebene des Business Layers vereinbart ein Client mit WS-Agreement ein oder
mehrere Agreements zu einem Service. Grundlage der Agreements sind die vom QoSProxy erzeugten Agreement Templates, in denen Zusicherungen bezüglich Durchsatz und Antwortzeit eines Services gemacht werden. Die Kommunikation zwischen dem
Client und WS-Agreement erfolgt auf Basis von Web Services, die zwischen einem WSAgreement und dem QoS-Proxy erfolgt auf Basis von RMI.
Das Agreement beinhaltet eine URL zu dem vom QoS-Proxy bereitgestellten Service. Der
Client aus dem Business Layer reicht die URL an den Client im Service Layer weiter.
Unter Umständen handelt sich dabei um den gleichen Client. Der Client erzeugt WebService-Anfragen, die vom Proxy unter Berücksichtigung von Agreements umgesetzt
werden.
Grundlage der Grobarchitektur ist die Entscheidung zur Implementierung einer eigenen
Policy-Erweiterung für Tuscany (vergleiche 3.2.2). Die Grobarchitektur sieht die folgenden Subsysteme vor:
• Queueing
Das Queueing-Subsystem ist für das Queueing eingehender Aufträge in Form
von Web-Service-Anfragen verantwortlich. Das Subsystem definiert verschiedene
Queueing-Strategien.
• Monitoring
Das Monitoring-Subsystem ermöglicht es, den QoS-Proxy während der Laufzeit zu
beobachten. Zu den weiteren Aufgaben des Monitoring-Subsystems gehören das
Sammeln von Messwerten der einzelnen Subsysteme und die Erzeug von Statistiken.
68
Kapitel 4. Design
4.2. Queueing-Subsystem
• WS-Agreement
Das WS-Agreement-Subsystem erlaubt die Verwenndung von Agreements und
realisiert die Kommunikation zum QoS-Proxy. Dabei definiert das entsprechende
Protokoll die notwendigen Schritte zum Registrieren und Erzeugen von Agreement
Templates und einen Benachrichtigungsmechanismus für den QoS-Proxy.
• Konfiguration
Das Konfigurationssubsystem ermöglicht es, den QoS-Proxy beim Start und zur
Laufzeit zu konfigurieren. Über das Konfigurationssubsystem sollen verschiedene
Parameter des Proxys angepasst werden können. Dazu definiert die Konfigurationskomponente den Aufbau einer XML-Konfigurationsdatei, in der initiale Konfigurationswerte für den Proxy festgelegt werden.
• Integration
Die Aufgabe des Integrationssubsystems ist die Einbindung des QoS-Proxys in die
Tuscany-Architektur.
• Proxy
Das Proxy-Subystem ist eine Art Hülle für die angegebenen Subsysteme und realisiert die Anpassung einer bestehende SCA-Anwendung.
In den folgenden Abschnitten 4.2 bis 4.7 werden die Detailentwürfe der Subsysteme vorgestellt. Abschnitt 4.7 behandelt den Zusammenhang zwischen den einzelnen Subsystemen. Die Zusammenfassung in Abschnitt 4.8 beschreibt die Zusammenarbeit der einzelnen Subsysteme anhand eines Anwendungsfalls aus Kapitel 3.1.
4.2
4.2.1
Queueing-Subsystem
Überblick
Abbildung 4.2 präsentiert einen Überblick über alle am Queueing-Subsystem beteiligten Klassen. Das Queueing-Subsystem stellt die Queueing-Strategien und die dazu benötigten Datenstrukturen bereit. Jede Queueing-Strategie erbt von der abstrakten Klasse Strategy und stellt eine eigene Implementierung der abstrakten Klasse
ItemList zur Verwaltung der Aufträge zur Verfügung. Die Klasse ItemList besitzt
ein QueueStatistic-Objekt, in dem Statistiken zur Queue festgehalten werden. Die
69
4.2. Queueing-Subsystem
Kapitel 4. Design
tatsächliche Queue wird durch eine ArrayList aus Objekten vom Typ Queue realisiert. Dabei besitzt wiederum eine Queue eine ArrayList von Item-Objekten, die
die Aufträge im Queueing-Subsystem repräsentieren. Jede Queueing-Strategie erbt als At-
LeakyBucket
1
Thread
#bucket
1
WeightedFairQueueing
Strategy
ClassBasedQueueing
HierarchicalTokenBucket
1
1
1
1 - queue
1
WeightedFairQueueingItemList
-queue
ClassBasedQueueingItemList
-queue
1
HierarchicalTokenBucketItemList
ItemList
Queue
<<bind>>
1
1
1
-queue
1
1
-statistic
QueueStatistic
E > Element
ArrayList
-list
1
Item
<<bind>>
ItemStatistic
-statistic
1
1
Abbildung 4.2: Klassendiagramm: Überblick Queueing-Subsystem
tribut die Implementierung des Leaky-Bucket-Algorithmus die Klasse LeakyBucket.
Sowohl die einzelnen Queueing-Strategien als auch die Realisierung des Leaky-BucketAlgorithmus implementieren einen Thread.
70
Kapitel 4. Design
4.2.2
4.2. Queueing-Subsystem
Beschreibung der Klassen
Item und ItemStatistic
Jede Instanz der Klasse Item verwaltet genau einen Auftrag. In der Klasse wird ein Objekt vom Typ Thread abgelegt. Dabei entspricht das Thread-Objekt einem InterceptorThread der zu implementierenden Policy-Erweiterung. Zusätzlich führt die Klasse die
Statistik zu dem Thread in einem Objekt vom Typ ItemStatistic mit.
Abbildung 4.3 repräsentiert die Klasse Item und ItemStatistic. Zusammen mit
der Referenz auf den Thread werden eine Reihe von weiteren Parametern in der Klasse
Item gespeichert. Zu den Parametern zählt der Name, die Priorität und die Dienstgüteklasse des Services. Die Klasse Item stellt get- und set-Methoden für die Parameter
zur Verfügung. Um den abgelegten Thread in den Zustand Wartend oder Aktiv versetzen
Item
ItemStatistic
<<constructor>>+Item()
+getPriority() : int
+setPriority( prio : int ) : void
+getService() : String
+getQueueingClass() : String
+suspend() : void
+resume() : void
+getStatistics() : ItemStatistic
+setService( ser : String ) : void
+setQueueingClass( queueing : String ) : void
+setThread( thr : Thread ) : void
1
1
-statistic
+setRequestTime() : void
+setExposureTime() : void
+setResponseTimeOnRequest() : void
+setResponseTimeAfterRequest() : void
+getExposureTime() : double
+getResponseTime() : double
+getTotalRequestTime() : double
+toString() : String
+setService( name : String ) : void
+getService() : String
Abbildung 4.3: Klassendiagramm: Item
zu können, stehen die Methoden suspend() und resume() zur Verfügung.
In der Klasse ItemStatistic werden die in Abschnitt 3.4.2.2 vorgestellten Messgrößen gespeichert, um später Kenngrößen wie Verweilzeit, Bearbeitungszeit oder Wartezeit
bestimmen zu können. Über die Methode getStatistic() in der Klasse Item wird
das ItemStatistic-Objekt eines Interceptor-Threads zurückgegeben.
Queue
Die Klasse Queue repräsentiert eine Queue für Item-Objekte. In der Klasse werden die
Item-Objekte in einer Listenstruktur abgelegt und verwaltet. Dabei besitzt jede Queue
optional eine Priorität und ein Gewicht. Abbildung 4.4 zeigt das Klassendiagramm für die
71
4.2. Queueing-Subsystem
Kapitel 4. Design
Queue
<<constructor>>+Queue( p : int, w : int )
+add( item : Item ) : boolean{guarded}
+size() : int{guarded}
+update( weight : int, priority : int ) : void{guarded}
+get( index : int ) : Item{guarded}
+remove( index : int ) : Item{guarded}
+getPriority() : int{guarded}
+getWeight() : int{guarded}
Abbildung 4.4: Klassendiagramm: Queue
Klasse Queue. Die Methode add() fügt ein Item-Objekt zur Liste hinzu, remove()
entfernt ein Item-Objekt. Die Methode size() gibt die Anzahl der Item-Objekte in
der Queue zurück. Über die Funktion update() können das Gewicht und die Priorität
einer Queue aktualisiert werden. Die Methode remove() entnimmt ein Item-Objekt.
Mit den Methode getPriority() und getWeight() kann die Priorität bzw. das
Gewicht einer Queue bestimmt werden.
QueueStatistic
Die Klasse QueueStatistic sammelt die Statistiken zu einer Queueing-Strategie. Abbildung 4.5 stellt das Klassendiagramm für die Klasse QueueStatistic vor. Mit der
Methode addQueueData() werden die Statistiken einer Queue hinzugefügt. Parameter der Funktion ist die zugehörige Queueing-Strategie, die Nummer, die Priorität, das
Gewicht, die Anzahl der Aufträge in der Queue und die Anzahl der bereits abgearbeiten Aufträge der Queue. Über die Methode addItemData() werden Daten zur der
Queueing-Strategie, von der das Item-Objekt bearbeitet wurde, übergeben. Dazu zählt
die Nummer der Queue, der Service und die Verweilzeit in der Queue. Mit der Methode
getItemData() werden die Statistiken der Item-Objekte zurückgegeben. Die Statistiken, aufgeschlüsselt nach Queueing-Strategie und Queue, werden über die Methode
getQueueData() bestimmt. Die Methode getCombinedData() gibt die gesammelten Daten zusammengefasst zurück.
ItemList
Mit Hilfe der abstrakten Klasse ItemList wird eine Liste definiert, in der Aufträge
einer Queueing-Strategie abgelegt werden können. Die Klasse ItemList stellt bekannte Operationen auf Listen zur Verfügung. Abbildung 4.6 stellt die Klasse ItemList
72
Kapitel 4. Design
4.2. Queueing-Subsystem
QueueStatistic
+addItemData( strategy : String, queue : String, service : String, duration : long )
+addQueueData( strategy : String, queue : String, priority : int, weight : int, current : int, done : int )
+getItemData() : String[]
+getQueueData() : String[]
+getCombinedData() : String[]
Abbildung 4.5: Klassendiagramm: QueueStatistic
vor. Zu den definierten Methoden der Klasse gehören die Methoden get(), add() und
remove(). Die Methode get() gibt ein entsprechendes Element zurück. Mit Hilfe der
Methode add() werden Aufträge hinzugefügt. Über die Methode remove() werden
Aufträge entfernt.
ItemList
+add( item : Item ) : boolean
+remove( index : int, queue : int ) : Item
+size( queue : int ) : int
+get( index : int, queue : int ) : Item
Abbildung 4.6: Klassendiagramm: ItemList
Strategy
In der abstrakten Klasse Strategy werden die grundlegenden Operationen einer
Queueing-Strategie beschrieben. Abbildung 4.7 stellt das zugehörige Klassendiagramm
vor. Zu den grundlegenden Operationen gehören die Methoden add(), run(), schedule() und requeue(). Über die Methode add() wird ein Auftrag an die QueueingStrategie übergeben. Die Klasse erweitert die Thread-Klasse und überschreibt die Methode run(). Innerhalb der Methode wird die schedule()-Methode aufgerufen, welche die tatsächliche Queueing-Strategie realisiert.
Mit Hilfe der Methode requeue() werden die Aufträge, die sich in der Queue einer Queueing-Strategie befinden, an die Queue einer neuen Queueing-Strategie übergeben. Die Methode soll das Wechseln der Queueing-Strategie während des laufenden
Betriebs erleichtern. Da jede Queueing-Strategie als Thread implementiert wird, müssen bei der Implementierung bekannte Nebenläufigkeitskonzepte betrachtet werden. Eine
73
4.2. Queueing-Subsystem
Kapitel 4. Design
Strategy
<<constructor>>+Strategy( name : String )
+add( item : Item ) : void
+schedule() : void
+dumpActiveThreads() : void
+run() : void
+getStrategyName() : String
+requeue( strategy : Strategy ) : void
+getLeakyBucket() : LeakyBucket
Abbildung 4.7: Klassendiagramm: Strategy
Queueing-Strategie sollte nur wirklich dann aktiv sein, wenn Aufträge abgearbeitet werden. Realisiert werden kann dies über eine Semaphore in der entsprechenden ItemListImplementierung, deren Wert sich mit jedem hinzugefügten Auftrag erhöht und jedem
entnommen Auftrag verringert. Erreicht die Semaphore den Wert Null und versucht der
Thread den Wert der Semaphore zu senken, so blockiert der Thread an dem Aufruf. Der
Thread wird erst dann wieder aktiv wenn Aufträge in die ItemList-Implementierung
abgelegt werden.
LeakyBucket
Der Leaky-Bucket-Algorithmus (vergleiche 2.3.2.5) ist unter anderem verantwortlich
für die Umsetzung von Durchsatzanforderungen. Realisiert wird der Leaky-BucketAlgorithmus durch die Klasse LeakyBucket. Jede Queueing-Strategie besitzt ein
Objekt vom Typ LeakyBucket. Die Klasse definiert verschiedene get- und setMethoden für die Parameter des Algorithmus. Parameter des Algorithmus sind die Erzeugungsrate der Tokens, die Größe des Buckets und die Anzahl der aktuell verfügbaren Tokens. Abbildung 4.8 stellt das Klassendiagramm vor. Für jeden Auftrag, den ei-
LeakyBucket
<<constructor>>+LeakyBucket( s : int, i : int, r : long, n : int )
+take() : boolean
+getSize() : int{guarded}
+>+getAvailableTokens() : int{guarded}
+getRate() : double{guarded}
+setRate( rate : double ) : void{guarded}
+getNumber() : int{guarded}
+setNumber( n : int ) : void{guarded}
Abbildung 4.8: Klassendiagramm: LeakyBucket
74
Kapitel 4. Design
4.2. Queueing-Subsystem
ne Queueing-Strategie bearbeitet, wird ein Token aus dem Bucket des Leaky-BucketAlgorithmus entnommen. Sollten mehr Aufträge in den einzelnen Queues vorliegen als
Tokens verfügbar sind, so wartet die Queueing-Strategie nicht aktiv darauf, dass Tokens
verfügbar sind, sondern es werden entsprechende Datenstrukturen, wie sie sich beispielsweise in den Concurrency Utilities der Java API befinden, vorgesehen. Der Bucket der
Klasse LeakyBucket kann beispielsweise als BlockingQueue implementiert werden.
4.2.3
Beispiel: Weighted-Fair-Queueing-Algorithmus
Der Weighted-Fair-Queueing-Algorithmus wird durch die Klasse WeightedFairQueueing implementiert. Aufträge in Form von Item-Objekten legt die Queueing-Strategie
in einem Objekt der Klasse WeigtedFairQueueingItemList ab. Abbildung 4.9
stellt das Klassendiagramm der beteiligten Klassen vor. Der Konstruktor der Klasse
WeightedFairQueueingItemList
<<constructor>>+WeightedFairQueueingItemList( weight : int, divider : int )
+add( item : Item ) : boolean{guarded}
+remove( index : int, queue : int ) : Item
+size( queue : int ) : int{guarded}
+totalSize() : int{guarded}
+get( index : int, queue : int ) : Item{guarded}
+createQueue( priority : int ) : boolean{guarded}
+getWeightFromQueue( queue : int ) : int{guarded}
+getMaximumWeight() : int{guarded}
+available() : boolean
+dumpQueues() : void
1
-queues
1
WeightedFairQueueing
<<constructor>>+WeightedFairQueueing( bucket : LeakyBucket, divider : int, maximumWeight : int )
+schedule() : void
+run() : void
+add( item : Item ) : void
+getStrategyName() : String
+requeue( strategy : Strategy ) : void
+getLeakyBucket() : LeakyBucket{guarded}
Abbildung 4.9: Klassendiagramm: WeightedFairQueueing und WeightedFairQueueingItemList
WeightedFairQueueingItemList erhält als Parameter das maximal verfügbare
Gewicht und den Divisor zur Bestimmung der Gewichte. Die Klasse ist eine AdapterKlasse, die Operationen auf Objekten vom Typ Queue erlaubt. Eine WeightedFair-
75
4.2. Queueing-Subsystem
Kapitel 4. Design
QueueingItemList kann dabei aus n-Queue-Objekten bestehen, wobei die QueueObjekte in einer ArrayList abgelegt werden.
Über die Methode add() wird ein Item-Objekt hinzugefügt. Mit der Methode remove()
wird ein entsprechendes Item-Objekt aus der Queue entfernt. Die Methode size() gibt
die Größe einer Queue in der WeightedFairQueueingItemList zurück. Die Anzahl der Queues der WeightedFairQueueingItemList kann über die Methode
getTotalSize() ermittelt werden. Über die Methode get() erhält man ein ItemObjekt, ohne es aus einer Queue zu entfernen. Mit der Methode createQueue() wird
eine neue Queue in der Klasse WeightedFairQueueing erzeugt.
Ablauf zur Laufzeit
Abbildung 4.10 stellt das Sequenzdiagramm zur Bearbeitung eines Auftrags durch die
Queueing-Strategie Weighted Fair Queueing vor. Der Auftrag wird in Form eines ItemObjektes an ein WeightedFairQueueing-Objekt mit der Methode add() übergeben.
Der Algorithmus erhält über die Methode getThread() eine Referenz auf das in der
Klasse Item abgelegte Thread-Objekt und versetzt den Thread in den Zustand Wartend.
Das WeightedFairQueueing-Objekt fügt das Objekt mit der Methode add() in
seine WeightedFairQueueingItemList ein.
In der run()-Methode der Klasse WeightedFairQueueing wird die Methode
schedule() aufgerufen, die den Algorithmus der Queueing-Strategie implementiert.
Für jede Queue im WeightedFairQueueingItemList-Objekt prüft der Algorithmus, ob Aufträge in der Queue abgelegt sind. Falls das der Fall ist, versucht der Algorithmus, die Aufträge zu bearbeiten. Das WeightedFairQueueing-Objekt bearbeitet maximal
soviele Aufträge, wie das Gewicht der Queue ist.
Für jeden Auftrag versucht die Methode mit dem Aufruf von take() einen Token aus
dem Bucket des Leaky-Bucket-Algorithmus zu entnehmen. Falls ein Token verfügbar ist,
wird ein Item-Objekt aus der Queue entnommen. Über die Methode getThread()
wird eine Referenz auf das zugehörige Thread-Objekt im Item-Objekt zurückgegeben.
Der Thread wird in den Zustand Aktiv gesetzt.
76
Kapitel 4. Design
: Item
4.3. Monitoring-Subsystem
: WeightedFairQueueing
: WeightedFairQueueingItemList
: Queue
: LeakyBucket
1: add()
2: getThread()
3: add()
4: run()
5: add()
6: schedule()
loop
[for every queue in the weightedfairqueueingitemlist]
loop
[for every item in the queue and weight is
available for the queue]
7: take()
alt
[if take was successful]
8: remove()
9: getThread()
[else]
Abbildung 4.10: Sequenzdiagramm: Bearbeitung eines Interceptors durch eine QueueingStrategie
4.3
4.3.1
Monitoring-Subsystem
Überblick
Zu den Aufgaben des Monitoring-Subsystem gehört das Sammeln und Erzeugen von
Statistiken der einzelnen Subsysteme. Dabei werden die erzeugten Statistiken über JMX
Management-Anwendungen zur Verfügung gestellt.
4.3.2
Beschreibung der Klasse
Das Statistiksubsystem besteht aus der Klasse Statistic und dem Interface StatisticMBean. Das Interface definiert die Methoden die über JMX bereitgestellt werden.
Die Klasse Statistic implementiert das Interface StatisticMBean. Abbildung
4.11 stellt das Klassendiagramm vor.
77
4.3. Monitoring-Subsystem
Kapitel 4. Design
StatisticMBean
+getItemData() : String"[]"
+getItemMinData() : String"[]"
+getItemMaxData() : String"[]"
+getItemAverageData() : String"[]"
+getItemStandardDeviationData() : String"[]"
+setInterval( start : int, stop : int ) : void
+getItemDataSize() : int
+getServices() : String"[]"
+getServiceLevelAgreementSuccessful() : int
+getServiceLevelAgreementFailed() : int
+resetInterval() : void
+setFilter( filter : String ) : void
+getFilter() : String
+resetFilter() : void
+setItemDataCVSFileName( file : String ) : void
+getItemDataCVSFileName() : String
+exportItemDataToCVSFile() : void
+getItemsInQueue() : int
+getQueueData() : String"[]"
+getQueueItemData() : String"[]"
Statistic
<<constructor>>+Statistic()
+getItemData() : String"[]"
+getItemMinData() : String"[]"
+getItemMaxData() : String"[]"
+getItemAverageData() : String"[]"
+getItemStandardDeviationData() : String"[]"
+setInterval( startInterval : int, stopInterval : int ) : void
+getItemDataSize() : int
+getServices() : String"[]"
+getServiceLevelAgreementSuccessful() : int
+getServiceLevelAgreementFailed() : int
+resetInterval() : void
+setFilter( filter : String ) : void
+getFilter() : String
+resetFilter() : void
+setItemDataCVSFileName( file : String ) : void
+getItemDataCVSFileName() : String
+exportItemDataToCVSFile() : void
+getItemsInQueue() : int
+updateQueueData() : void
+getQueueData() : String"[]"
+getQueueItemData() : String"[]"
+addItemStatistic( statistic : ItemStatistic ) : void
+addQueueStatistic( stat : QueueStatistic ) : void
+addServiceLevelAgreementFailed() : void
+addServiceLevelAgreementSuccessful() : void
Abbildung 4.11: Klassendiagramm: Statistic
Der Erfolg des QoS-Proxys wird in der Einhaltung von Service Level Agreements gemessen. Ein Service Level Agreement ist üblicherweise über einen relativ langen Zeitraum
gültig. Um eine mittelfristige Bewertung des QoS-Proxys zu erleichtern, können die in
3.4.2 vorgestellten Mess- und Kenngrößen zur Leistungsbewertung herangezogen werden. Der QoS-Proxy wird an fünf Punkten instrumentiert, um die entsprechenden Messwerte bestimmen zu können.
Der erste Instrumentierungspunkt befindet sich kurz nach dem Aufruf der invoke()Methode des Interceptors. Weitere Instrumentierungspunkte befinden sich vor dem Einfügen in die Queue und nach dem Entfernen aus der Queue. Die letzten beiden Messungen
werden kurz vor dem tatsächlichen Absetzen des Web-Service-Aufruf und kurz nach der
Antwort des Web Services vorgenommen.
Die Statistik-Objekte des Queueing- und Integrationssubsystem werden über die Methoden addQueueStatistic() und addPolicyStatistic() eingefügt. Die
Methode getPolicyData() gibt alle gesammelten Datensätze des Integrationssubystems zurück. Aus den gesammelten Datensätzen werden die Minimal-, Maximalund Durchschnittswerte sowie die Standardabweichung bestimmt. Über die Methode setInterval() lässt sich die Anzahl der Datensätze einschränken. Das Interval kann mit der Methode resetInterval() zurückgesetzt werden. Die Methode
78
Kapitel 4. Design
4.3. Monitoring-Subsystem
getPolicyDataSize() gibt die Anzahl der Datensätze des Integrationssubystems
zurück.
Die Methode getServices() gibt eine Liste aller vom QoS-Proxy behandelten Services zurück. Sollte ein SLA während der Lebenszeit des Proxys terminiert werden, so
wird in Abhängigkeit von der Art der Terminierung mit der Methode addSuccessfulServiceLevelAgreement() oder addFailedServiceLevelAgreement()
ein entsprechender Zähler erhöht. Ein Grund für ein erfolgreiches SLA ist das Beenden
durch das Erreichen des Ablaufdatums des SLA. Während der Lebenszeit des SLAs sind
keine Verletzungen des SLAs eingetreten, die zu einer Terminierung des SLAs geführt
hätten. Die Methode addSuccessfulServiceLevelAgreement() wird aufgerufen. Wird ein SLA durch den Client terminiert, weil Service Level Objectives nicht eingehalten wurden, so wird die Methode addFailedServiceLevelAgreement()
aufgerufen. Über die Methode getSuccesfulServiceLevelAgreement() und
getFailedServiceLevelAgreement() wird die Anzahl der erfolgreichen, beziehungsweise der nicht erfolgreichen, Service Level Agreements zurückgegeben.
Über die Methode setFilter() kann auf einen Web-Service eingeschränkt werden.
Der Filter wirkt sich auf alle Methoden aus, auf die der Filter anwendbar ist. Beispielsweise werden beim Aufruf der Methode getPolicyData() nur noch die Datensätze zurückgegeben, die auf den Filter zutreffen. Die Methode getFilter() gibt den
aktuell gesetzten Filter zurück. Der Filter kann über die Methode resetFilter()
zurückgesetzt werden, alternativ kann auch ein leerer Filter gesetzt werden. Um das
Auswerten der Statistiken des Integrationssubsystem zu erleichtern, kann mit der Methode setPolicyDataCSVFileName() eine Datei angegeben werden, in der die
gesammelten Daten des Integrationssubsystem in eine CSV-Datei mit dem Aufruf
der Methode exportPolicyDataToCSV() geschrieben werden. Über die Methode
getPolicyDataCSVFileName() wird der Name der CSV-Datei zurückgegeben.
Mit Hilfe der Methode getQueueData() werden die gesammelten Datensätze des
Queueing-Subsystems zurückgegeben. Über die Methoden getQueueMinData(),
getQueueMaxData(), getQueueAverageData() werden aus den gesammelten
Datensätzen die Minimal-, Maximal- sowie die Durchschnittswerte bestimmt.
79
4.4. WS-Agreement-Subsystem
4.4
4.4.1
Kapitel 4. Design
WS-Agreement-Subsystem
Überblick
Das WS-Agreement-Subsystem definiert die Kommunikation und das Protokoll zwischen einem WS-Agreement-System und dem Konfigurationssubsystem. Das Konfigurationssubsystem erzeugt auf Grundlage von Angaben zur Leistungsfähigkeit eines
Services verschiedene Agreement Templates und registriert sie an einem WSAgreement-System. Ein Agreement Template repräsentiert eine Dienstgüteklasse,
wobei es mehrere unterschiedliche Agreement Templates zu einer Dienstgüteklasse geben kann. Das WS-Agreement-System bietet die unterschiedlichen Agreement
Templates einem Client an. Der Client erzeugt auf Grundlage der Agreement
Templates ein Agreement Offer. Das Agreement Offer wird vom WSAgreement-System auf gültige Parameter hin überprüft. Sind die Parameter im Agreement Offer gültig, so erzeugt das WS-Agreement-System ein Agreement mit dem
Client (vergleiche Kapitel 2.1.2).
Unter Umständen ist ein WS-Agreement-System nicht immer verfügbar oder das Erzeugen von Service Level Agreements soll über einen andere Software erfolgen. Für diesen
Fall wird eine Schnittstelle auf Basis einer XML-Datei es erlauben, bereits abgeschlossene Service Level Agreements dem Konfigurationssubsystem zur Verfügung zu stellen.
Die Kommunikation zwischen dem WS-Agreement-System und dem Konfigurationssubsystem erfolgt auf Basis von RMI. Das Erzeugen der Agreement Templates auf
Grundlage von Angaben zur Leistungsfähigkeit des Services ist Aufgabe des Konfigurationssubsystems. Im Interface ICallback werden die Operationen definiert, die das WSAgreement-System am QoS-Proxy aufruft. Abbildung 4.12 zeigt die für die Kommunikation relevanten Klassen. Das Interface IServiceLevelManagement definiert die
Operationen, die der QoS-Proxy am WS-Agreement-System aufruft. Zusammen mit dem
Interface ICallback definiert das Interface das Kommunikationsprotokoll zwischen
einem WS-Agreement-System und dem QoS-Proxy. Die Klasse AgreementManager
implementiert das Interface IServiceLevelManagement.
80
Kapitel 4. Design
4.5. Konfigurationssubsystem
IServiceLevelManagement
+report( information : String[] ) : void
+register( callback : ICallback ) : void
+createTemplate( template : String[] ) : void
AgreementManager
ICallback
1
+createTemplate( template : String[] ) : void
+report( information : String[] ) : void
+register( callback : ICallback ) : void
1
+notify( message : String ) : void
-callback +notifyAgreement( agreement : String[] ) : void
+notifyTermination( id : String ) : void
Abbildung 4.12: Klassendiagramm: ICallback, IServiceLevelManagement, AgreementManager
4.4.2
Beschreibung der Klasse
AgreementManager
Die Klasse AgreementManager implementiert die durch das Interface IServiceLevelManagement bereitgestellten Methoden. Über den Aufruf der Methode register() wird ein Callback-Objekt im WS-Agreement-System registriert. Die Klasse
AgreementManager ist daraufhin in der Lage, die Methoden des Objektes aufzurufen und dem QoS-Proxy mitzuteilen, ob beispielsweise ein Agreement Template
erfolgreich registriert wurde. Erzeugt werden Agreement Templates über den Aufruf der Methode createTemplate(). Kann der QoS-Proxy ein Agreement nicht
einhalten, so meldet der Manager mit Hilfe der Methode report() die Verletzung des
zugehörigen Agreements.
4.5
4.5.1
Konfigurationssubsystem
Überblick
Abbildung 4.13 präsentiert einen Überblick über alle am Konfigurationssubsystem beteilitigen Klassen. Die Aufgaben des Konfigurationssubsystems umfassen die Konfiguration
des Proxys zum Zeitpunkt des Starts und während des Betriebes. Weiterhin bestimmt das
Subsystem die Service Level Agreements zu einem Service, die die zeitliche Anforderungen an das Queueing-Subsystem festlegen. Grundlage für die Bestimmung der Service
81
4.5. Konfigurationssubsystem
Kapitel 4. Design
ServiceLevelAgreementFile
Callback
1 -callback
-serviceLevelAgreementFile 1
1
1
-strategy
1
1
Manager
1
ConfigurationFile -configuration
ICallback
ManagerMBean
1
1
1
1
1
1
LeakyBucket
-bucket
1
-qos
key > Element
value > Element
HashMap
Strategy
ServiceLevelAgreementList
<<bind>>
ServiceClass
1
1
- list
E > Element
ArrayList
<<bind>>
String
<<bind>>
ServiceLevelAgreement
Abbildung 4.13: Überblick über das Konfigurationssubsystem
Level Agreements bildet die in Abschnitt 4.4 beschriebene Kommunikation mit einem
WS-Agreement-System.
Die Klasse Manager besitzt Referenzen zu anderen Teilen der Architektur des QoSProxys. Der Manager bietet vereinfachte und einheitliche Schnittstellen zu anderen Subsystemen und orientiert sich damit am Fassaden-Entwurfsmuster [GHJ95]. Die Klassen
ConfigurationFile und ServiceLevelAgreementFile sind Laufzeitrepräsentierung der entsprechenden Konfigurationsdateien. Die Klasse ConfigurationFile verwaltet ServiceClass-Objekte in einer HashMap der Schlüssel ein String
und Wert ein ServiceClass-Objekt ist. Aus einzelnen ServiceClass-Objekten
werden in der Klasse Manager verschiedene Agreement Templates erzeugt.
Gespeichert werden die ServiceLevelAgreementList die eine Liste zur Verwaltung von ServiceLevelAgreement-Objekten bereitstellt. Realisiert wird die
Klasse durch Operationen auf eine ArrayList von ServiceLevelAgreementObjekten. Neben den Java-Objektrepräsentierungen der Konfigurationsdateien verfügt der
Manager über Referenzen zum Queueing-Subsystem und stellt Verwaltungsoperationen
auf das Queueing-Subsystem zur Verfügung.
82
Kapitel 4. Design
4.5. Konfigurationssubsystem
4.5.2
Konfiguration des QoS-Proxys
4.5.2.1
Initialisierung
Die initiale Konfiguration des QoS-Proxys soll über eine XML-Datei erfolgen. Quellcode
4.1 stellt das XML-Schema für eine QoS-Proxy-Konfigurationsdatei vor.
1 <xml xmlns="http://www.osoa.org/xmlns/sca/1.0"
2 targetNamespace="http://tuscany.apache.org/xmlns/sca/1.0"
3 xmlns:sca="http://www.osoa.org/xmlns/sca/1.0"
4 xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
5 xmlns:xs="http://www.w3.org/2001/XMLSchema">
6
7 <hostName>xs:anyURI</hostName>
8 <loggingConfigurationFile>xs:string</loggingConfigurationFile>
9 <leakyBucket size="xs:int" initial="xs:int" rate="xs:float" token="xs:int"
10
unit="xs:string"/>
11 <weightedFairQueueing weight="xs:int"/>
12 <qosResponseTime service="xs:string" class="xs:string" max="xs:float"
13
unit="xs:float"/>
14 <qosThroughPut service="xs:string" class="xs:string" min="xs:float" max="xs:float"
15
unit="xs:string"/>
16 <rmiRegistry>xs:string</rmiRegistry> |
17 <slaFileLocation>xs:string</slaFileLocation>
18 <qosClass>xs:string</qosClass>
19
20 </xml>
Quellcode 4.1: QoS-Proxy-XML-Schema der Konfigurationsdatei
Das Element hostName in Zeile 7 definiert die URL zum Service, darauf aufbauend
werden später beim Erzeugen der Agreement Templates die URLs zu den einzelnen
Dienstgüteklassen eines Services erzeugt. Um interne Vorgänge im QoS-Proxy transparent mitverfolgen zu können, wird ein Logging-Mechanismus genutzt, der Log-Ausgaben
in eine Datei schreibt. Für das Logging stehen verschiedene Systeme zur Auswahl, wie
beispielsweise die Java Logging API [Ham01] oder log4j [Gup05]. Über das Element
loggingConfigurationFile in Zeile 8 kann der Name und Ort einer Konfigurationsdatei für das Logging zur Verfügung gestellt werden.
In der QoS-Proxy-Konfigurationsdatei werden initiale Parameter für die im QoS-Proxy
verwendeten Algorithmen festgelegt. In Zeile 9 wird das Element leakyBucket definiert. Parameter des Algorithmus sind die Attribute size, initial, rate, token und
unit. Das Attribut size legt die Größe des Buckets fest (vergleiche 2.3.2.5). Die Anzahl der initial verfügbaren Tokens wird mit dem Attribut initial definiert. Mit Hilfe
des Attributes rate und token wird die Erzeugungsrate und die Anzahl der pro Rate
83
4.5. Konfigurationssubsystem
Kapitel 4. Design
erzeugten Tokens bestimmt. Das Attribut unit definiert die Einheit, in der die Erzeugungsrate vorliegt.
Das Element weightedFairQueueing in Zeile 11 definiert die initialen Parameter für den Weighted-Fair-Queueing-Algorithmus (vergleiche 2.3.2.3). Das Atttribut
weight legt das maximale Gewicht des Algorithmus fest.
Aus den Elementen qosResponseTime und qosThroughPut werden die Agreement Templates für einen Service erzeugt. Die Attribute entsprechen den Attributen
der QoS-Erweiterung für WS-Agreement wie sie in 2.1.3 vorgestellt wurden.
Die Kommunikation mit dem WS-Agreement-System erfolgt auf Basis von RMI. Über
das Element rmiRegistry in Zeile 16 wird der Hostname der Registry gesetzt. Ist
das Element rmiRegistry nicht gesetzt, so müssen die SLAs in Form einer Datei
vorliegen. Der Ort und Name der Datei wird über das Element slaFileLocation in
Zeile 17 festgelegt.
Über das Element qosClass in Zeile 18 erhält der QoS-Proxy seine Dienstgüteklassen,
dabei wird pro Dienstgüteklasse eine Queue angelegt.
Quellcode 4.2 stellt das XML-Schema der Service-Level-Agreement-Datei vor. Eine
Service-Level-Agreement-Datei (SLA-Datei) besteht aus mindestens einem agreementElement. Das agreement-Element entspricht dabei einem Service Level Agreement.
Jedes agreement-Element verfügt über die Attribute name und service. Das Attribut name vergibt einen eindeutigen Namen für das Agreement. Das Attribut service
benennt den zum Agreement zugehörigen Service.
1 <xml version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" encoding="UTF-8">
2 {
3
<agreement name="xs:string" service="xs:string">
4
<client>xs:sequence</client>
5
<responseTime max="xs:float" unit="xs:string"/>
6
<throughput min="xs:float" max="xs:float" unit="xs:string"/>
7
<expiration>xs:any</expiration>
8
</agreement>
9 } +
10 <xml>
Quellcode 4.2: XML-Schema der Service-Level-Agreement-Datei
Das agreement-Element hat die folgenden vier Kindelemente: client-, responseTime-, throughput- und expiration. Im client-Element in Zeile 4 wird eine
Liste mit zulässigen Clients für das Agreement hinterlegt. Die Elemente responseTime
84
Kapitel 4. Design
4.5. Konfigurationssubsystem
und throughput in Zeile 5 und 6 entsprechen den Dienstgüteeigenschaften Antwortzeit und Durchsatz. Beide Elemente verfügen über die Attribute unit und max.
Das Attribut unit gibt eine Einheit an, in der die Werte vorliegen. Über das Attribut
max wird ein maximaler Wert definiert. Über das Attribut min, welches zusätzlich im
Element throughput definiert ist, wird ein minimaler Wert bestimmt. Das Element
expiration in Zeile 7 legt ein Ablaufdatum für das Agreement fest.
Realisiert wird die initiale Konfiguration des QoS-Proxys durch eine Klasse ConfigurationFileReader. Die Klasse liest sowohl die Konfigurationsdatei des QoS-Proxys
als auch eine optionale Service-Level-Agreement-Datei. Die Werte der Konfigurationsdatei werden in einem Objekt vom Typ ConfigurationFile abgelegt, die der SLADatei in einem Objekt vom Typ ServiceLevelAgreementFile.
4.5.2.2
Management
Der QoS-Proxy soll auch zur Laufzeit konfigurierbar sein. Um eine einheitliche Schnittstelle zur Verfügung zu stellen, nutzt das Konfigurationssubsystem wie auch das MonitoringSubsystem JMX.
Die JMX-Schnittstelle wird im Interface ManagerMBean definiert und durch die Klasse
Manager implementiert.
4.5.3
Beschreibung der Klassen
Callback
Die Klasse Callback implementiert die im Interface ICallback definierten Methoden. Über den Aufruf der Methode notify() wird dem QoS-Proxy eine allgemeine Nachricht mitgeteilt. Eine solche Nachricht könnte das erfolgreiche Registrieren von Agreement Templates am WS-Agreement-System oder Statusmitteilungen
sein. Die Methode notifyAgreement() wird aufgerufen, wenn das WS-AgreementSystem mit einem Client ein Agreement abgeschlossen hat. Wird ein Agreement beendet, so wird der QoS-Proxy über die Methode notifyTermination() darüber informiert.
85
4.5. Konfigurationssubsystem
Kapitel 4. Design
ICallback
+notify( message : String ) : void
+notifyAgreement( agreement : String[] ) : void
+notifyTermination( id : String ) : void
Callback
+notify( message : String ) : void
+notifyTermination( id : String )
+notifyAgreement( agreement : String[] ) : void
Abbildung 4.14: Klassendiagramm: ICallback und Callback
ServiceClass
Die Klasse ServiceClass repräsentiert die responseTime- und throughputElemente der Konfigurationsdatei als Java-Klasse. Üblicherweise werden ServiceClass-Objekte beim Einlesen der Konfigurationsdatei durch die Klasse ConfigurationFileReader erzeugt und in einer Liste in der Klasse ConfigurationFile
abgelegt. Abbildung 4.15 stellt das Klassendiagramm der Klasse vor. Die Klasse be-
ServiceClass
<<constructor>>+ServiceClass( s : String )
+getQosClass() : String
+setQosClass( c : String ) : void
+getServiceClass() : String
+setServiceClass( serviceClass : String ) : void
+getResponseTime() : double
+setResponseTime( responseTime : double ) : void
+getResponseTimeUnit() : String
+setResponseTimeUnit( responseTimeUnit : String ) : void
+getThroughputMinValue() : double
+setThroughputMinValue( throughputMinValue : double ) : void
+getThroughputMaxValue() : double
+setThroughputMaxValue( throughputMaxValue : double ) : void
+getThroughputUnit() : String
+setThroughputUnit( throughputUnit : String ) : void
+setUrl( host : String ) : void
+getUrl() : String
+getOperator() : String
+setOperator( operator : String ) : void
Abbildung 4.15: Klassendiagramm: ServiceClass
steht aus get- und set-Methoden der im vorherigen Abschnitt beschriebenen At-
86
Kapitel 4. Design
4.5. Konfigurationssubsystem
tribute der Elemente responseTime und throughput. Aus den verschiedenen
ServiceClass-Objekten werden in der Klasse Manager die Agreement Templates erzeugt und im WSAG4J-System registriert.
ServiceLevelAgreement
Die Klasse ServiceLevelAgreement repräsentiert ein Service Level Agreement in
der Architektur des QoS-Proxys. Abbildung 4.16 stellt das Klassendiagramm der Klasse
ServiceLevelAgreement vor. Die Klasse implementiert get- und set-Methoden
für die Elemente einer SLA-Datei. Dabei implementiert die Klasse zusätzlich die Methode
isValid(). Über diese Methode kann geprüft werden, ob das SLA noch gültig ist. Mit
der Methode setValid() kann der Status des SLAs aktualisiert werden.
ServiceLevelAgreement
<<constructor>>+ServiceLevelAgreement( agreement : String"[]" )
<<constructor>>+ServiceLevelAgreement( service : String )
+getService() : String
+getMaxResponseTime() : float
+getMinThroughput() : double
+getMaxThroughput() : double
+getClient() : String
+getResponseTimeUnit() : String
+getThroughputUnit() : String
+isValid() : boolean
+setValid( valid : boolean ) : void
+setService( service : String ) : void
+setResponseTime( maxResponseTime : float ) : void
+setMinThroughput( minThroughput : double ) : void
+setMaxThroughput( maxThroughput : double ) : void
+setClient( client : String ) : void
+setResponseTimeUnit( responseTimeUnit : String ) : void
+setThroughputUnit( throughputUnit : String ) : void
Abbildung 4.16: Klassendiagramm: ServiceLevelAgreement
ServiceLevelAgreementList
Die Klasse ServiceLevelAgreementList stellt Verwaltungsoperationen für eine Liste von ServiceLevelAgreement-Objekten zur Verfügung. Abbildung 4.17
stellt das Klassendiagramm vor. Mit der add()-Methode wird ein ServiceLevelAgreement an die Klasse übergeben. Über die Methode remove() wird ein ServiceLevelAgreement aus der Klasse entfernt. Ein bestimmtes ServiceLevel-
87
4.5. Konfigurationssubsystem
Kapitel 4. Design
Agreement erhält man mit der Methode get(). Die Methode size() gibt die Größe
der Liste zurück.
ServiceLevelAgreementList
<<constructor>>+ServiceLevelAgreementList()
+add( agreement : ServiceLevelAgreement ) : boolean{guarded}
+add( agreement : String"[]" ) : boolean{guarded}
+add( agreement : ServiceLevelAgreement"[]" ) : boolean{guarded}
+remove( service : String, client : String ) : boolean{guarded}
+getResponseTime( service : String, client : String ) : double
+get( service : String, client : String ) : ServiceLevelAgreement{guarded}
Abbildung 4.17: Klassendiagramm: ServiceLevelAgreementList
ServiceLevelAgreementFile
Die Klasse ServiceLevelAgreementFile repräsentiert die SLA-Datei als JavaKlasse und stellt verschiedene get- und set-Methoden für die Elemente der Datei zur
Verfügung. Abbildung 4.18 zeigt das Klassendiagramm der Klasse ServiceLevelAgreementFile.
ServiceLevelAgreementFile
+setService( service : String ) : void
+setResponseTime( service : String, max : float, unit : String ) : void
+setThroughPut( service : String, min : double, max : double, unit : String ) : void
+toArray() : ServiceLevelAgreement"[]"
Abbildung 4.18: Klassendiagramm: ServiceLevelAgreementFile
ConfigurationFile
Die Klasse ConfigurationFile ist die Repräsentierung der XML-Konfigurationsdatei
in Form einer Java-Klasse. Die Klasse besteht im wesentlichen aus get- und setMethoden der Attribute. Attribute der Klasse sind die Elemente der XML-Konfigurationsdatei.
Elemente, die beliebig oft auftreten können, werden in einer Liste in der Klasse verwaltet.
Abbildung 4.19 repräsentiert das zugehörige Klassendiagramm.
88
Kapitel 4. Design
4.5. Konfigurationssubsystem
ConfigurationFile
<<constructor>>+ConfigurationFile()
+getLoggingConfigurationFile() : String
+setLoggingConfigurationFile( file : String ) : void
+getQos() : HashMap<String, ServiceClass>
+setQosResponseTime( s : String, c : String, max : float, unit : String, operator : String ) : void
+setQosThroughPut( s : String, c : String, min : double, max : double, unit : String, operator : String ) : void
+getRmiRegistry() : String
+setRmiRegistry( registry : String ) : void
+getSlaFileLocation() : String
+setSlaFileLocation( location : String ) : void
+setHostname( host : String ) : void
+getHostname() : String
+setWeightedFairQueueing( w : int ) : void
+getWeightedFairQueueingWeight() : int
+setLeakyBucket( r : long, s : int, n : int, u : String ) : void
+getLeakyBucketRate() : long
+getLeakyBucketSize() : int
+getLeakyBucketNumber() : int
+getLeakyBucketUnit() : String
+setQosClass( list : String ) : void
+getQosClass() : String
Abbildung 4.19: Klassendiagramm: ConfigurationFile
ConfigurationFileReader
Die Klasse ConfigurationFileReader ist verantwortlich für das Lesen der Konfigurationsdateien des QoS-Proxy. Abbildung 4.20 stellt die Klasse vor. Eingelesen
werden die Konfigurationsdateien über einen XMLStreamReader [BEA03]. In einem ersten Schritt wird die Konfigurationsdatei des QoS-Proxy über die Methode
readConfigurationFile() eingelesen. Die Konfigurationsdatei liest initiale Konfigurationsparameter des QoS-Proxys aus. Sollte in der Konfigurationsdatei kein Wert für
eine rmiRegistry gesetzt sein, so muss ein Element slaFileLocation gesetzt
sein.
Ist das Element slaFileLocation gesetzt, so wird die SLA-Datei über den Aufruf der
Methode readSLAFile() eingelesen. Die Werte aus der SLA-Datei werden in Form
eines ServiceLevelAgreementFile-Objektes zurückgegeben.
ConfigurationFileReader
+readConfigurationFile( reader : XMLStreamReader ) : ConfigurationFile
+readSLAFile( reader : XMLStreamReader ) : ServiceLevelAgreementFile
Abbildung 4.20: Klassendiagramm: ConfigurationFile
89
4.5. Konfigurationssubsystem
Kapitel 4. Design
Manager
Die Klasse Manager implementiert die im Interface ManagerMBean definierten
Methoden. In Abbildung 4.21 ist das Klassendiagramm der Klasse dargestellt. Über
die Methode initialize() wird die RMI-Kommunikation initialisiert. Die Methode createTemplate() erzeugt Agreement Templates zu einem Service
und registriert sie an einem WS-Agreement-System mit dem Aufruf der Methode
registerTemplate().
Weiterhin stellt der Manager Methoden zum Wechseln der Queueing-Strategie zur
Verfügung. Mit der Methode getQueueingStrategies() werden die verfügbaren
Queueing-Strategien ermittelt. Über die Methode getActiveQueueingStrategy()
wird die aktive Queueing-Strategie bestimmt und mit dem Aufruf der Methode setActiveQueueingStrategy() wird auf eine andere verfügbare Queueing-Strategie gewechselt.
ManagerMBean
+getQueueingStrategies() : String"[]"
+getActiveQueueingStrategy() : String
+setActiveQueueingStrategy( index : String ) : void
+getBucketSize() : int
+getTokenRate() : double
+getAvailableToken() : int
+setAvailableToken( value : int ) : void
+getToken() : int
+setToken( newToken : int ) : void
+setTokenRate( time : double ) : void
+getLoggingConfigurationFileLocation() : String
+getServiceLevelAgreementFileLocation() : String
Manager
<<constructor>>+Manager()
<<setter>>+setConfigurationFile( file : ConfigurationFile ) : void
+initialize( hostname : String, name : String ) : void
+createTemplates( templates : HashMap<String, ServiceClass> ) : void
+getQueueingStrategies() : String"[]"
+getActiveQueueingStrategy() : String
+setActiveQueueingStrategy( index : String ) : void
+getBucketSize() : int
+getTokenRate() : double
+getAvailableToken() : int
+setAvailableToken( value : int ) : void
+getToken() : int
+setToken( newToken : int ) : void
+setTokenRate( time : double ) : void
+setAvailableQueueingStrategies( strategies : String"[]" ) : void
+getLoggingConfigurationFileLocation() : String
+getServiceLevelAgreementFileLocation() : String
+getServiceLevelAgreementList() : ServiceLevelAgreementList
Abbildung 4.21: Klassendiagramm: Manager
Zu den Methoden der Klasse Manager gehören Methoden zum Anpassen des Leaky-
90
Kapitel 4. Design
4.5. Konfigurationssubsystem
Bucket-Algorithmus. Mit der Methode getBucketSize() wird die Größe des Buckets
ermittelt. Die Methode getTokenRate() gibt die Erzeugungsrate der Tokens zurück.
Die Methode setTokenRate() setzt die Erzeugungsrate auf einen neuen Wert. Mit der
Methode getTokenRateNumber() wird die aktuelle Anzahl der pro Rate erzeugte
Tokens bestimmt, setTokenRateNumber() verändert die Anzahl der pro Rate erzeugte Tokens. Über die Methode getToken() kann die aktuell im Bucket befindliche
Anzahl von Tokens bestimmt werden. Mit der Methode setToken() wird die Anzahl
der Tokens neu gesetzt. Über eine Referenz auf die Klasse LeakyBucket kann der
Durchsatz des QoS-Proxys reguliert werden.
Die Methode setAvailableQueueingStrategies() informiert die Klasse Manager über die im QoS-Proxy registrierten Queueing-Strategien. Die Methode getServiceLevelAgreementList() gibt die ServiceLevelAgreeementList zurück.
4.5.4
Ablauf der Kommunikation zwischen dem WS-Agreementund dem Konfigurationssubsystem
Abbildung 4.22 stellt das Sequenzdiagramm zur Kommunikation mit WS-Agreement
vor. In einem ersten Schritt initialisiert der Manager in der Methode initialize()
die RMI-Kommunikation und registriert sein Callback-Objekt am WS-AgreementSystem. Für jeden Service in der composite-Datei einer SCA-Anwendung erstellt
der Manager mit der Methode createTemplates() aus den ServiceClassObjekten Agreement Templates, die im WS-Agreement-System über den Aufruf
der Methode createTemplate() registriert werden.
Wurde ein Agreement Template erfolgreich registriert, wird der Manager über das
zugehörige Callback-Objekt benachrichtigt. Wird ein Agreement zwischen einem
WS-Agreement-System erzeugt, so ruft die Klasse AgreementManager die Methode
notifyAgreement() auf.
In einem nächsten Schritt erhält die Klasse Callback über eine Referenz auf die
Klasse Manager die Möglichkeit auf die ServiceLevelAgreementList zuzugreifen. Über die Methode getServiceLevelAgreementList() erhält die Klasse Callback eine Referenz auf das ServiceLevelAgreementList-Attribut der
Klasse Manager und kann mit der Methode add() das neue Agreement hinzufügen.
Das Agreement bildet damit die Anforderungen an das Queueing im QoS-Proxy.
91
4.6. Integrationssubsystem
: ServiceLevelAgreementList
Kapitel 4. Design
: Manager
: Callback
: AgreementManager
1: initialize()
2: notify()
3: createTemplates()
4: createTemplate()
5: notify()
6: notifyAgreement()
7: getServiceLevelAgreementList()
8: add()
Abbildung 4.22: Sequenzdiagramm: Kommunikation mit WSAG4J-System/QoS-Proxy
4.6
4.6.1
Integrationssubsystem
Überblick
Das Integrationssubsystem beschreibt die notwendigen Schritte zur Integration des QoSProxys in Tuscany. Neben einer Reihe von Hilfsklassen, die den QoS-Proxy als PolicyErweiterung registrieren (vergleiche 3.2.2), sind die folgenden Klassen von besonderer
Bedeutung:
• ProxyPolicyProcessor
Der ProxyPolicyProcessor ist verantwortlich für das Lesen und Schreiben
der Modelldaten der Policy-Erweiterung.
• ProxyPolicyInterceptor
Der ProxyPolicyInterceptor beinhaltet die Interceptor-Klasse, die in die
Aufrufkette einer SCA-Anwendung eingefügt wird.
92
Kapitel 4. Design
4.6.2
4.6. Integrationssubsystem
Beschreibung der Klassen
ProxyPolicyProcessor
Über das Element policySet und intent in der Datei definitions.xml einer SCA-Anwendung werden Angaben zur Policy hinterlegt. Ausgelesen wird die Datei
über eine Implementierung des generischen Interface StAXArtifactProcessor der
Klasse ProxyPolicyProcessor.
ProxyPolicy
m>M
+getResourceBundleName() : String
+setResourceBundleName( resourceBundleName : String ) : void
+isUseParentHandlers() : boolean
+setUseParentHandlers( useParentHandlers : boolean ) : void
+getSchemaName() : QName
+isUnresolved() : boolean
+setUnresolved( unresolved : boolean ) : void
+getConfigFileLocation() : String
+setConfigFileLocation( logFileLocation : String ) : void
StAXArtifactProcessor
<<bind>>
+read( reader : XMLStreamReader ) : M
+write( model : M, writer : XMLStreamWriter ) : void
+getArtifactType() : QName
ProxyPolicyProcessor
<<constructor>>+ProxyPolicyProcessor( modelFactories : ModelFactoryExtensionPoint )
+getArtifactType() : QName
+read( reader : XMLStreamReader ) : ProxyPolicy
+write( policy : ProxyPolicy, writer : XMLStreamWriter ) : void
+getModelType() : Class<ProxyPolicy>
+resolve( arg0 : ProxyPolicy, arg1 : ModelResolver ) : void
Abbildung 4.23: Klassendiagramm: ProxyPolicyProcessor
In Abbildung 4.23 ist das Klassendiagramm der Klasse ProxyPolicyProcessor
dargestellt. Die Klasse wandelt die Daten aus der Datei definitions.xml in ein Modell der Policy, die durch die Klasse ProxyPolicy repräsentiert wird, um. Ausgelesen
und geschrieben wird das Modell über einen StAX XMLStreamReader. Die Klasse implementiert die durch das Interface bereitgestellten Methoden getArtifactType(),
read() und write(). Das von der Klasse ProxyPolicyProcessor verwaltete
Artefakt wird über die Methode getArtifactType() bestimmt. Mit der Methode
read() wird das Modell gelesen, mit der Methode write() geschrieben. Der Typ des
Modells wird mit der Methode getModelType() bestimmt.
Jedes Element, das ausgelesen wird, besitzt in der Klasse ProxyPolicy eine getund set-Methode. In Quellcode 4.3 ist ein Beispiel für die definitions.xmlDatei des Taschenrechner-Web-Service (vergleiche 2.2.3) zu sehen. Mit der Methode setConfigurationFileLocation() wird der Wert, der von dem Element
93
4.6. Integrationssubsystem
Kapitel 4. Design
configFileLocation eingeschlossen ist, gesetzt. Über die Methode getConfigurationFileLocation() kann der Wert zu einem späteren Zeitpunkt wieder zurückgegeben werden.
Innerhalb der Klasse ProxyPolicy wird der Pfad, der sich zwischen dem Element
configFileLocation befindet, an den Proxy übergeben, der über die Konfigurationskomponente die initiale Konfiguration des Proxys aus der Konfigurationsdatei ausliest (vergleiche 4.5.2.1).
1 <definitions xmlns="http://www.osoa.org/xmlns/sca/1.0"
2 targetNamespace="http://tuscany.apache.org/xmlns/sca/1.0"
3 xmlns:sca="http://www.osoa.org/xmlns/sca/1.0"
4 xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0" xmlns:sample="http://sample">
5 <policySet name="proxyPolicy" provides="tuscany:proxy"
6
appliesTo="sca:binding.ws" xmlns="http://www.osoa.org/xmlns/sca/1.0">
7
<tuscany:proxy name="Calculator">
8
<configFileLocation>/root/configuration/proxyconfig.xml</configFileLocation>
9
</tuscany:proxy>
10 </policySet>
11 </definitions>
Quellcode 4.3: Beispiel: Auszug aus der Datei definitions.xml
Die Klasse, die den generischen Typen StAXArtifactProcessor implementiert,
muss in der Datei org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor festgelegt werden. Zusätzlich muss der XML-Namensraum
der Policy-Erweiterung und die Klasse, die das Modell implementiert, genannt werden.
ProxyPolicyInterceptor
Die Klasse ProxyPolicyInterceptor implementiert das Interface Interceptor
und repräsentiert den Interceptor, der in die Aufrufkette einer bestehenden SCA-Anwendung eingebunden wird (vergleiche 3.2.2). Abbildung 4.24 stellt das Klassendiagramm der Klasse ProxyPolicyInterceptor vor. Die Klasse implementiert die
durch das Interface Interceptor definierten Methoden getNext(), setNext()
und invoke(). Über die Methode getNext() wird der nächste Interceptor in der
Aufrufkette bestimmt und mit setNext() der nächste Interceptor aufgerufen. In der
Methode invoke() befindet sich die eigentliche Logik des Interceptors.
Ein Web-Service-Aufruf entspricht einem Thread in Tuscany. Die Klasse ProxyPolicyInterceptor implementiert keinen Thread sondern ist Teil der Aufrufkette und
damit des aufrufenden, aktiven Threads. Dies bedeutet, dass pro Web-Service-Aufruf nur
94
Kapitel 4. Design
4.7. Proxy-Subsystem
Interceptor
+getNext() : Invoker
+setNext( next : Invoker )
ProxyPolicyInterceptor
<<constructor>>+ProxyPolicyInterceptor( c : String, o : Operation, s : PolicySet )
+invoke( msg : Message ) : Message
+getNext() : Invoker
+setNext( n : Invoker ) : void
Abbildung 4.24: Klassendiagramm: ProxyPolicyInterceptor
ein Interceptor Objekt erzeugt wird, um das unter Umständen verschiedene Threads konkurrieren. Für das Queueing ist es wichtig, dass der Thread in seiner Ausführung unterbrochen werden kann, um ihn zu einem späteren Zeitpunkt wieder zu aktivieren.
4.7
Proxy-Subsystem
Das Proxy-Subsystem ist die Hülle für die in den vorherigen Abschnitten vorgestellten
Subsysteme. Zusätzlich definiert das Proxy-Subsystem die Integration des QoS-Proxys in
eine SCA-Anwendung. Für das Hinzufügen der Funktionalität des QoS-Proxys zu einer
SCA-Anwendung sind keine Anpassungen am bestehenden Quelltext der Anwendung
notwendig.
4.7.1
Anpassung einer SCA-Anwendung
Eine Anforderung an den QoS-Proxy ist das leichte Hinzufügen und Entfernen zu einer SCA-Anwendung. Der QoS-Proxy bietet verschiedene Dienstgüteklassen zu einem
Service an. Über die Konfigurationsdatei des QoS-Proxys werden die unterschiedlichen Dienstgüteklassen definiert und die zugehörigen Werte der Dienstgüteeigenschaften
Durchsatz beziehungsweise Antwortzeit festgelegt (vergleiche 4.5).
Die Struktur einer SCA-Anwendung wird in einer composite-Datei festgelegt. Um
den QoS-Proxy für einen Web Service einzubinden, muss die composite-Datei der
zugehörigen SCA-Anwendung angepasst werden. Jede Dienstgüteklasse entspricht einer
Web-Service-Schnittstelle.
In Quellcode 4.4 ist ein Beispiel für eine angepasste composite-Datei aufgeführt.
95
4.7. Proxy-Subsystem
Kapitel 4. Design
Für jede Dienstgüteklasse muss ein Eintrag hinzugefügt werden. In Zeile 6 ist der Service CalculatorService definiert. Die Funktionalität des Service wird in Zeile 7
im interface.java-Element definiert. Der Zugriffsmechanismus ist ein Web Service, wie in Zeile 8 zu sehen ist. Für die Dienstgüteklasse „Gold“ wird ein weiteres
service-Element in Zeile 11 definiert. Das neue Element verweist auf die gleiche
Funktionalität, bindet aber mit dem Attribut requires den Proxy für den Web Service
CalculatorServiceGold ein.
1 <composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
2 targetNamespace="http://wwwvs.informatik.fh-wiesbaden.de/"
3 xmlns:sample="http://wwwvs.informatik.fh-wiesbaden.de"
4 xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0" name="Calculator">
5
6 <service name="CalculatorService" promote="CalculatorServiceComponent">
7
<interface.java interface="calculator.CalculatorService" />
8
<binding.ws/>
9 </service>
10
11 <service name="CalculatorServiceGold" promote="CalculatorServiceComponent"
12
requires="tuscany:proxy>
13
<interface.java interface="calculator.CalculatorService" />
14
<binding.ws/>
15 </service>
16 ...
17 </composite>
Quellcode 4.4: Beispiel: Angepasste composite-Datei einer SCA-Anwendung
Zusätzlich muss eine Datei definitions.xml erstellt werden, in der ein intentund ein policySet-Element für den Wert proxy definiert wird (vergleiche 3.2.2).
4.7.2
Initialisierung der Subsysteme
Repräsentiert wird das Proxy-Subystem durch die Klasse Proxy, in der die verschiedenen Subsysteme, ausgenommen das Integrationssubsytem, initialisiert werden.
Abbildung 4.25 stellt das Klassendiagramm der Klasse vor. Die Methode getProxyInstance() gibt eine Instanz der Klasse zurück. Über die Methode queue() übergibt
sich ein ProxyPolicyInterceptor-Thread an die Klasse Proxy. Um die Statistiken unterschiedlicher Subysteme zu sammeln, steht für das Queueing-Subsytem die
Methode addQueueStatistic() und für das Integrations-Subsystem die Methode
addPolicyStatistic() zur Verfügung.
96
Kapitel 4. Design
4.8. Zusammenfassung
Proxy
+getProxyInstance() : Proxy{guarded}
+queue( thread : ProxyPolicyInterceptor, service : String, queueingClass : String, priority : int ) : void
+addPolicyStatistic( stat : ProxyPolicyInterceptorStatistic ) : void
+addQueueStatistic( stat : QueueStatistic ) : void
+setActiveStrategy( index : int ) : boolean
+getServiceLevelAgreementList() : ServiceLevelAgreementList
+getActiveStrategy() : int
+getStrategy() : ArrayList<Strategy>
+setConfigurationPath( path : String ) : void
Abbildung 4.25: Klassendiagramm: Proxy
Um die aktive Queueing-Strategie zu wechseln, steht die Methode setActiveStrategy() zur Verfügung. Über den Aufruf der Methode getServiceLevelAgreementList() wird eine Liste mit den gültigen Service Level Agreements des Proxys zurückgegeben. Die aktive Queueing-Strategie wird mit der Methode getActiveStrategy() bestimmt. Über den Aufruf der Methode getStrategy() wird eine Liste der
im Proxy registrierten Queueing-Strategien zurückgegeben. Nach dem Setzen des Pfades zur Konfigurationsdatei über die Methode setConfigurationPath() liest der
Proxy die Konfigurationsdatei des Proxys ein.
4.8
Zusammenfassung
Abbildung 4.26 stellt das vollständige Sequenzdiagramm des QoS-Proxys dar. Das Sequenzdiagramm ergänzt die Diagramme 4.10 und 4.22 um weitere Funktionsaufrufe und
beschreibt damit den in 3.1 aufgeführten Anwendungsfall.
Der Proxy erhält in einem ersten Schritt den Pfad zur Konfigurationsdatei mit dem Aufruf der Methode setConfigurationPath(). Um die Konfigurationsdatei einzulesen, erzeugt der Proxy ein Objekt vom Typ ConfigurationFileReader und liest
die Konfigurationsdatei mit dem Aufruf der Methode readConfigurationFile()
ein. Anhand der Konfigurationsdatei lässt sich bestimmen, ob die Service Level Agreements über RMI mit einem WSAG4J-System ermittelt werden können oder ob sie aus
einer weiteren Datei ausgelesen werden müssen. Falls die Service Level Agreements über
einen WSAG4J-System bestimmt werden, ruft der Proxy die Methode initialize()
der Klasse Manager auf. Nachdem das AgreementManager-RMI-Objekt in der
RMI Registry gefunden wurde, registriert der Manager seinen Callback. Alternativ
liest der Manager über den Aufruf der Methode readSLAFile() die Service-LevelAgreement-Datei ein.
97
4.8. Zusammenfassung
Kapitel 4. Design
Der Manager erzeugt für jeden Service und jede in der Konfigurationsdatei definierte
Dienstgüteklasse ein Agreement Template. Über die Methode createTemplates() werden die Agreement Templates erzeugt, mit createTemplate()
werden die Agreement Templates am AgreementManager registriert.
Wird ein Agreement basierend auf einem Agreement Template erzeugt, so ruft
die Klasse AgreeementManager den zugehörigen Callback auf. Über die Methode notifyAgreement() erhält das Konfigurationssubsystem das neue Agreement.
Das Agreement wird von der Klasse Callback an die ServiceLevelAgreementListKlasse mit dem Aufruf der add()-Methode übergeben.
Stellt ein Client eine Anfrage an einen Web Service, der vom QoS-Proxy verwaltet wird, so erzeugt Tuscany einen neuen ProxPolicyInterceptor für die Anfrage. In einem ersten Schritt wird die Ankunftszeit des Web-Service-Aufrufs im
ItemStatistic-Objekt des vom ProxyPolicyInterceptor erzeugten ItemObjektes mit der Methode setRequestTime() gespeichert. Über den Aufruf der Methode getProxyInstance() holt sich der ProxyPolicyInterceptor eine Referenz auf eine Instanz der Klasse Proxy, um in einem nächsten Schritt den aufrufenden
Thread in ein Item-Objekt abzulegen und mit dem Aufruf der Methode queue() an
den Proxy zu übergeben.
Der Proxy Item übergibt über die Methode add() das Item-Objekt an die QueueingStrategie WeightedFairQueueing. Die Queueing-Strategie legt das Objekt in seine Queue WeightedFairQueueingItemList über die Methode add() ab. Das
WeightedFairQueueingItemList reicht mit der Methode add() wiederum das
Item-Objekt an seine interne Queue weiter. Über die Methode getThread() erhält
die Queueuing-Strategie eine Referenz auf das Thread-Objekt. Der Thread wird über die
Methode suspend() in den Zustand Wartend versetzt. Nach einer gewissen Zeit ruft
die Queueing-Strategie in der run-Methode die schedule()-Methode auf.
Für jede Queue in der Klasse WeightedFairQueueingItemList prüft die WeightedFairQueueing-Klasse, ob die entsprechende Queue Item-Objekte enthält. Falls
die Queue Item-Objekte enthält und das Gewicht der Queue in der aktuellen Iteration
noch nicht „aufgebraucht wurde“, versucht die Queueing-Strategie, einen Token aus dem
LeakyBucket mit der Methode take() zu entnehmen.
Falls ein Token verfügbar ist, wird das Item-Objekt aus der Queue mit der Methode remove() entfernt und mit getThread() die Referenz auf das gespeicherte
Thread-Objekt zurückgegeben. Daraufhin kann die Queueing-Strategie auf das zugehörige ItemStatistic-Objekt mit der Methode getStatistic() zugreifen und
98
Kapitel 4. Design
4.8. Zusammenfassung
die Verweilzeit in der Queue mit dem Aufruf der Methode setExposureTime() festhalten. Der Thread wird mit der Methode resume() in den Zustand Aktiv versetzt.
Nachdem das ProxyPolicyInterceptor-Objekt wieder aktiv ist, kann es den Aufruf an den Web Service fortsetzen. Kurz vor dem Aufruf setzt das Objekt mit der Methode setResponseTimeOnRequest() und nach dem Eintreffen der Antwort mit
der Methode setResponseTimeAfterRequest() die Zeitmarken, um die Antwortzeit des Web Services zu bestimmen. Abschließend übergibt das ProxyPolicyInterceptor-Objekt über die Methode addItemStatistic() das ItemStatistic-Objekt an den Proxy. Der Proxy übergibt das ItemStatistic-Objekt an
die Klasse Statistic zur Auswertung.
99
Kapitel 4. Design
4.8. Zusammenfassung
: ProxyPolicyInterceptor
: Callback
alt
: Manager
3: initialize()
5: createTemplates()
6: createTemplate()
9: add()
10: readSlaFile()
: ServiceLevelAgreementList
12: getStatistic()
32: setResponseTimeAfterRequest
30: setResponseTimeOnRequest()
29: getStatistic
17: add()
16: Item()
2: readConfigurationFile()
: AgreementManager
4: register
1: setConfigurationPath()
: Proxy
[if rmiregistry is set]
alt
[if serviceclass list != null]
[else]
7: notifyAgreement()
8: getServiceLevelAgreementList()
[else]
15: queue()
14: getProxyInstance()
31: getNext()
33: addItemStatistic
11: add()
: ConfigurationFileReader
loop
: Item
21: run()
: AgreementFactory
19: add()
23: take()
25: remove()
27: setExposureTime()
: WeightedFairQueueingItemList
24: remove()
22: schedule()
18: add()
13: setRequestTime()
: WeightedFairQueueing
20: suspend()
[for every queue in the weightedfairqueueingitemlist]
loop
28: resume()
26: getStatistic()
[for every item in the queue and weight is available for the queue]
alt
[if take was successful]
[else]
34: addItemStatistic()
: Queue
: LeakyBucket
Abbildung 4.26: Sequenzdiagramm: Berücksichtigung von QoS-Anforderungen an Web Services
: ItemStatistic
: Statistic
100
Kapitel 5
Implementierung
Im folgenden Kapitel soll das Konzept eines QoS-Proxy für SOA-Dienste, wie es im
Kapitel 4 entworfen wurde, umgesetzt werden. Im ersten Abschnitt werden die Entwicklungsumgebung und verwendeten Werkzeuge vorgestellt. Im Anschluss werden die Implementierungsdetails der zuvor entworfenen Subsysteme betrachtet.
5.1
Umgebung
Der Proxy wurde in die Version 1.2.1 der Apache Tuscany SCA integriert. Als Application Server wurde Apache Tomcat in der Version 5.5.26 eingesetzt. Als Java Compiler
und Java Runtime wurde das JDK von Sun in der Version 1.5.0_15 verwendet. Die QoSErweiterung für WSAG4J machte es erforderlich ein JDK in der Version 1.6 einzusetzen.
Zum Einsatz kam das JDK in der Version 1.6.0_10, allerdings wurde der Code im Kompatibilitätsmodus übersetzt, so dass er auch unter einem JDK 1.5 lauffähig ist. Für WSAG4J
wurde als Application Server Tomcat in der Version 6.0.18 verwendet. Zur Erstellung der
Software-Komponenten wurde als Entwicklungsumgebung die Eclipse IDE in der Version 3.3.1 eingesetzt.
5.2
Namenskonventionen
Alle erstellten Klassen im Proxy-Modul werden unterhalb des Packages org.apache.tuscany.sca.policy.proxy abgelegt. Interface-Namen beginnen mit einem I gefolgt von einem weiteren Großbuchstaben. Ausgenommen von dieser Konvention sind
101
5.3. Logging
Kapitel 5. Implementierung
die MBean-Interfaces, da der Klassenname ebenfalls IKlassennamen lauten müsste und
zwischen den anderen Interfaces und Klasse nicht mehr unterschieden werden könnte. Klassennamen beginnen mit einem Großbuchstaben und alle Bezeichner mit einem
Kleinbuchstaben. Klassen und Interfaces werden jeweils in eine eigene Datei abgelegt,
ausgenommen davon sind innere, private Klassen. Weiterhin wurde Wert auf sogenannte „sprechende Bezeichner“ gelegt. Der jeweils erste Buchstaben bei zusammengesetzten
Bezeichnern wird groß geschrieben, wie zum Beispiel objectInstance.
5.3
Logging
Für den QoS-Proxy wurde das Apache-log4j-Projekt (log4j) [Gup05] verwendet. Das Verhalten des log4j-Systems kann durch eine Datei individuell gestaltet werden, was es einem Entwickler erlaubt, das Logging-Verhalten einer Software, ohne das Anpassen des
Quellcodes, zu steuern. Mit Hilfe von log4j kann zwischen verschiedenen Schweregraden unterschieden werden. Die Schweregrade sind in einer Hierarchie angeordnet. Aus
einer Anwendung heraus können diese Schweregrade ausgewählt werden, um ihnen LogNachrichten zuzuweisen. Man unterscheidet zwischen den Schweregraden TRACE, DEBUG, INFO, WARN, ERROR und FATAL. Konfiguriert wird die Ausgabe mit Hilfe einer
Konfigurationsdatei. Dabei wird mit sogenannten Appendern festgelegt, wohin die Ausgabe der Log-Nachrichten erfolgt. Zur Auswahl stehen dabei die Standardausgabe, eine
Datei oder beliebige andere Ziele. Für jeden Appender kann ein Layout festgelegt werden, welches definiert, wie die Daten strukturiert ausgegeben werden. In Quellcode 5.1
ist ein Beispiel für eine Konfigurationsdatei von log4j abgebildet.
1
2
3
4
5
log4j.rootLogger=DEBUG, ProxyAppender
log4j.appender.ProxyAppender=org.apache.log4j.FileAppender
log4j.appender.ProxyAppender.File=proxy.log
log4j.appender.ProxyAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.ProxyAppender.layout.ConversionPattern=%d [%t] - %c - %m%n
Quellcode 5.1: Beispiel: Konfigurationsdatei für log4j
Die Konfigurationsdatei wird einmalig mit der Methode configure() der log4j-Klasse
PropertyConfigurator initialisiert. Jede Klasse besitzt ein Attribut logger vom Typ
Logger. Mit der Funktion getLogger() der Klasse Logger wird der Logger für die
entsprechende Klasse zurückgegeben. Log-Nachrichten für einen bestimmten Schweregrad erfolgen mit dem Aufruf logger.SCHWEREGRAD().
102
Kapitel 5. Implementierung
5.4
5.4.1
5.4. Queueing-Subsystem
Queueing-Subsystem
Überblick
Das Queue-Subsystem stellt Implementierungen von Queueing-Strategien und die dazu
benötigten Datenstrukturen bereit. Eine weitere Queueing-Strategie lässt sich über das
Erben der abstrakten Klasse Strategy realisieren. Jede Queueing-Strategie benötigt
eine Datenstruktur, die die Queues realisiert. Die Klasse ItemList stellt als abstrakte
Klasse das Grundgerüst an Operationen zur Verfügung. Die Klasse Strategy erbt von
der Klasse Thread und besitzt eine Methode run(), die periodisch aufgerufen wird.
Jeder Algorithmus ist damit auch ein Thread.
Mit Java 5 wurden die Concurrency Utilities1 in Java eingeführt. Die Concurrency Utilities sollen das Entwickeln von Anwendungen mit Nebenläufigkeit erleichtern. Jede
Queueing-Strategie besitzt eine Binärsemaphore deren Wert erhöht wird, wenn ein ItemObjekt in eine Queue abgelegt wird und gesenkt wird, wenn kein Item-Objekt mehr in
einer Queue vorhanden ist. Sind keine Item-Objekte mehr in der Queue und ist der Wert
der Semaphore 0, so blockiert der Thread und wartet nicht aktiv darauf, dass ThreadObjekte eingefügt werden.
• Item
Innerhalb der Klasse wird ein Auftrag für eine Queueing-Strategie in Form eines
Threads abgelegt.
• ItemStatistic
In der Klasse ItemStatistic werden Messwerte des aufrufenden Threads
abgelegt und verschiedene Kenngrößen berechnet.
• LeakyBucket
Die Klasse LeakyBucket implementiert den Leaky-Bucket-Algorithmus und erzeugt in einer konstanten Rate Tokens.
• Queue
Die Klasse Queue ist eine Hilfsklasse für die Implementierung der Klasse
ItemList. In eine Queue werden Item-Objekte abgelegt.
• WeightedFairQueueingItemList
Die Klasse WeightedFairQueueingItemList implementiert die Queue der
Queueing-Strategie Weighted Fair Queueing.
1
Homepage der Java 5 Concurrency Utilities: http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/
103
5.4. Queueing-Subsystem
Kapitel 5. Implementierung
• WeightedFairQueueing
In der Klasse WeightedFairQueueing wird die Queueing-Strategie Weighted
Fair Queueing implementiert.
5.4.2
Beschreibung der Implementierung
Item
In der Klasse Item wird ein Auftrag für eine Queueing-Strategie abgelegt. Ein Auftrag
entspricht einem Thread der pro Web-Service-Anfrage verwendet wird. Zusätzlich werden eine Reihe von weiteren Informationen in der Klasse abgelegt, die über get- und
set-Methoden abrufbar bzw. setzbar sind.
Die Klasse speichert den aufrufenden Thread in einem Attribut. Die Klasse realisiert
zusätzlich die Methoden, die benötigt werden, um den Thread in den Zustand Wartend
oder Aktiv zu versetzen. Innerhalb der suspend()-Methode wartet der Thread mit
Hilfe des Aufrufes der wait()-Methode. Dabei wird über eine Zähler festgelegt, ob der
Thread nach dem Ablauf des Timeouts des wait()-Aufrufes weiter warten muss oder
weiterlaufen kann. In den Zustand Aktiv wird der Thread über den Aufruf der Methode
resume() versetzt. Der Zustandswechsel wird dabei durch den Aufruf der Methode
notify() durchgeführt.
ItemStatistic
Die Klasse ItemStatistic speichert Messwerte des aufrufenden Threads und berechnet daraus die in Abschnitt 3.4.2.1 vorgestellten Kenngrößen. Die Messwerte werden
über einen einfachen Aufruf der jeweiligen Methode gesetzt, dabei wird mit der Methode
System.nanoTime() eine Zeitmarke im entsprechenden Attribut gespeichert.
LeakyBucket
Der Leaky-Bucket-Algorithmus erzeugt in einer konstanten Rate Tokens. Der Konstruktor
der Klasse hat als Parameter die Größe des Buckets, die initiale Anzahl der verfügbaren
Tokens, die Rate in der Tokens erzeugt werden und die Anzahl der Tokens die erzeugt
werden. Erzeugt werden die Tokens in einer inneren, privaten Klasse Producer. Die
Klasse Producer implementiert einen Thread und erzeugt in einer konstanten Rate
Tokens.
104
Kapitel 5. Implementierung
5.4. Queueing-Subsystem
Abgelegt werden die erzeugten Tokens in einer LinkedBlockingQueue. Die Klasse
LinkedBlockingQueue ist Bestandteil der Java Concurrency API. Werden mehr Tokens erzeugt als in der LinkedBlockingQueue Platz ist, so häufen sich die Tokens
vor der LinkedBlockingQueue und warten bis wieder Platz in der LinkedBlockingQueue verfügbar ist. Die Queueing-Strategie entnimmt immer dann ein Token, wenn
ein Item-Objekt aus einer Queue entfernt wird und bearbeitet werden soll. Mit der Methode take() entnimmt die Queueing-Strategie die Tokens. Sind keine Tokens mehr in
der LinkedBlockingQueue vorhanden, so blockiert die Queueing-Strategie an der
Datenstruktur, solange bis Tokens wieder verfügbar sind. Nach der Erzeugung der Tokens schläft der Thread der Klasse Producer für einen entsprechenden Zeitraum. Der
Zeitraum entspricht der Erzeugungsrate.
Der Algorithmus wird initial in der Klasse Proxy erzeugt. Alle im Proxy registrierten Queueing-Strategien erhalten eine Referenz auf das LeakyBucket-Objekt. Da alle
Queueing-Strategien zum Zeitpunkt des Startes inaktiv sind bzw. über einen Semaphore sichergestellt ist, dass die Strategien an der Semaphore blockieren, kann es nicht zu
Wechselwirkungen zwischen einzelnen Queueing-Strategien kommen.
Queue
Die Klasse Queue implementiert eine einfache Queue für die Klasse WeightedFairQueueingItemList. In der Klasse Queue werden die Item-Objekte einer Dienstgüteklasse abgelegt. Die Klasse WeightedFairQueueingItemList verwaltet bis zu
n-Queue-Objekte in einer ArrayList. Jede Queue verfügt über ein Gewicht und eine
Priorität. Die Klasse verfügt über verschiedene get- und set-Methoden. Innerhalb der
Klasse Queue werden die Item-Objekte ebenfalls in einer ArrayList verwaltet.
WeightedFairQueueingItemList
Die Klasse WeightedFairQueueingItemList implementiert die Queue für die
Klasse WeightedFairQueueing. Dabei erbt die Klasse von der abstrakten Klasse
ItemList. Aufträge werden von der Klasse WeightedFairQueueing an die Klasse
WeightedFairQueueingItemList über den Aufruf der Methode add() übergeben. Dabei werden die Aufträge in ein Objekt vom Typ Queue abgelegt. Die Klasse kann
dabei n Queue-Objekte besitzen, die in einem ArrayList-Objekt verwaltet werden.
Eingehende Aufträge werden von der Klasse anhand der Dienstgüteklasse klassifiziert
und in die entsprechende Queue abgelegt.
105
5.4. Queueing-Subsystem
Kapitel 5. Implementierung
Die Queue prüft, ob bereits eine Queue mit der Dienstgüteklasse existiert. Falls ja, wird
das Objekt in die Queue einsortiert. Falls nein, so wird geprüft, ob überhaupt eine weitere
Queue mit einem Gewicht angelegt werden kann. Das kleinste Gewicht einer Queue ist 1.
Ein Gewicht von 1 bedeutet, dass für jeden Aufruf genau ein Auftrag verarbeitet werden
kann. Eine Verarbeitung von Bruchteilen ist nicht möglich.
Die Methode size() liefert die Größe einer Queue, die Methode totalSize() gibt
die Anzahl der Queues in der WeightedFairQueueingItemList zurück. Mit der
Methode getIndexFromPriority() kann bestimmt werden, welche Queue in der
Verwaltungsstruktur die entsprechende Priorität besitzt. Um das Gewicht einer Queue
zu bestimmen, existiert die Methode getWeightFromQueue(). Mit der Methode
contains() wird bestimmt, ob eine Queue mit der Priorität bereits existiert. Eine neue
Queue wird mit der Methode createQueue() erzeugt. Alle öffentlichen Methoden der
Klasse sind synchronized-Methoden, um einen Thread-sicheren Zugriff zu garantieren.
WeightedFairQueueing
Die Klasse WeightedFairQueueing realisiert den Weighted-Fair-Queueing-Algorithmus. Parameter des Konstruktors sind das maximale verfügbare Gewicht und eine Referenz auf das LeakyBucket-Objekt. Mit der Methode add() übergibt der Proxy ein
Objekt vom Typ Item an die Implementierung des Algorithmus. In der add()-Methode
wird das Item-Objekt an die Queue weitergereicht. Über den Aufruf der Methode
suspend des Item-Objektes wird die im Objekt befindliche Referenz des Thread
in den Zustand Wartend versetzt.
In der schedule()-Methode ist der eigentliche WFQ-Algorithmus implementiert. Der
Algorithmus durchläuft jede Queue der WeightedFairQueueingItemList-Klasse
und entnimmt Item-Objekte. Die Anzahl der Objekte die entnommen wird, entspricht dem
Gewicht der Queue. Mit der Methode inspectThroughput() wird in der Funktion
geprüft, ob die SLOs für den jeweiligen Service noch einzuhalten sind.
106
Kapitel 5. Implementierung
5.5
5.5.1
5.5. Monitoring-Subsystem
Monitoring-Subsystem
Überblick
Das Monitoring-Subsystem sammelt und erzeugt Statistiken der einzelnen Subsysteme
und stellt sie über JMX Management-Anwendungen zur Verfügung. Bestandteile des Subsystems sind das Interface StatisticMBean und die Klasse Statistic. Die Klasse
implementiert die durch das Interface StatisticMBean bereitgestellten Methoden.
Aufgrund von Konflikten1 mit der aktuellen JDK-Version 1.6 nutzt das Apache-TuscanySCA-Projekt das JDK 1.5. Der Konflikt beruht auf der in Tuscany genutzten Version von
JAXB oder StAX und den in JDK 1.6 ausgelieferten Versionen. Die JDK-Version 1.6 setzt
die JMX-Spezifikation 1.4 um. Das JDK in der Version 1.5 setzt die JMX-Spezifikation
1.2 um. Da die Management-Komponente im Proxy und damit in Tuscany selbst integriert
ist, werden die MBeans als OpenMBeans modelliert. Der Einsatz von OpenMBeans garantiert, dass jede JMX-Management-Anwendung benutzt werden kann.
5.5.2
Beschreibung der Implementierung
Statistic
Die Klasse Statistic implementiert die im Interface StatisticMBean definierten Methoden. Von besonderem Interesse sind die Statistiken die aus der Klasse
ItemStatistic erzeugt werden. Mit der Methode getItemData() werden alle gesammelten ItemStatistic-Datensätze zurückgegeben. In einem relativ kurzen Zeitraum können, je nach Anzahl der Web-Service-Anfragen, sich entsprechend viele ItemStatistic-Objekte in der Klasse Statistic befinden. Über die Methode
setInterval kann ein Interval gesetzt werden. Das Interval hat auf alle weitere Methoden, die Statistiken zu den Item-Objekten erzeugen, Einfluss. Mit resetInterval()
wird das Interval zurückgesetzt. Das Interval wird durch zwei Marken realisiert, die in den
jeweiligen Schleifen zur Erzeugung einen Start- und einen Endwert bilden.
Mit der Methode setFilter() kann ein Filter gesetzt werden, der auf einen Web
Service einschränkt. Das ist besonders hilfreich, wenn man nur die Statistiken zu einem
ganz bestimmten Datensatz bilden möchten. Intern werden die Datensätze in HashMaps
verwaltet. Der Filter entspricht dem Schlüssel in einer HashMap. Statt alle Werte aller
1
Hinweis auf der Apache Tuscany
faq.html#TuscanySCAJava-FAQ-BuildA
Homepage:
107
http://tuscany.apache.org/tuscany-sca-java-
5.6. WS-Agreement-Subsystem
Kapitel 5. Implementierung
Schlüssel zurückzugeben werden nur die Werte eines bestimmten Schlüssel zurückgegeben. Über die Methode resetFilter() wird der Filter zurückgesetzt.
Um die Statistiken außerhalb einer Management-Anwendung auswerten zu können, steht
eine Exportfunktion zur Verfügung. Mit der Methode setFileName wird ein Dateiname und ein Pfad für die Exportfunktion gesetzt. Die Methode exportItemDataToCVSFile() exportiert die ItemStatistic-Datensätze in eine CSV-Datei.
Die Methode getSize() gibt die Anzahl der protokollierten ItemStatisticObjekte zurück. Das Betrachten von Abweichungen ist von besonderem Interesse. Mit
der Methode min(), max() und getStandardDeviationData() wird das Minimum, Maximum und die Standardabweichung bestimmt. Die Standardabweichung in
der Klasse Statistic entspricht dabei der diskreten Standardabweichung. Je höher
die Werte sind, die vom Wert 0 abweichen, desto größer sind die Schwankungen in den
Messwerten. Das arithmetische Mittel lässt sich mit der Methode getAverageData()
bestimmen. Die Methode getServices() gibt die Services der gesammelten ItemStatistic-Objekte zurück. Mit der Methode getSuccessfulSLA() und getFailedSLA() wird der entsprechende Zähler zurückgegeben.
5.6
5.6.1
WS-Agreement-Subsystem
Überblick
Das WS-Agreement-Subsystem wird durch WSAG4J, einer WS-Agreement-Implementierung des Fraunhofer Instituts (vergleiche 2.1.3) implementiert.
Das WSAG4J-Subsystem beschreibt die Klassen, die für die Kommunikation mit dem
Konfigurationssubsystem auf Seiten des WSAG4J angepasst oder neu erstellt werden
mussten. Zu den Klassen gehören:
• AgreementManager
Die Klasse AgreementManager implementiert das Interface IServiceLevelManagement und stellt Methoden zur Registrierung von Agreement Templates bereit.
• TemplateManager
In der Klasse TemplateManager werden Agreement Templates registriert und Agreement Offer auf ihre Gültigkeit hin überprüft.
108
Kapitel 5. Implementierung
5.6. WS-Agreement-Subsystem
Die Funktionalität der Klasse AgreementManager wurde bewusst nicht in die Klasse
TemplateManager integriert. Das vom WSAG4J-System erzeugte Objekt vom Typ
AgreementManager wird in einer RMI-Registry abgelegt. Um das Objekt nutzen
zu können, muss eine Java-Anwendung den gleichen package-Namensraum verwenden. Für das WSAG4J-System hätte das bedeutet, den ursprünglichen Namensraum von
de.fh_wiesbaden.cs.vs.agreement auf org.apache.tuscany.sca.policy.proxy zu ändern, was alleine inhaltlich nicht korrekt wäre. Eine Änderung des
Namensraums des QoS-Proxys war aus Integrationsgründen nicht möglich.
5.6.2
Beschreibung der Implementierung
AgreementManager
Die Klasse AgreementManager kann als eine Art Adapter-Klasse für die Klasse
TemplateManager betrachtet werden. In einem ersten Schritt wird über die Methode register() ein Callback für den QoS-Proxy am Server registriert. Agreement
Templates werden über die Methode createTemplate() registriert. Die Methode
erzeugt dabei aus einem String-Array die XML-Repräsentierung eines Agreement
Templates. Über die Methode report() kann der QoS-Proxy dem WSAG4J-System
mitteilen, wenn ein Agreement nicht eingehalten werden konnte.
TemplateManager
Die Klasse TemplateManager ist die eigentliche Schnittstelle um Agreement
Templates eines Services zu registrieren. Über den Aufruf der Methode registerTemplate() werden Agreement Templates im WSAG4J-System registriert. Alle Methoden sind, bis auf eine neue, erweiterte createTemplate()-Methode, bereits
vorhanden.
Die bestehenden Methoden werden um zusätzliche Funktionalität erweitert. Dabei wird
geprüft, ob ein Agreement mit einem über den AgreementManager erzeugtem
Agreement Template übereinstimmt oder darauf basiert. Trifft dies zu, wird die Methode notify() des zugehörigen Callback-Objekts aufgerufen.
Wird ein neues Agreement erzeugt, so wird die Methode newAgreement() aufgerufen. Bei einer Übereinstimmung zu einem Agreement Template ruft die Klasse
die Methode notifyAgreement() des zugehörigen Callback-Objekts auf. Wird
109
5.7. Konfigurationsubsystem
Kapitel 5. Implementierung
ein Agreement beendet, so wird die Methode agreementTerminated() aufgerufen. Im Falle einer Übereinstimmung ruft die Klasse die notifyTermination() des
zugehörigen Callback-Objekts auf.
Verwaltet werden die Callback-Objekte in einer HashMap, dabei entspricht das Template dem Schlüssel der HashMap und das Callback-Objekt dem Wert.
5.7
5.7.1
Konfigurationsubsystem
Überblick
Das Konfigurationssubsystem ist verantwortlich für die Konfiguration des QoS-Proxys
zum Zeitpunkt des Startes und zur Laufzeit. Zum Konfigurationssubsystem zählen die
folgenden Klassen:
• Callback
Die Klasse Callback ermöglicht es dem WS-Agreement-Subsystem den QoSProxy über das erfolgreiche Registrieren von Agreement Templates oder das
Erzeugen von neuen Agreements zu informieren.
• ServiceClass
In der Klasse ServiceClass werden die Elemente througput und responseTime der Konfigurationsdatei zur Erzeugung von Agreement Templates gespeichert.
• ConfigurationFile
Die Klasse ConfigurationFile repräsentiert die Konfigurationsdatei des
QoS-Proxys als Java-Objekt.
• ServiceLevelAgreementFile
Die Klasse ServiceLevelAgreementFile ist die Java-Objektrepräsentierung
einer Service-Level-Agreement-Datei wie sie in Abschnitt 4.5.2 definiert wurde.
• ServiceLevelAgreementList
In der Klasse ServiceLevelAgreementList werden die ServiceLevelAgreement-Objekte des QoS-Proxys verwaltet.
• ConfigurationFileReader
Die Klasse ConfigurationFileReader liest die Konfigurationsdateien des
QoS-Proxys ein.
110
Kapitel 5. Implementierung
5.7. Konfigurationsubsystem
• Manager
Die Klasse Manager implementiert das Interface ManagerMBean und stellt über
JMX Operationen zur Verwaltung des QoS-Proxys zur Verfügung.
5.7.2
Beschreibung der Implementierung
Callback
Die Klasse Callback implementiert die im Interface ICallback definierten Methoden. Der Konstruktor der Klasse erhält als Parameter eine Referenz auf die Klasse
Manager und kann somit Methoden dieser Klasse aufrufen. Ein Agreement erhält die
Klasse über die Methode notifyAgreement(). Innerhalb der Methode wird die Methode getServiceLevelAgreementList() der Klasse Manager aufgerufen und
eine Referenz auf das ServiceLevelAgreementList-Objekt der Klasse Manager
zurückgegeben. Über die Methode add() der Klasse ServiceLevelAgreementList wird ein Agreement zur Liste hinzugefügt.
Wird ein Agreement mit der Methode notifyTermination() beendet, so wird ein
Flag im entsprechenden ServiceLevelAgreement-Objekt in der ServiceLevelAgreementList gesetzt. Über den Aufruf der Methode getServiceLevelAgreement() in der Klasse ServiceLevelAgreementList kann das entsprechende
Agreement bestimmt werden.
ServiceClass
In der Klasse ServiceClass werden die Elemente throughput und responseTime aus der Konfigurationsdatei des QoS-Proxys gespeichert. Die Attribute der Elemente sind über get- und set-Methoden setzbar. Aus den verschiedenen ServiceClassObjekten erzeugt die Klasse Manager in einem späteren Schritt die Agreement
Templates und registriert sie an einem WSAG4J-System.
ConfigurationFile
Die Klasse ConfigurationFile repräsentiert die Konfigurationsdatei des QoSProxys als Java-Objekt. Elemente der Konfigurationsdatei werden über get- und setMethoden bestimmt bzw. gesetzt. In einer Konfigurationsdatei können sich beliebig viele
throughput- und responseTime-Elemente befinden. Verwaltet werden die Elemente in der Klasse in einer HashMap.
111
5.7. Konfigurationsubsystem
Kapitel 5. Implementierung
ServiceLevelAgreementFile
Die Klasse ServiceLevelAgreementFile repräsentiert die alternative ServiceLevel-Agreement-Datei für den QoS-Proxy. Über verschiedene set-Methoden werden
die Elemente der Datei in der Klasse gespeichert. Die Klasse erzeugt aus den gesammelten Agreements Objekte der Klasse ServiceLevelAgreement-Objekte. Die Methode toArray() gibt ein Array von ServiceLevelAgreement-Objekten zurück,
welche aus den aus der Datei ausgelesenen Agreements erzeugt wurde.
ServiceLevelAgreementList
In der Klasse ServiceLevelAgreementList werden die ServiceLevelAgreement-Objekte des QoS-Proxys verwaltet. Die Klasse stellt drei verschiedene add()Methoden zur Verfügung. Über die erste add()-Methode können ServiceLevelAgreement-Objekte in Form eines Arrays übergeben werden. Die zweite Methode hat
als Parameter ein String-Array und gibt der Callback-Klasse die Möglichkeit das
Array, das bei einem notifyAgreement() erhalten wird, direkt an die Klasse weiterzugeben. Die letzte add()-Methode nimmt ein einzelnes SerivceLevelAgreementObjekt entgegen. Verwaltet werden die SerivceLevelAgreement-Objekt intern in
einer ArrayList.
ConfigurationFileReader
Die Klasse ConfigurationFileReader ist verantwortlich für das Lesen der Konfigurationsdateien. Über den Aufruf der Methode readConfigurationFile() wird
eine Konfigurationsdatei für den QoS-Proxy ausgelesen. Die Konfigurationsdatei enthält
Angaben zur Erzeugung von Agreement Templates oder einen Pfad zu einer alternativen Datei mit Service Level Agreements, die über die Methode readSLAFile()
ausgelesen wird. Beide Dateien liegen im XML-Format vor und werden über einen StAX
XMLStreamReader ausgelesen. Die Methoden liefern eine Repräsentierung der Konfigurationsdatei als Java-Objekt und werden in der Klasse Proxy weiterverarbeitet.
Manager
Die Klasse Manager implementiert das Interface ManagerMBean. In der initializeMethode wird die RMI-Kommunikation initialisiert und ein Callback-Objekt regis-
112
Kapitel 5. Implementierung
5.8. Integrationssubsystem
triert. Das Callback-Objekt erlaubt es einem WSAG4J-System, dem QoS-Proxy Statusmeldungen zu schicken und über neue Agreements zu informieren.
Auf Grundlage der durch die Konfigurationsdatei erzeugten ServiceClass-Objekte
erzeugt der Manager in der Methode createTemplates() verschiedene Templates
und registriert sie mit dem Aufruf der Methode createTemplate() am WSAG4JSystem.
5.8
5.8.1
Integrationssubsystem
Überblick
Das Integrationssubsystem beschreibt die Implementierung der Hilfsklassen und verwandter Klassen die benötigt werden, um den QoS-Proxy in Tuscany zu integrieren. Zu
den Klassen gehören:
• ProxyPolicyInterceptor
Die Klasse ProxyPolicyInterceptor implementiert den Interceptor der Policy der in eine Aufrufkette einer SCA-Anwendung integriert wird.
• ProxyPolicyProcessor
Über die Klasse ProxyPolicyProcessor wird die definitions.xmlDatei einer SCA-Anwendung eingelesen.
• ProxyPolicyProvider
Die Klasse ProxyPolicyProvider erzeugt die entsprechenden Provider für
das entsprechende SCA-Element.
• ProxyPolicyDefinitionsProvider
Mit der Klasse ProxyPolicyDefinitionsProvider wird die definitions.xml-Datei der Policy eingelesen.
5.8.2
Beschreibung der Implementierung
ProxyPolicyInterceptor
Der ProxyPolicyInterceptor ist der Interceptor, der in die Aufrufkette einer bestehenden SCA-Anwendung eingekettet wird. Pro Operation wird der ProxyPolicyInterceptor genau einmal erzeugt. Dies bedeutet, dass bei einem Aufruf der Operation
113
5.8. Integrationssubsystem
Kapitel 5. Implementierung
von verschiedenen Quellen verschiedene Threads um das Objekt konkurrieren. Der Konstruktor der Klasse erhält als Parameter die Operation, das policySet, welches aus der
Datei definitions.xml ausgelesen wurde und einen Kontext.
Die eigentliche Funktionalität des Interceptors befindet sich in der Methode invoke().
In einem ersten Schritt wird ein neues Item-Objekt erzeugt. Das Item-Objekt initialisiert sein ItemStatistic-Attribut. Mit dem Aufruf der Methode getStatistic()
aus dem neu erzeugten Item-Objekt wird das ItemStatistic-Objekt zurückgegeben. Der Interceptor kann dann die erste Zeitmarke, die Ankunftszeit im System, setzen.
Über die Methode getServiceInformationFromURI() wird die Dienstgüteklasse aus der aufrufenden URL bestimmt und im Item-Objekt mit dem Aufruf der Methode
setQueueingClass() gesetzt. Der Interceptor übergibt das Item-Objekt mit der
Methode queue() an die Klasse Proxy.
Der Interceptor implementiert weiterhin die Methoden getNext() und setNext().
Mit der Methode getNext() wird der nächste Interceptor in der Aufrufkette bestimmt.
Über die Methode setNext() wird die Nachricht an den nächsten Interceptor in der
Aufrufkette weitergegeben und der auf dem ProxyPolicyInterceptor folgende
Interceptor wird aktiv.
ProxyPolicyProcessor
Die Klasse ProxyPolicyProcessor implementiert einen StAXArtifactProcessor für die Klasse PolicyProcessor. Der StAXArtifactProcessor kapselt einen StAX XMLStreamReader und stellt als Interface die Methoden read(),
write() und getArtifactType() bereit. Die Methode read() der Klasse ProxyPolicyProcessor liest die Datei definitions.xml ein und speichert die eingelesenen Elemente in einem PolicyProcessor-Objekt. In der Klasse PolicyProcessor
wird das XML-Schema definiert. Dies bedeutet, dass jedes Attribut, das eingelesen wird,
in der Klasse als Datentyp abgebildet ist.
1 org.apache.tuscany.sca.policy.proxy.ProxyPolicyProcessor;
2 qname=http://tuscany.apache.org/xmlns/sca/1.0#proxy,
3 model=org.apache.tuscany.sca.policy.proxy.ProxyPolicy
Quellcode 5.2: Konfiguration: StAXArtifactProcessor-Datei
Die Klasse ProxyPolicyProcessor muss zusätzlich in der Datei org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor im Ver-
114
Kapitel 5. Implementierung
5.8. Integrationssubsystem
zeichnis src/main/resources/META-INF/services/ mit dem Eintrag in Quellcode 5.2 beschrieben werden.
ProxyPolicyProvider
Jedes Element, auf das eine Policy angewendet werden soll, muss einen ProxyPolicyProvider zur Verfügung stellen. In der aktuellen SCA-Spezifikation ist es nur möglich, Policies auf service-, reference- oder implementation-Elemente anzuwenden. Alle ProxyPolicyProvider implementieren die durch das Interface
PolicyProvider bereitgestellten Methoden createInterceptor() und getPhase().
Die Klasse ProxyPolicyProviderFactory implementiert das Interface PolicyProviderFactory. Das Interface PolicyProviderFactory ist ein parameterisiertes Interface, welches als Parameter eine Klasse, die das Interface Policy erweitert,
besitzt. Die Klasse ProxyPolicyProviderFactory implementiert daher das Interface PolicyProviderFactory<ProxyPolicy>. Zu dem Interface gehören Methoden zur Erzeugung von ProxyPolicyProvidern für die Elemente implementation,
service und reference. Die Methoden createImplementationPolicyProvider, createServicePolicyProvider() und createReferencePolicyProvider() rufen den Konstruktur der Klassen ProxyImplementationPolicyProvider, ProxyServicePolicyProvider und ProxyReferencePolicyProvider auf. Gemeinsame Argumente der Konstruktoren ist die Laufzeitrepräsentierung der component der Anwendung. Der Konstruktor der Klasse ProxyImplementationPolicyProvider hat als weiteres Argument die Laufzeitrepräsentierung
der zugehörigen implementation. Die Klasse ProxyServicePolicyProvider
und ProxyReferencePolicyProvider haben als Argumente die Laufzeitrepräsentierung des zugehörigen service bzw. reference und der des bindings.
Die Klasse ProxyPolicyProvider muss zusätzlich in der Datei org.apache.tuscany.sca.provider.PolicyProviderFactory im Verzeichnis src/main/resources/META-INF/services/ mit dem folgenden Eintrag (Quellcode
5.3) beschrieben werden.
1 org.apache.tuscany.sca.policy.proxy.ProxyPolicyProviderFactory;
2 model=org.apache.tuscany.sca.policy.proxy.ProxyPolicy
Quellcode 5.3: Konfiguration: ProxyPolicyProviderFactory-Datei
115
5.9. Proxy-Subsystem
Kapitel 5. Implementierung
ProxyPolicyDefinitionsProvider
Die Klasse ProxyPolicyDefinitionsProvider ist verantwortlich für das Einlesen der Policy-eigenen Datei definitions.xml. Der Pfad zur Datei wird als relativer Pfad in einem Attribut gesetzt. Quellcode 5.4 zeigt den Aufbau der Datei. Die Datei
befindet sich im Verzeichnis src/main/resources/org/apache/tuscany/sca/policy/proxy/.
1 <definitions xmlns="http://www.osoa.org/xmlns/sca/1.0"
2 targetNamespace="http://tuscany.apache.org/xmlns/sca/1.0"
3 xmlns:sca="http://www.osoa.org/xmlns/sca/1.0"
4 xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0">
5 <!-- Policy Intents Defined by the SCA Runtime -->
6 <intent name="proxy" constrains="sca:binding.ws">
7
<description>
8
All messages to and from this implementation must be proxied
9
</description>
10 </intent>
11 </definitions>
Quellcode 5.4: definitions.xml-Datei des QoS-Proxys
Über das Attribut constrains in Zeile 6 wird die Policy auf ein SCA-Element eingeschränkt. In Zeile 8 findet sich eine allgemeine Beschreibung des QoS-Proxys.
Über den Konstruktor wird der Wert eines weiteren Attributes vom Typ URLArtifactProcessor bestimmt. Der URLArtifactProcessor ermöglicht es, Model-Daten
aus einer URL, wie beispielsweise einem Dateipfad, auszulesen und zu verarbeiten.
Die Klasse ProxyPolicyDefinitionsProvider muss zusätzlich in der Datei
org.apache.tuscany.sca.definitions.SCADefinitionsProvider im
Verzeichnis src/main/resources/META-INF/services/ mit dem folgenden
Eintrag (Quellcode 5.5) beschrieben werden.
1 org.apache.tuscany.sca.policy.proxy.ProxyPolicyDefinitionsProvider
Quellcode 5.5: Konfiguration: SCADefinitionsProvider-Datei
5.9
Proxy-Subsystem
Die Klasse Proxy ist die zentrale Komponente in der Architektur des QoS-Proxys. In der
Klasse werden alle relevanten Klassen instanziiert. Der Proxy wird als Singleton [GHJ95]
116
Kapitel 5. Implementierung
5.9. Proxy-Subsystem
implementiert. Dies bedeutet, dass der Konstruktor der Klasse private ist. Im Konstruktur des Proxys werden das Statistic- und Manager-Objekte für den MBean
Server erzeugt und registriert.
Der ProxyPolicyProcessor liest die Datei definitions.xml einer SCAAnwendung ein und wandelt die Informationen aus der Datei in ein Modell der Policy um. Die Klasse ProxyPolicy entspricht dem Modell der Policy. Der Proxy erhält den Pfad zur Konfigurationsdatei über die Klasse ProxyPolicy, sobald der Pfad
über den ProxyPolicyProcessor gesetzt wird, wird das Proxy-Objekt zum ersten Mal aufgerufen. Über den Aufruf der Methode setConfigurationPath() wird
die Konfigurationsdatei des Proxys ausgelesen. Der Proxy erzeugt ein Objekt vom Typ
ConfigurationFileReader und ruft die Methode readConfigurationFile()
auf, die ein Objekt vom Typ Configuration zurückgibt, die die aus der Konfigurationsdatei ausgelesenen Werte speichert. In einem nächsten Schritt erzeugt der Proxy die
Queues mit der Methode initializeQueues().
Der Proxy erzeugt von jeder verfügbaren Queueing-Strategie ein Objekt und legt es in
einer Verwaltungsstruktur ab. Da jede Queueing-Strategie über ein Semaphor verfügt, die
mit 0 initialisiert wird, blockiert jede Strategie und wartet nicht aktiv auf Aufträge, die in
der Queue abgelegt werden. Mit der Methode setActiveStrategy() kann von der
aktive Queueing-Strategie auf eine neue Strategie gewechselt werden.
Über die Methode queue() übergibt die Klasse ProxyPolicyInterceptor ein
Item-Objekt an den Proxy. Im Proxy-Objekt wird die Priorität der Dienstgüteklasse bestimmt und im Item-Objekt abgelegt. Die Queueing-Strategie versetzt den Thread in den
Zustand Wartend. Die Klasse Item stellt dazu die Methode suspend() zur Verfügung.
Nach einer entsprechenden Zeit wird der Thread von der Queueing-Strategie bearbeitet
und über die Methode resume() in den Zustand Aktiv versetzt. Die Queueing-Strategie
setzt einen Messwert im ItemStatistic-Objekt des Items um die Verweilzeit in der
Queue festzuhalten.
Verschiedene Statistiken werden über den Proxy an das Monitoring-Subsytem weitergereicht. Die Methoden addItemStatistic() und addQueueStatistic übergeben ItemStatistic- und QueueStatistic-Objekte an das Monitoring-Subsystem.
Innerhalb der addItemStatistic()-Methode prüft der Proxy, ob für den Service
eine maximale Antwortzeit festgelegt wurde. Falls eine Antwortzeit festgelegt wurde,
prüft der Proxy, ob die Anforderungen eingehalten wurde. Wurde die Anforderungen verletzt, so informiert der Proxy den Manager.
117
5.10. Implementierungsaufwand
5.10
Kapitel 5. Implementierung
Implementierungsaufwand
In Tabelle 5.1 ist der Implementierungsaufwand aufgeschlüsselt nach Komponenten dargestellt.
5.11
Zusammenfassung
Der Anwendungsfall 3.1 beschreibt das Berücksichtigen von QoS-Anforderungen an Web
Services. In Kapitel 4 wurde der Anwendungsfall unter Berücksichtigung der vorgestellten Subsystemen in einem Sequenzdiagramm beschrieben. Die Funktionalität des QoSProxys soll anhand der log4j-Ausgabe der Implementierung unter Berücksichtigung des
Anwendungsfalldiagramms verdeutlicht werden.
Für den QoS-Proxy wurde auf Basis des in Abschnitt 2.1.4 vorgestellten TaschenrechnerWeb-Service mit Axis2 ein Client erzeugt. Der Übersichtlichkeit wegen wurde die log4jAusgabe unterteilt. Der Quellcode 5.6 beginnt mit Informationen zu den Konfigurationsdateien. In Zeile 2 wird der Ort und Name der Konfigurationsdatei ausgegeben und in
Zeilte 4 der der log4j-Konfigurationsdatei. In einem nächsten Schritt initialisiert die Klasse Proxy den Leaky-Bucket-Algorithmus (Zeile 5 bis 7) und die Queues der QueueingStrategie (Zeile 8 bis 16).
Zeile 18 zeigt den Ort und Namen der SLA-Konfigurationsdatei. In der SLA-Konfigurationsdatei befinden sich Agreements, die die Rahmenbedingungen für die QueueingStrategie definieren. Alternativ hätte die Konfigurationsdatei auch Agreement Templates beinhalten können, die das Konfigurationssubsystem des QoS-Proxys über RMI
an einem WSAG4J-System registriert hätte.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2008-12-06 18:01:53,929 [main] - Proxy - Configuration File Location:
/users/m_frey/Projekte/Diplom/trunk/src/Proxy/configuration.xml
2008-12-06 18:01:53,929 [main] - Proxy - Logging Configuration File Location:
/users/m_frey/Projekte/Diplom/trunk/src/Proxy/log4j.txt
2008-12-01 18:01:53,932 [main] - LeakyBucket - Start the Producer Thread
2008-12-01 18:01:53,961 [Leaky Bucket] - LeakyBucket - Rate is 1000 Number is 2 Size
is 10
2008-12-01 18:01:53,966 [main] - WeightedFairQueueingItemList - Set the divider to 2
2008-12-01 18:01:53,966 [main] - WeightedFairQueueingItemList - Set the maximum weight
to 8
2008-12-01 18:01:53,967 [main] - WeightedFairQueueingItemList - Creating queue with a
service class Gold, priority 0 and weight 4
2008-12-01 18:01:53,967 [main] - WeightedFairQueueingItemList - Creating queue with a
service class Silver, priority 1 and weight 2
2008-12-01 18:01:53,967 [main] - WeightedFairQueueingItemList - Creating queue with a
118
Kapitel 5. Implementierung
Datei
Queueing
Item.java
ItemList.java
ItemStatistic.java
LeakyBucket.java
Queue.java
QueueStatistic.java
Strategy.java
WeightedFairQueueing.java
WeightedFairQueueingItemList.java
Monitoring
Statistic.java
StatisticMBean.java
WS-Agreement
AgreementManager.java
TemplateManager.java
Konfiguration
Callback.java
ConfigurationFile.java
ConfigurationFileReader.java
ICallback.java
IServiceLevelManagement.java
Manager.java
ManagerMBean.java
ServiceClass.java
ServiceLevelAgreement.java
ServiceLevelAgreementFile.java
ServiceLevelAgreementList.java
Integration
ProxyImplementationPolicyProvider.java
ProxyPolicy.java
ProxyPolicyDefinitionsProvider.java
ProxyPolicyInterceptor.java
ProxyPolicyProcessor.java
ProxyPolicyProviderFactory.java
ProxyReferencePolicyProvider.java
ProxyServicePolicyProvider.java
Proxy
Proxy.java
Summe
5.11. Zusammenfassung
Leerzeilen Kommentare Code Summe
18
3
22
18
11
15
11
18
19
106
47
98
153
73
50
65
113
121
75
8
72
128
34
54
25
132
102
139
58
192
299
118
119
101
263
242
76
21
258
120
352
23
686
164
22
0
127
10
129
16
278
26
8
26
11
3
3
26
12
21
20
10
15
65
167
99
38
41
189
79
144
145
43
78
23
115
139
8
8
168
15
69
79
47
62
96
308
249
49
52
383
106
234
244
100
155
11
22
7
13
23
9
10
9
27
30
34
91
68
34
27
27
52
53
27
67
94
32
52
50
90
105
68
171
185
75
89
86
24
537
227
2994
239
2549
490
6080
Tabelle 5.1: Implementierungsaufwand sortiert nach Subsystemen
119
5.11. Zusammenfassung
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Kapitel 5. Implementierung
service class Bronze, priority 2 and weight 1
2008-12-01 18:01:54,008 [main] - Proxy - Available Strategies: 0. Weighted Fair Queueing
2008-12-01 18:01:54,009 [main] - Proxy - SLA File Location:
/users/m_frey/Projekte/Diplom/trunk/src/Proxy/log4j.txt
2008-12-01 18:01:54,033 [main] - ServiceLevelAgreementFile - Create agreement
CalculatorBronzeService for a CalculatorServiceBronze
2008-12-01 18:01:54,033 [main] - ServiceLevelAgreementFile - The proxy received a
agreement for a CalculatorServiceBronze. The name of the agreement is:
CalculatorBronzeService
2008-12-01 18:01:54,035 [main] - ServiceLevelAgreementFile - Agreement:
CalculatorBronzeService. Set response time to max: 400.0. The unit is: ms
2008-12-01 18:01:54,035 [main] - ServiceLevelAgreementFile - Agreement:
CalculatorBronzeService. Set throughput to min: 1.0 and max: 20.0. The unit is: rps
2008-12-01 18:01:54,035 [main] - ServiceLevelAgreementFile - Create agreement
CalculatorGoldService for a CalculatorServiceGold
2008-12-01 18:01:54,035 [main] - ServiceLevelAgreementFile - The proxy received a
agreement for a CalculatorServiceGold. The name of the agreement is:
CalculatorGoldService
2008-12-01 18:01:54,035 [main] - ServiceLevelAgreementFile - Agreement:
CalculatorGoldService. Set response time to max: 300.0. The unit is: ms
2008-12-01 18:01:54,035 [main] - ServiceLevelAgreementFile - Agreement:
CalculatorGoldService. Set throughput to min: 1.0 and max: 50.0. The unit is: rps
2008-12-01 18:01:54,036 [main] - Proxy - Adding SLA to list was successful
Quellcode 5.6: Logging: Initialisierung des QoS-Proxys
Um die Funktionalität des Queueings zu zeigen, wird ein Client der die Dienstgüteklasse
Bronze und ein Client der die Dienstgüteklasse Gold nutzt gestartet. Beide Clients erzeugen jeweils 5 Threads die 15 Web-Service-Anfragen stellen. In Quellcode 5.7 ist zu sehen,
dass eine Web-Service-Anfrage eintrifft (Zeile 1 und 2) und dass es sich dabei um einen
Bronze-Client handelt (Zeile 3 und 4). Die Anfrage wird direkt aus der Bronze-Queue von
der Queueing-Strategie entnommen. Die Anzahl der wartenden Aufträge ist Null (Zeile
10 bis 12).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2008-12-01 18:05:57,073 [http-172.25.48.142-8080-Processor24] - Proxy -Add thread item
to the list
2008-12-01 18:05:57,073 [http-172.25.48.142-8080-Processor24] - Item - Try to suspend
thread with id 49 and service class Bronze
2008-12-01 18:05:57,073 [Weighted Fair Queueing] - LeakyBucket - Number of tokens
available: 10
2008-12-01 18:05:57,073 [http-172.25.48.142-8080-Processor23] - Proxy - Add thread item
to the list
2008-12-01 18:05:57,073 [Weighted Fair Queueing] - WeightedFairQueueingItemList Items in Queue 0 : 0
Items in Queue 1 : 0
Items in Queue 2 : 0
2008-12-01 18:05:57,073 [Weighted Fair Queueing] - WeightedFairQueueing - Schedule
thread with service class Bronze.
2008-12-01 18:05:57,073 [Weighted Fair Queueing] - WeightedFairQueueing - Weight
(Total): 1 (Used): 1
120
Kapitel 5. Implementierung
5.11. Zusammenfassung
Quellcode 5.7: Logging: Bearbeiten einer Web-Service-Anfragen
Nach einer gewissen Zeit sind die Tokens verbraucht und die Queueing-Strategie muss
solange warten bis wieder Tokens verfügar sind. In Quellcode 5.8 ist erkennbar, dass zur
Zeit 4 Gold-Anfragen (Queue 0) und vier Bronze-Anfragen (Queue 3) auf Bearbeitung
warten. Die fünfte Gold-Anfrage wird gerade bearbeitet (Zeile 11). In Zeile 6 ist zu sehen,
dass nur noch ein Token verfügbar ist, der allerdings von der gerade bearbeiteten GoldAnfrage verwendet wurde.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2008-12-01 18:05:59,075 [Weighted Fair Queueing] - Item - Try to resume thread
with id 36 and service class Bronze
2008-12-01 18:05:59,075 [Weighted Fair Queueing] - Item - Resume thread with id
36 and service class Bronze
2008-12-01 18:05:59,075 [Weighted Fair Queueing] - LeakyBucket - Number of tokens
available: 1
2008-12-01 18:05:59,075 [Weighted Fair Queueing] - WeightedFairQueueingItemList Items in Queue 0 : 4
Items in Queue 1 : 0
Items in Queue 2 : 4
2008-12-01 18:05:59,075 [Weighted Fair Queueing] - WeightedFairQueueing - Schedule
thread with service class Gold.
2008-12-01 18:05:59,075 [Weighted Fair Queueing] - WeightedFairQueueing - Weight
(Total): 4 (Used): 1
2008-12-01 18:05:59,075 [Weighted Fair Queueing] - ItemStatistic - Calculates
the exposure time to 1.228583159075905E12 - 1.228583158113223E12 = 962.68212890625
2008-12-01 18:05:59,076 [Weighted Fair Queueing] - Item - Try to resume thread
with id 33 and service class Gold
2008-12-01 18:05:59,076 [Weighted Fair Queueing] - Item - Resume thread with id
33 and service class Gold
2008-12-01 18:05:59,076 [Weighted Fair Queueing] - LeakyBucket - Number of tokens
available: 0
Quellcode 5.8: Logging: Wartende Web-Service-Anfragen
Das Gewicht von Queue 0 garantiert dem Gold-Client, dass mindestens 4 Gold-Anfragen
bearbeitet werden. Die Queue für Bronze-Anfrage hat nur ein Gewicht von 1, was bedeutet, dass bei vielen Gold- und Silber-Anfragen höchstens nur 1 Bronze-Auftrag bearbeitet
wird. Für die Bearbeitung durch den QoS-Proxy benötigt ein Bronze-Client mit 5 Threads
mit je 25 Anfragen 1 Minute und 16 Sekunden, ein Gold-Client 59 Sekunden.
121
5.11. Zusammenfassung
Kapitel 5. Implementierung
122
Kapitel 6
Bewertung
Das vorliegende Kapitel soll eine Bewertung des implementierten QoS-Proxy für SOADienste durchführen. Dabei gliedert sich das Kapitel in einer architekturelle Bewertung
und eine Bewertung der Leistungsfähigkeit des QoS-Proxys. Innerhalb der Leistungsbewertung wird in einem ersten Schritt das zugrunde liegende Messmodell vorgestellt,
das die Art und Weise des Messaufbaus in Zusammenspiel mit der gegebenen Hardware
beschreibt. Anschließend werden die Messungen durchgeführt und die Ergebnisse interpretiert.
6.1
Bewertung der Architektur
Der QoS-Proxy implementiert den Weighted-Fair-Queueing- und Leaky-Bucket-Algorithmus. Das Ziel weitere Queueing-Strategien zu implementieren konnte aus Zeitgründen
nicht umgesetzt werden.
Innerhalb der Aufrufkette von Tuscany ist es in der verwendeten Version 1.2.1 nicht möglich den Client einer Web-Service-Anfrage zu ermitteln. Informationen zum Client werden vor der Aufrufkette aus der Nachricht entfernt. Aus diesem Grund kann ein SLA nicht
eindeutig einem Client zugewiesen werden. Problematisch wird das insbesondere, wenn
man eine Art Abrechnungsmodell für die vom QoS-Proxy bereitgestellten Dienste zur
Verfügung stellen möchte. Demnach ist es nur möglich nach Dienst und nicht nach Client
abzurechnen. Für zukünftige Versionen von Tuscany ist es angedacht, Informationen zum
Client, wie beispielsweise die IP, in der Nachricht zu belassen. Alternativ wäre es vorstellbar eine weitere Policy neben dem QoS-Proxy für eine SCA-Anwendung einzubinden. In
der Entwicklerversion von Tuscany gibt es eine Policy, die eine Authentifizierung auf
123
6.2. Bewertung der Leistungsfähigkeit
Kapitel 6. Bewertung
Basis von Tokens ermöglicht. Der Token wird dabei in den SOAP Header der Nachricht
eingebunden. Der Inhalt des Tokens ist frei wählbar und so wäre es denkbar, Informationen zum Client im Token zu hinterlegen.
Zur Zeit ist die QoS-Proxy-Policy nur auf das implementation.java-Elemente anwendbar und verletzt damit den generischen Aspektes des QoS-Proxys. Damit schränkt
der QoS-Proxy auf SCA-Anwendungen ein die in Java implementiert wurden. Zusätzlich ist es nicht möglich, den QoS-Proxy auf service-Elemente anzuwenden, deren Implementierung nicht lokal ist. Einschränkungen für eine Policy werden in Tuscany über die Policy-eigene Datei definitions.xml gesetzt. Um den QoS-Proxy
auf das binding.ws-Element einzuschränken, hätte es ausreichen müssen, in der Datei im intent-Element das Attribut constrain auf den Wert sca:binding.ws
statt sca:implementation.java zu setzen. In einer SCA-Anwendung hätte in der
definitions.xml der Anwendung das constrain-Attribut statt auf sca:implemenation das Attribut auf sca:service/sca:binding.ws gesetzt werden müssen. Verschiedene Tests haben leider zu keinem verwendbaren Ergebnis geführt.
6.2
6.2.1
Bewertung der Leistungsfähigkeit
Versuchsaufbau
Alle Messungen wurden auf einem Intel Core 2 Duo mit 1,86 Ghz und 2 GB RAM durchgeführt. Als Betriebssystem wurde Ubuntu/Linux mit einem Kernel in der Version 2.6.24
verwendet. Als Java Runtime diente, wie schon bei der Implementierung, das JDK von
SUN in der Version 1.5.0_15. Zusätzlich wurde Grinder [AF08], ein ein Java-basiertes
Lasttest-Framework, für die Messungen verwendet.
Abbildung 6.1 zeigt die drei prinzipiellen Versuchsaufbauten, die dazu dienen den QoSProxy zu bewerten. Im Versuchsaufbau 1 werden die Messungen ohne den QoSProxy durchgeführt. Die Messungen dienen als Referenz für die Beurteilung des Overheads durch den QoS-Proxy. Im zweiten Versuchsaufbau (Versuchsaufbau 2) wird
der QoS-Proxy zum Web Service hinzugefügt, allerdings werden Web-Service-Anfragen
nicht in Queues einsortiert. Der Versuch dient als Referenz für das Ermitteln des Aufwandes der entsteht wenn eine Web-Service-Anfrage in eine Queue einsortiert wird.
Versuchsaufbau 3 erweitert den vorherigen Versuchsaufbau um das Queueing von
Web-Service-Anfragen.
124
Kapitel 6. Bewertung
6.2. Bewertung der Leistungsfähigkeit
Versuchsaufbau 1
Client
Web Service
Requests
Versuchsaufbau 2
Client
Requests
QoS-Proxy
Web Service
Requests
QoS-Proxy
Web Service
Versuchsaufbau 3
Client
Abbildung 6.1: Aufbau der Versuche für die Leistungsbewertung
Für alle Versuche wird mit Grinder eine Web-Service-Anfrage an einen Web Service aufgezeichnet. Dabei wird der bereits in der Implementierung in 5.11 benutzte Client verwendet. Als Web Service wird der in 2.1.4 vorgestellte Taschenrechner-Web-Service eingesetzt. Die Aufzeichnung zwischen einem Client und dem Web Service erfolgt über
den TCPProxy des Grinders. Der TCPProxy zeichnet dabei die Web-Service-Anfrage
auf und generiert aus der Anfrage ein Python-Testskript. Das erzeugte Testskript ist
Grundlage für Messung. Die Web-Service-Anfrage ruft über den Taschenrechner-WebService den Add-Service auf und addiert zwei Zahlenwerte. Der Web-Service erhält zwei
java.lang.double-Parameter und liefert ein Ergebnis als java.lang.double
zurück.
Alle beteiligten Komponenten werden ohne Optimierungen eingesetzt. Um die Ergebnisse nicht durch zusätzlichen I/O Overhead zu verfälschen wird das Log Level von Tomcat
und Tuscany auf WARNING beziehungsweise ERROR gesetzt.
Mit den aufgeführten Versuchsaufbauten werden insgesamt fünf Messreihen durchgeführt. In jeder Messreihe ruft der Grinder fünftausendmal einen Web Service auf.
6.2.2
Auswertung der Messungen
Versuch 1 wurde ohne den QoS-Proxy durchgeführt und zeigt auch bei mehreren Messreihen relativ ähnliche Ergebnisse. Für den nächsten Versuch wurde der QoS-Proxy in die
Anwendung eingebunden, allerdings wurde in der Konfigurationsdatei des QoS-Proxys
125
6.2. Bewertung der Leistungsfähigkeit
Kapitel 6. Bewertung
keine Dienstgüteklassen hinterlegt. Der QoS-Proxy prüft vor dem Einfügen in eine Queue,
ob eine Dienstgüteklasse für den aufgerufenen Web-Service existiert. Der Versuch 1 erweitert Versuch 2 um einen weiteren Interceptor in der Aufrufkette der Anwendung, einer
Prüfung der aufrufenden URL des Web Services sowie die Initialisierung der Subsysteme
des QoS-Proxys. Die Auswirkungen auf das Antwortzeitverhalten sind zwischen Versuch
1 und 2 geringfügig.
In Versuch 3 wurden für den QoS-Proxy in der Konfigurationsdatei Dienstgüteklassen
hinterlegt, so dass der QoS-Proxy eingehende Aufträge klassifizieren und in eine Queue
einsortieren kann. Im Vorlauf zur Messung zeigten sich bei einer Probemessung Spitzen
in den Messwerten von bis zu 1000 ms. Zeitlich betrachtet waren die Spitzen am Anfang
der Messung, konnten aber bei den folgenden Messreihen nicht erfasst werden.
Tabelle 6.1 enthält die Mittelwerte der Versuche 1 bis 3. Um eine Einschätzung zu den
Werten geben zu können sollten weitere Versuche erfolgen. Eine Standardabweichung
von fast 2,4 ms bei einem einfachen Web Service erscheint nicht normal. Aus Zeitgründen
konnte das Verhalten nicht näher untersucht werden.
Versuch Min [ms] Max [ms] Mittelwert [ms] Standardabweichung [ms]
1
9
59
12,65
2,37
2
9
77
12,84
2,69
3
9
103,2
13,01
3,23
Tabelle 6.1: Mittelwerte der Versuch 1 bis 3
6.2.3
Zusammenfassung
Das Antworzeitverhalten des QoS-Proxys wird durch die Token-Erzeugungsrate, das Gewicht der jeweiligen Queue und die Anzahl der Aufträge im QoS-Proxy beeinflusst. Tests
mit einem einfachen Axis2-basierten Client, der eine Reihe von Operationen durchführt,
haben gezeigt, dass sich Auswirkungen auf das Antwortzeitverhalten besonders stark bei
einer Reihe von einander abhängigen Web-Service-Anfragen äußern.
Der mit Grinder erzeugte Test ruft nur einen Service auf und so ist es naheliegend ein
Testszenario aufzubauen dass eine Reihe von Web-Service-Anfragen durchführt und das
Ergebnis jeder Anfrage für eine neue Berechnung verwendet. Aus Zeitgründen konnte keine Bandbreitentest durchgeführt werden. Dieser Test sollte verteilt auf mehreren
Rechnern erfolgen.
126
Kapitel 7
Zusammenfassung
Diese Arbeit entstand im Labor für Verteilte Systeme (DOPSY) an der Fachhochschule Wiesbaden im Rahmen des Projektes ”Selbstmanagement am Beispiel Serviceorientierter Architekturen”. Ziel der Arbeit war das Design und die Implementierung eines
generischen QoS-Proxys für SOA-Dienste. Der zu entwickelnde QoS-Proxy sollte dazu
mit Hilfe der Service Component Architecture transparent in bestehende Web-servicebasierte Anwendungen integriert werden.
In einem ersten Schritt wurden in der Analyse die Anforderungen an den QoS-Proxy
formuliert. Dazu gehört die transparente Integrierbarkeit des QoS-Proxys in bestehende
SCA-Anwendungen, das Queueing von Web-Service-Anfragen, Monitoring des Laufzeitverhaltens sowie die Konfiguration des QoS-Proxys zur Laufzeit.
Zunächst wurde die SCA auf mögliche Erweiterungspunkte untersucht. Dabei stellte
sich heraus, dass der QoS-Proxy sich am besten über eine SCA-Policy in eine SCAAnwendung integerieren lässt.
Im weiteren wurden Queueing-Strategien des Linux Kernels auf Ihre Eignung für
das Queueing von Web-Service-Anfragen betrachtet. Zu den betrachteten QueueingStrategien gehört das Multi Band Priority Queueing, Stochastic Fairness Queueing,
Weighted Fair Queueing, Class Based Queueing sowie der Hierarchical-Token-BucketAlgorithmus. Als Token-Verfahren zur Realisierung von Bandbreitenanforderungen wurde der Leaky-Bucket-Algorithmus untersucht. Bei der Analyse geeigneter QueueingStrategien stand im Vordergund die Möglichkeit Anforderungen an Durchsatz und Antwortzeit mit einer entsprechenden Queueing-Strategie umzusetzen. Eine Kombination aus
dem Weighted-Fair-Queueing-Algorithmus mit dem Leaky-Bucket-Algorithmus hat sich
bei der Betrachtung hierfür als besonders geeignet erwiesen.
127
Kapitel 7. Zusammenfassung
Ausgehend von den in der Analyse getroffenen Entscheidungen wurde ein Konzept für
einen QoS-Proxy erstellt. In der Grobarchitektur des QoS-Proxys wurden die einzelne Subsysteme identifiziert und in einem Business und Service Layer aufgeteilt. Beim
Entwurf der einzelnen Subsysteme wurde auf eine flexible Erweiterbarkeit der Architektur Wert gelegt. Der Proxy soll in eine SCA-Policy integriert werden. Dabei bietet der
Proxy unterschiedliche Dienstgüteklassen zu einem Web Service an, die alle auf die selbe
Implementierung verweisen. Kern der Architektur ist das Queueing-Subsystem, das die
Queueing-Strategien und für das Queueing benötigten Datenstrukturen bereitstellt. Aufgabe des Queueing-Subsystems ist das Queueing von Web-Service-Anfragen. Eine eigene
Klasse zum Sammeln von Messwerten erleichtert das Prüfen von Dienstgüteanforderungen.
Das Monitoring-Subsystem umfasst die Klassen die zur Sammlung und zur Erzeugung von Statistiken der einzelnen Subsysteme benötigt werden. Verantwortlich für
die Konfiguration des QoS-Proxy ist das Konfigurationssubsystem. Dabei werden die
Management-Operationen für die im Queueing-Subsystem definierten Algorithmen über
JMX zur Verfügung gestellt. Zusätzlich besitzt das Konfigurationssubsystem eine Schnittstelle um einen vertraglichen Rahmen für die Anforderungen an den QoS-Proxy und der
bereitgestellten Services zu definieren.
Im Anschluß an den Entwurf wurde eine prototypische Implementierung des QoSProxys vorgenommen. Der QoS-Proxy wurde dabei in eine Policy für Apache Tuscany, das eine Umsetzung der SCA Spezifikation 1.0 bereitstellt, integriert. Als QueueingStrategie wurde der Weighted-Fair-Queueing-Algorithmus zusammen mit dem LeakyBucket-Algorithmus implementiert. Innerhalb der Architektur von Tuscany wird pro
Web-Service-Anfrage ein Thread erzeugt. Das erlaubt es anstatt der Nachricht den aufrufenden Thread in einer Queue einzusortieren und nach einer Queueing-Strategie abzuarbeiten. Ein bestehendes WSAG4J-System wurde um Funktionalität zur Registrierung
von Templates erweitert und ein zusätzlicher Callback-Mechanismus implementiert, der
es erlaubt den QoS-Proxy neben allgemeinen Informationen über neue Agreements und
der Terminierung von Agreements zu informieren. Die Monitoring- und Konfigurationskomponenten stellen Teile ihrer Funktionalität über JMX zur Verfügung. Mit Hilfe von
Management-Anwendungen kann somit die Funktionalität des QoS-Proxys nachvollzogen werden. Exportmöglichkeiten aus dem Monitoring-Subsystem heraus erlauben eine
spätere und einfachere Auswertung des Laufzeitverhalten. Aus Zeitgründen konnten keine weitere Queueing-Strategien implementiert werden. Der generische Aspekt des QoSProxys wird durch die Einschränkung auf sca:implementation.java verletzt, verschiedene Tests konnten die Ursache dafür nicht näher eingrenzen.
128
Kapitel 7. Zusammenfassung
Mit Hilfe eines Beispiel-Clients auf Basis von Axis2 wurde ein Test der Funktionalität
durchgeführt. Dabei wurden für einen Web-Service mehrere Dienstgüteklassen erzeugt.
Der Test sollte die Priorisierung der angebotenen Services verdeutlichen und zusätzlich
die Funktionalität der Queueing-Strategie Weighted Fair Queueing präsentieren.
Nach der Analyse und einem ersten funktionalen Test erfolgte eine architekturelle Bewertung des QoS-Proxys. Dabei wurden insbesondere Schwachstellen in der vorliegenden
Implementierung hervorgehoben und mögliche Verbesserungsansätze vorgestellt. Der architekturellen Bewertung folgte ein Bewertung der Leistungsfähigkeit des QoS-Proxys.
In einem ersten Schritt wurde das zugrunde liegende Messmodell vorgestellt. Darauf aufbauend wurden Messungen vorgenommen um den Overhead durch den QoS-Proxy zu
ermitteln. Ein weiterer Test zur Überprüfung der Bandbreitenanforderungen des QoSProxys konnte aus Zeitgründen nicht durchgeführt werden. Das Ergebnis der Bewertung
des Overheads ist nicht eindeutig und soll durch weitere Tests ermittelt werden.
Im Rahmen dieser Arbeit wurde die Möglichkeit geschaffen Web-Service-Anfragen unter
Berücksichtigung von Dienstgüteanforderungen umzusetzen. Grundlage für weitere Arbeiten am QoS-Proxy sollte die Portierung auf eine aktuelle Version von Tuscany sein. Zur
Zeit arbeiten die Apache Tuscany Entwickler an einer Aktualisierung des Policy-Modells
in der Tuscany-Architektur. Eine neueren Version von Tuscany erlaubt es die QoS-ProxyPolicy auf das binding.ws-Element einzuschränken. Um eine umfassendere Bewertung des QoS-Proxys zu ermöglichen sollten weitere Queueing-Strategien implementiert
werden. Besonders Queueing-Strategien die ein Hierarchie-Modell von Dienstgüteklassen unterstützen sind dabei von Interesse. Queueing-Strategien die hierarchische Strukturen unterstützen eignen sich für spezielle Anwendungsfälle.
In der aktuellen Version des Policy-Modells von Tuscany wird die IP des Clients, der eine
Web-Service-Anfrage stellt, bereits vor der Aufrufkette aus der SOAP-Nachricht entfernt.
Die Entwicklerversion von Tuscany bietet Ansätze zur Umgehung dieser Problematik.
Bisher erfolgt die Anpassung einer SCA-Anwendung manuell. Ein graphisches Werkzeug würde das Anpassen, insbesondere bei komplexen und umfangreichen SCAAnwendungen erheblich erleichtern. Das Werkzeug könnte die composite-Dateien einer Anwendung analysieren, Services zur Auswahl stellen für die das Dienstgütemanagement aktiviert werden soll und verschiedene Dienstgüteklassen zur Auswahl stellen. Die
graphische Anwendung könnte in einem weiteren Schritt um einen Editor für die Konfigurationsdatei des QoS-Proxys erweitert werden.
Workflow-Beschreibungen in Form der BPEL sind in vielen Geschäftsanwendungen weit
verbreitet. Einzelne Aktivitäten in einem BPEL-basierten Workflow erfolgen auf Basis
129
Kapitel 7. Zusammenfassung
von Web Services. Eine Erweiterung des QoS-Proxys könnte solche Workflows berücksichtigen und unterschiedliche Wertigkeiten für verschiedene Web Services offerieren.
Insbesondere die Koordinationen von verteilten Web Services und der Umsetzung durch
den QoS-Proxy bietet eine interessante Herausforderung.
Langfristig sollte der QoS-Proxy um eine Bewertungsplattform erweitern werden. Dabei
sollte ein Abrechnungsmodell eingeführt werden, dass es erlaubt die Nutzung der Web
Services des QoS-Proxys abzurechnen. Aufgeschlüsselt nach Client und Dienstgüteklasse kann das Abrechnungsmodell in eine Service-Level-Management-Plattform integriert
werden.
130
Kapitel 8
Literaturverzeichnis
[ACD+ 07]
A NDRIEUX, Alain ; C ZAJKOWSKI, Karl ; DAN, Asit ; K EAHEY,
Kate ; L UDWIG, Heiko ; NAKATA, Toshiyuki: Web Services Agreement Specification (WS-Agreement).
V1.0.
Open Grid Forum,
P.O. Box 2326, Joliet, Illinois 60434 USA: Open Grid Forum,
März 2007.
http://forge.gridforum.org/sf/docman/
do/downloadDocument/projects.graap-wg/docman.
root.published_documents.web_services_agreement_
specifica/doc14574
[AF08]
A STON, Philip ; F ITZGERALD, Calum: The Grinder 3 - Complete User
Guide, August 2008. http://grinder.sourceforge.net/g3/
manual.pdf
[BBB+ 07]
B EISIEGEL, Michael ; B LOHM, Henning ; B OOZ, Dave ; E DWARDS, Mike
; H URLEY, Oisin ; I ELCEANU, Sabin: SCA Assembly Model. V1.0. Open
Service Oriented Architecture, März 2007. http://www.osoa.org/
download/attachments/35/SCA_AssemblyModel_V100.pdf
[BBC+ 07a] B EISIEGEL, Michael ; B OOZ, Dave ; C HAO, Ching-Yun ; E DWARDS, Mike
; I ELCEANU, Sabin: SCA Policy Framework. V1.0. Open Service Oriented Architecture, März 2007. http://www.osoa.org/download/
attachments/35/SCA_Policy_Framework_V100.pdf
[BBC+ 07b] B ERGLUND, Anders ; B OAG, Scott ; C HAMBERLIN, Don ; F ERNÁNDEZ,
Mary F. ; K AY, Michael ; ROBIE, Jonathan ; S IMÉON, Jérôme: XML Path
Language (XPath). V2.0. Massachusetts Institute of Technology,32 Vassar
131
Kapitel 8. Literaturverzeichnis
Street, Cambridge, MA 02139 USA: W3C, Januar 2007. http://www.
w3.org/TR/xpath20/
[BEA03]
BEA Systems Inc.: Streaming API for XML JSR-173 for Java Specification.
1. Auflage. Oktober 2003
[Blo08]
B LOCH, Joshua: Effective Java: A Programming Language Guide. 2. Auflage : Addison-Wesley Longman, 2008 (The Java Series). – 384 S
[BVP06]
B ON, Jan von ; V EEN, Annelies van d. ; P IEPER, Mark: Foundations in IT
Service Management basierend auf ITIL. Van Haren Publishing, 2006
[CFSD90]
C ASE, J. ; F EDOR, M. ; S CHOFFSTALL, M. ; DAVIN, J.: RFC1157 - Simple
Network Management Protocol. IETF Secretariat c/o Association Management Solutions, LLC (AMS) 48377 Fremont Blvd., Suite 117 Fremont,
California 94538 USA: Internet Engineering Task Force Network Working
Group, Mai 1990
[Deb04]
D EBUSMANN, Markus: Modellbasiertes Service Level Management verteilter Anwendungssysteme, Universität Kassel, Diss., Dezember 2004
[Dis05]
Distributed Management Task Force: CIM Infrastructure Specification.
v2.3. Oktober 2005
[DKS89]
D EMERS, A. ; K ESHAV, S. ; S HENKER, S.: Analysis and simulation of a
fair queueing algorithm. In: SIGCOMM ’89: Symposium proceedings on
Communications architectures & protocols. New York, NY, USA : ACM,
1989. – ISBN 0–89791–332–9, S. 1–12
[Erl07]
E RL, Thomas: SOA Principles of Service Design. 1. Auflage. Prentice Hall
International, 2007 (Prentice Hall Service-Oriented Computing Series from
Thomas Erl). – 608 S
[Fen08]
F ENG, Raymond: Extending Tuscany. http://tuscany.apache.org/scajava-extension-development-guide.data/ExtendingTuscany1.pdf.
Version: Juni
2008.
http://tuscany.apache.org/
sca-java-extension-development-guide.data/
ExtendingTuscany1.pdf. – Präsentation
[FJ95]
F LOYD, Sally ; JACOBSON, Van: Link-sharing and Resource Management
Models for Packet Networks. In: IEEE/ACM Transactions on Networking 3
132
Kapitel 8. Literaturverzeichnis
(1995), August, S. 365 – 386. http://dx.doi.org/10.1109/90.
413212. – DOI 10.1109/90.413212
[Fou08]
F OUNDATION, Apache S.: Apache Tuscany SCA Java Architecture Guide.
http://tuscany.apache.org/sca-java.html, 2008
[FW04]
FALLSIDE, David C. ; WALMSLEY, Priscilla: XML Schema Part 0: Primer
Second Edition. V1.1. Massachusetts Institute of Technology,32 Vassar
Street, Cambridge, MA 02139 USA: W3C, Oktober 2004. http://www.
w3.org/TR/xmlschema-0/
[GC01]
G OVERNMENT C OMMERCE, Office of: Service Delivery. Stationery Office,
2001 (IT Infrastructure Library Series)
[GHJ95]
G AMMA, Erich ; H ELM, Richard ; J OHNSON, Ralph E.: Design Patterns.
Elements of Reusable Object-Oriented Software. 1. Auflage. AddisonWesley, 1995
[Gup05]
G UPTA, Samudra: Pro Apache Log4j. 2. Auflage. APress, 2005. – 224 S
[Ham01]
H AMILTON, Graham: Java Logging APIs. Sun Microsystems Incoperated,
901 San Antonio Road, Palo Alto, California 94303, U.S.A: Sun Microsystems, September 2001
[Hof00]
H OFFMANN, Ulrich: Modellierung von Kommunikationssystemen. 1. Auflage. Fortis, 2000. – 182 S
[JN06]
J OHNSON, Chris D. ; NARESH, Revanuru:
Concurrency Utilities
for Java EE, April 2006.
http://gee.cs.oswego.edu/dl/
concurrencyee-interest/ConcurrencyUtilsEE_Early_
Draft_Preview_V01.pdf
[Knu98]
K NUTH, Donald E.: The Art of Computer Programming. Bd. 3. Addison
Wesley, 1998. – 780 S
[Kö07]
KÖHLER, Peter T.: ITIL. 2. Auflage. Springer, 2007. – 396 S
[KS93]
K LEMM, Liesel ; S CHWELLENBACH, Detlef: Leistungsmessung in verteilten Systemen: Meßmodell, Implementierung, Anwendung. (1993). http:
//www.scientificcommons.org/26091074
133
Kapitel 8. Literaturverzeichnis
[Lew99]
L EWIS, Lundy: Service Level Management of Enterprise Networks. 1.
Auflage. Artech House, 685 Canton Street, Norwood, MA 02062, USA :
Artech House, 1999. – 326 S
[McK90]
M C K ENNEY, P.E.: Stochastic fairness queueing. In: INFOCOM ’90. Ninth
Annual Joint Conference of the IEEE Computer and Communication Societies. ’The Multiple Facets of Integration’. Proceedings., IEEE (1990), June,
S. 733–740 vol.2. http://dx.doi.org/10.1109/INFCOM.1990.
91316. – DOI 10.1109/INFCOM.1990.91316
[PG93]
PAREKH, Abhay K. ; G ALLAGER, Robert G.: A generalized processor sharing approach to flow control in integrated services networks: the
single-node case. In: IEEE/ACM Transactions on Networking 1 (1993),
Nr. 3, 344–357. http://dx.doi.org/http://dx.doi.org/10.
1109/90.234856. – DOI http://dx.doi.org/10.1109/90.234856. – ISSN
1063–6692
[SMS+ 02]
S AHAI, Akhil ; M ACHIRAJU, Vijay ; S AYAL, Mehmet ; J IN, Li J. ; C ASATI,
Fabio: Automated SLA Monitoring for Web Services. In: Lecture Notes in
Computer Science 2506 (2002), S. 28–41
[Sun02]
Sun Microsystems:
Java Management Extensions (JMX) Specification.
V1.2.
Oktober 2002.
http://jcp.org/aboutJava/
communityprocess/final/jsr003/index3.html
[Sun04]
Sun Microsystems: Java Remote Method Invocation Specification. V1.5.
2004. http://java.sun.com/j2se/1.5/pdf/rmi-spec-1.
5.0.pdf
[Sun06]
Sun Microsystems: Java Management Extensions (JMX) Specification.
V1.4. November 2006. http://java.sun.com/javase/6/docs/
technotes/guides/jmx/JMX_1_4_specification.pdf
[SV95]
S HREEDHAR, M. ; VARGHESE, George:
Efficient fair queueing using deficit round robin.
In: SIGCOMM Comput. Commun. Rev. 25 (1995), Nr. 4, S. 231–242.
http://dx.doi.
org/http://doi.acm.org/10.1145/217391.217453. – DOI
http://doi.acm.org/10.1145/217391.217453. – ISSN 0146–4833
[Tan02]
TANENBAUM, Andrew S.: Computer Networks. 4. Auflage. Prentice Hall,
2002. – 912 S
134
Kapitel 8. Literaturverzeichnis
[Tan07]
TANENBAUM, Andrew S.: Modern Operating Systems. 3. Auflage. Prentice
Hall, 2007. – 1104 S
[TG05]
T RAN -G IA, Phuoc: Einführung in die Leistungsbewertung und Verkehrstheorie. 2. Auflage. Oldenbourg, 2005. – 284 S
[Tur02]
T URNER, J.S.: New directions in communications (or which way to the information age?). In: Communications Magazine, IEEE 40 (2002), May,
Nr. 5, S. 50–57. http://dx.doi.org/10.1109/MCOM.2002.
1006972. – DOI 10.1109/MCOM.2002.1006972. – ISSN 0163–6804
[VMSE+ 04] VALENZUELA, J.L. ; M ONLEON, A. ; S AN E STEBAN, I. ; P ORTOLES,
M. ; S ALLENT, O.: A hierarchical token bucket algorithm to enhance
QoS in IEEE 802.11: proposal, implementation and evaluation. In: Vehicular Technology Conference, 2004. VTC2004-Fall. 2004 IEEE 60th 4
(2004), Sept., S. 2659–2662 Vol. 4. http://dx.doi.org/10.1109/
VETECF.2004.1400539. – DOI 10.1109/VETECF.2004.1400539. –
ISSN 1090–3038
135
Kapitel 8. Literaturverzeichnis
136
Anhang A
Abkürzungen
A
API
Application Programming Interface.
B
BPEL
Business Process Execution Language.
C
CBQ
Class Based Queuing.
CIM
Common Information Model.
D
DMTF
Distributed Management Task Force.
E
EAR
Enterprise Application Archive.
EJB
Enterprise Java Beans.
EPR
Endpoint Reference.
137
Anhang A. Abkürzungen
F
FIFO
First In First Out.
G
GRAAP
Grid Resource Allocation Agreement Protocol.
H
HTB
Hierarchical Token Bucket.
I
ITIL
IT Infrastructure Library.
J
J2SE
Java 2 Standard Edition.
JAR
Java Archive.
JAXB
Java Architecture for XML Binding.
JBI
Java Business Integration.
JEE
Java Enterprise Edition.
JMX
Java Management Extensions.
JSR
Java Specification Request.
L
LB
Leaky Bucket.
Q
QoS
Quality of Service.
138
Anhang A. Abkürzungen
S
SCA
Service Component Architecture.
SFQ
Stochastic Fairness Queuing.
SLA
Service Level Agreement.
SLM
Service Level Management.
SLO
Service Level Objective.
SLR
Service Level Requirement.
SNMP
Simple Network Management Protocol.
SOA
Service Oriented Architecture.
StAX
Streaming API for XML.
W
WAR
Web Archive.
WBEM
Web-Based Enterprise Management.
WCF
Windows Communication Foundation.
WFQ
Weighted Fair Queuing.
WSAG4J Web Service Agreement for Java.
WSDL
Web Service Description Language.
X
XML
Extensible Markup Language.
XSLT
Extensible Stylesheet Language Transformation.
139
Anhang A. Abkürzungen
140
Anhang B
Messwerttabellen für den QoS-Proxy
Messreihe Min [ms] Max [ms]
1
9
56
2
9
59
3
9
64
4
9
60
5
9
56
Mittelwert [ms] Standardabweichung [ms]
12,72
2,32
12,45
2,37
12,62
2,29
12,77
2,42
12,67
2,43
Tabelle B.1: Messwerte für Versuch 1
Messreihe Min [ms] Max [ms]
1
10
107
2
9
70
3
9
69
4
9
73
5
9
66
Mittelwert [ms] Standardabweichung [ms]
13,35
3,24
12,86
2,72
12,40
2,38
13,13
2,7
12,47
2,4
Tabelle B.2: Messwerte für Versuch 2
141
Anhang B. Messwerttabellen für den QoS-Proxy
Messreihe Min [ms] Max [ms] Mittelwert [ms] Standardabweichung [ms]
1
9
93
13,34
2,77
2
9
56
13,05
2,9
3
9
64
12,92
2,76
4
9
228
12,83
3,9
5
9
75
13,01
3,23
Tabelle B.3: Messwerte für Versuch 3
142
Anhang C
Inhalt des Datenträgers
Der Inhalt des dieser Arbeit beiliegenden Datenträgers gliedert sich in die folgenden fünf
Verzeichnisse:
1. Im Verzeichnis Text befindet sich der Text dieser Arbeit als PDF-Datei.
2. Das Verzeichnis Source enthält die Quellen der Arbeit. Zu den Quellen gehören:
• der QoS-Proxy,
• die verwendete Apache-Tuscany-SCA-Implementierung,
• eine Beispielanwendung,
• ein angepasstes WSAG4J-System
• und eine Beispielanwendung für das WSAG4J-System.
3. Das Verzeichnis Javadoc enthält die Javadoc-generierte Dokumentation der erstellten Klassen.
4. Im Verzeichnis Software befindet sich die für die Arbeit verwendete Software. Dazu
gehören Programmpakete und Bibliotheken die zum übersetzen benötigt werden
oder bei der Entwicklung verwendet wurden.
5. Das Verzeichnis Literatur enthält Dokumente, die in der Arbeit zitiert werden, sofern sie elektronisch verfügbar waren.
Im Grundverzeichnis des Datenträgers befindet sich eine Textdatei Anmerkungen mit Hinweisen zur Software, inbesondere zum übersetzen des QoS-Proxys und der Integration in
bestehende SCA-Anwendungen.
143

Documentos relacionados