|
Cover |
1 |
|
|
Titel |
3 |
|
|
Impressum |
4 |
|
|
Inhaltsverzeichnis |
5 |
|
|
Einleitung |
15 |
|
|
Über den Autor |
20 |
|
|
Kapitel 1: Microservices |
21 |
|
|
1.1 Was sind Microservices? |
22 |
|
|
1.1.1 Klein und darauf spezialisiert, eine bestimmte Aufgabe richtig gut zu erledigen |
22 |
|
|
1.1.2 Eigenständigkeit |
23 |
|
|
1.2 Die wichtigsten Vorteile |
24 |
|
|
1.2.1 Verschiedenartige Technologien |
24 |
|
|
1.2.2 Belastbarkeit |
26 |
|
|
1.2.3 Skalierung |
26 |
|
|
1.2.4 Komfortables Deployment |
27 |
|
|
1.2.5 Betriebliche Abstimmung |
28 |
|
|
1.2.6 Modularer Aufbau |
28 |
|
|
1.2.7 Austauschbarkeit |
29 |
|
|
1.3 Was ist mit serviceorientierten Architekturen? |
29 |
|
|
1.4 Weitere Verfahren zur Aufspaltung |
30 |
|
|
1.4.1 Programmbibliotheken |
31 |
|
|
1.4.2 Module |
31 |
|
|
1.5 Kein Patentrezept |
33 |
|
|
1.6 Fazit |
33 |
|
|
Kapitel 2: Der fortentwickelte Systemarchitekt |
35 |
|
|
2.1 Unangebrachte Vergleiche |
35 |
|
|
2.2 Das Zukunftsbild eines Systemarchitekten |
37 |
|
|
2.3 Zoneneinteilung |
39 |
|
|
2.4 Ein grundsätzlicher Ansatz |
40 |
|
|
2.4.1 Strategische Ziele |
41 |
|
|
2.4.2 Prinzipien |
41 |
|
|
2.4.3 Praktiken |
42 |
|
|
2.4.4 Prinzipien und Praktiken vereinigen |
42 |
|
|
2.4.5 Ein Praxisbeispiel |
43 |
|
|
2.5 Mindestvorgaben |
44 |
|
|
2.5.1 Monitoring |
44 |
|
|
2.5.2 Schnittstellen |
45 |
|
|
2.5.3 Architektonische Sicherheit |
45 |
|
|
2.6 Lenkung durch Code |
46 |
|
|
2.6.1 Musterbeispiele |
46 |
|
|
2.6.2 Maßgeschneiderte Servicevorlagen |
46 |
|
|
2.7 Technische Schulden |
48 |
|
|
2.8 Ausnahmebehandlung |
49 |
|
|
2.9 Governance und Steuerung aus der Mitte |
50 |
|
|
2.10 Aufbau eines Entwicklerteams |
52 |
|
|
2.11 Fazit |
52 |
|
|
Kapitel 3: Gestaltung von Services |
55 |
|
|
3.1 Kurz vorgestellt: MusicCorp |
55 |
|
|
3.2 Wodurch zeichnet sich ein guter Service aus? |
56 |
|
|
3.2.1 Lose Kopplung |
56 |
|
|
3.2.2 Hochgradige Geschlossenheit |
56 |
|
|
3.3 Begrenzter Kontext |
57 |
|
|
3.3.1 Geteilte und verborgene Modelle |
58 |
|
|
3.3.2 Module und Services |
59 |
|
|
3.3.3 Verfrühte Aufteilung |
60 |
|
|
3.4 Funktionalitäten des Kontexts |
61 |
|
|
3.5 Schildkröten bis ganz unten |
61 |
|
|
3.6 Kommunikation unter geschäftlichen Aspekten |
63 |
|
|
3.7 Der technische Rahmen |
63 |
|
|
3.8 Fazit |
65 |
|
|
Kapitel 4: Integration |
67 |
|
|
4.1 Die Suche nach der optimalen Integrationsmethode |
67 |
|
|
4.1.1 Zu Ausfällen führende Änderungen vermeiden |
67 |
|
|
4.1.2 Technologieunabhängige APIs verwenden |
67 |
|
|
4.1.3 Services für den Nutzer vereinfachen |
68 |
|
|
4.1.4 Implementierungsdetails verbergen |
68 |
|
|
4.2 Kundendatensätze |
68 |
|
|
4.3 Gemeinsame Nutzung der Datenbank |
69 |
|
|
4.4 Synchrone kontra asynchrone Kommunikation |
70 |
|
|
4.5 Orchestrierung kontra Choreografie |
72 |
|
|
4.6 Aufruf entfernter Prozeduren (RPC) |
75 |
|
|
4.6.1 Kopplung von Technologien |
76 |
|
|
4.6.2 Lokale Aufrufe sind keine entfernten Aufrufe |
76 |
|
|
4.6.3 Fragilität |
77 |
|
|
4.6.4 Ist RPC ein Übel? |
78 |
|
|
4.7 REST |
79 |
|
|
4.7.1 REST und HTTP |
80 |
|
|
4.7.2 HATEOAS |
81 |
|
|
4.7.3 JSON, XML oder etwas anderes? |
83 |
|
|
4.7.4 Vorsicht vor zu viel Komfort |
84 |
|
|
4.7.5 Nachteile von REST über HTTP |
85 |
|
|
4.8 Implementierung asynchroner ereignisgesteuerter Kollaboration |
86 |
|
|
4.8.1 Verfügbare Technologien |
86 |
|
|
4.8.2 Die Kompliziertheit asynchroner Architekturen |
88 |
|
|
4.9 Services als Zustandsautomaten |
90 |
|
|
4.10 Reactive Extensions |
90 |
|
|
4.11 DRY und die Gefahren der Wiederverwendung von Code im Microservices-Umfeld |
91 |
|
|
4.11.1 Client-Bibliotheken |
92 |
|
|
4.12 Zugriff über Referenzen |
93 |
|
|
4.13 Versionierung |
95 |
|
|
4.13.1 Solange wie möglich hinauszögern |
95 |
|
|
4.13.2 Zu Ausfällen führende Änderungen rechtzeitig erkennen |
96 |
|
|
4.13.3 Verwendung semantischer Versionierung |
97 |
|
|
4.13.4 Mehrere Endpunkte gleichzeitig betreiben |
98 |
|
|
4.13.5 Mehrere Serviceversionen gleichzeitig betreiben |
99 |
|
|
4.14 Benutzerschnittstellen |
101 |
|
|
4.14.1 Zunehmend digital |
101 |
|
|
4.14.2 Voraussetzungen |
102 |
|
|
4.14.3 Aufbau der API |
102 |
|
|
4.14.4 Bausteine der Benutzeroberfläche |
104 |
|
|
4.14.5 Back-Ends für Front-Ends |
106 |
|
|
4.14.6 Ein Hybridansatz |
108 |
|
|
4.15 Integration der Software von Drittherstellern |
108 |
|
|
4.15.1 Fehlende Entscheidungsmöglichkeiten |
109 |
|
|
4.15.2 Anpassungen |
109 |
|
|
4.15.3 Integrationswirrwarr |
110 |
|
|
4.15.4 Auf sich selbst gestellt |
110 |
|
|
4.15.5 Das Strangler-Pattern |
113 |
|
|
4.16 Fazit |
114 |
|
|
Kapitel 5: Die Aufspaltung des Monolithen |
115 |
|
|
5.1 Seams |
115 |
|
|
5.2 Aufspaltung von MusicCorp |
116 |
|
|
5.3 Gründe zur Aufspaltung des Monolithen |
117 |
|
|
5.3.1 Tempo der Änderungen |
117 |
|
|
5.3.2 Teamstruktur |
118 |
|
|
5.3.3 Sicherheitsaspekte |
118 |
|
|
5.3.4 Technologie |
118 |
|
|
5.4 Verwickelte Abhängigkeiten |
118 |
|
|
5.5 Die Datenbank |
119 |
|
|
5.6 Dem Problem zu Leibe rücken |
119 |
|
|
5.7 Beispiel: Auflösen von Fremdschlüssel-Relationen |
120 |
|
|
5.8 Beispiel: Statische Daten gemeinsam nutzen |
122 |
|
|
5.9 Beispiel: Veränderliche Daten gemeinsam nutzen |
123 |
|
|
5.10 Beispiel: Tabellen gemeinsam nutzen |
125 |
|
|
5.11 Refactoring von Datenbanken |
126 |
|
|
5.11.1 Die Aufspaltung umsetzen |
126 |
|
|
5.12 Abgrenzung von Transaktionen |
127 |
|
|
5.12.1 Versuchen Sie es später noch mal |
129 |
|
|
5.12.2 Abbruch des gesamten Vorgangs |
129 |
|
|
5.12.3 Verteilte Transaktionen |
130 |
|
|
5.12.4 Was also tun? |
131 |
|
|
5.13 Berichte |
131 |
|
|
5.14 Datenbanken zur Berichterstellung |
132 |
|
|
5.15 Datenabruf über Serviceaufrufe |
134 |
|
|
5.16 Datenpumpen |
135 |
|
|
5.16.1 Alternative Ziele |
137 |
|
|
5.17 Ereignis-Datenpumpen |
137 |
|
|
5.18 Backup-Datenpumpe |
139 |
|
|
5.19 Benachrichtigung in Echtzeit |
139 |
|
|
5.20 Änderungen verursachen Aufwand |
140 |
|
|
5.21 Erkennen der eigentlichen Ursachen |
141 |
|
|
5.22 Fazit |
141 |
|
|
Kapitel 6: Deployment |
143 |
|
|
6.1 Continuous Integration für Einsteiger |
143 |
|
|
6.1.1 Machen Sie es auch richtig? |
144 |
|
|
6.2 Continuous Integration und Microservices |
145 |
|
|
6.3 Build Pipelines und Continuous Delivery |
148 |
|
|
6.3.1 Die unvermeidlichen Ausnahmen |
149 |
|
|
6.4 Plattformspezifische Artefakte |
150 |
|
|
6.5 Betriebssystemspezifische Artefakte |
151 |
|
|
6.6 Selbsterstellte Images |
152 |
|
|
6.6.1 Images als Artefakte |
154 |
|
|
6.6.2 Unveränderliche Server |
155 |
|
|
6.7 Umgebungen |
155 |
|
|
6.7.1 Servicekonfiguration |
157 |
|
|
6.7.2 Zuordnung der Services zu den Hosts |
158 |
|
|
6.7.3 Mehrere Services pro Host |
158 |
|
|
6.7.4 Anwendungscontainer |
161 |
|
|
6.7.5 Ein Service pro Host |
162 |
|
|
6.7.6 Platform-as-a-Service (PaaS) |
163 |
|
|
6.8 Automatisierung |
164 |
|
|
6.8.1 Zwei Fallstudien zur Leistungsfähigkeit der Automatisierung |
165 |
|
|
6.9 Physisch wird virtuell |
166 |
|
|
6.9.1 Herkömmliche Virtualisierung |
166 |
|
|
6.9.2 Vagrant |
168 |
|
|
6.9.3 Linux-Container |
168 |
|
|
6.9.4 Docker |
170 |
|
|
6.10 Schnittstelle für das Deployment |
171 |
|
|
6.10.1 Definition der Umgebung |
173 |
|
|
6.11 Fazit |
174 |
|
|
Kapitel 7: Testen |
177 |
|
|
7.1 Testtypen |
177 |
|
|
7.2 Testumfang |
178 |
|
|
7.2.1 Unit-Tests |
180 |
|
|
7.2.2 Servicetests |
181 |
|
|
7.2.3 End-to-End-Tests |
182 |
|
|
7.2.4 Nachteile |
182 |
|
|
7.2.5 Wie viele Tests? |
183 |
|
|
7.3 Implementierung von Servicetests |
183 |
|
|
7.3.1 Mock-Objekte kontra Platzhalter |
184 |
|
|
7.3.2 Ein intelligenterer Platzhalterservice |
185 |
|
|
7.4 Knifflige End-to-End-Tests |
185 |
|
|
7.5 Nachteile von End-to-End-Tests |
187 |
|
|
7.5.1 Unzuverlässige und fragile Tests |
187 |
|
|
7.5.2 Wer programmiert die Tests? |
188 |
|
|
7.5.3 Testdauer |
189 |
|
|
7.5.4 Das große Auftürmen |
190 |
|
|
7.5.5 Die Metaversion |
191 |
|
|
7.6 Abläufe testen, nicht Funktionalitäten |
191 |
|
|
7.7 Abhilfe durch Consumer-Driven Tests |
192 |
|
|
7.7.1 Pact |
194 |
|
|
7.7.2 Konversationen |
195 |
|
|
7.8 End-to-End-Tests: Pro und Kontra |
196 |
|
|
7.9 Testen nach der Veröffentlichung |
196 |
|
|
7.9.1 Deployment und Veröffentlichung trennen |
197 |
|
|
7.9.2 Canary-Veröffentlichung |
198 |
|
|
7.9.3 MTTR kontra MTBR |
200 |
|
|
7.10 Funktionsübergreifende Tests |
201 |
|
|
7.10.1 Geschwindigkeitstests |
202 |
|
|
7.11 Fazit |
203 |
|
|
Kapitel 8: Monitoring |
205 |
|
|
8.1 Ein Service, ein Server |
206 |
|
|
8.2 Ein Service, mehrere Server |
207 |
|
|
8.3 Mehrere Services, mehrere Server |
208 |
|
|
8.4 Protokolle, Protokolle und noch mehr Protokolle |
208 |
|
|
8.5 Kennzahlen mehrerer Services |
209 |
|
|
8.6 Servicekennzahlen |
211 |
|
|
8.7 Monitoringung von Pseudo-Ereignissen |
212 |
|
|
8.7.1 Implementierung des semantischen Monitorings |
213 |
|
|
8.8 Korrelations-IDs |
213 |
|
|
8.9 Die Aufrufkette |
216 |
|
|
8.10 Standardisierung |
216 |
|
|
8.11 Zielgruppen |
217 |
|
|
8.12 Wie geht es weiter? |
218 |
|
|
8.13 Fazit |
219 |
|
|
Kapitel 9: Sicherheit |
221 |
|
|
9.1 Authentifizierung und Autorisierung |
221 |
|
|
9.1.1 Gängige Single-Sign-On-Implementierungen |
222 |
|
|
9.1.2 Single-Sign-On-Gateway |
223 |
|
|
9.1.3 Fein unterteilte Authentifizierung |
225 |
|
|
9.2 Authentifizierung und Autorisierung von Services |
226 |
|
|
9.2.1 Im internen Netzwerk ist alles erlaubt |
226 |
|
|
9.2.2 Authentifizierung über HTTP(S) |
226 |
|
|
9.2.3 Verwendung von SAML oder OpenID Connect |
227 |
|
|
9.2.4 Client-Zertifikate |
228 |
|
|
9.2.5 HMAC über HTTP |
229 |
|
|
9.2.6 API-Schlüssel |
230 |
|
|
9.2.7 Das Stellvertreterproblem |
231 |
|
|
9.3 Schutz ruhender Daten |
233 |
|
|
9.3.1 Wohlbekannte Verfahren einsetzen |
234 |
|
|
9.3.2 Die Bedeutung der Schlüssel |
235 |
|
|
9.3.3 Was soll verschlüsselt werden? |
235 |
|
|
9.3.4 Entschlüsselung bei Bedarf |
236 |
|
|
9.3.5 Backups verschlüsseln |
236 |
|
|
9.4 Gestaffelte Sicherheitsstrategie |
236 |
|
|
9.4.1 Firewalls |
236 |
|
|
9.4.2 Protokollierung |
236 |
|
|
9.4.3 Intrusion-Detection-Systeme |
237 |
|
|
9.4.4 Unterteilung des Netzwerks |
237 |
|
|
9.4.5 Betriebssystem |
238 |
|
|
9.5 Ein ausgearbeitetes Beispiel |
239 |
|
|
9.6 Datensparsamkeit |
241 |
|
|
9.7 Der Faktor Mensch |
242 |
|
|
9.8 Eine Goldene Regel |
242 |
|
|
9.9 Integrierte Sicherheit |
243 |
|
|
9.10 Externe Prüfung |
243 |
|
|
9.11 Fazit |
244 |
|
|
Kapitel 10: Conways Gesetz und Systemdesign |
245 |
|
|
10.1 Beweise |
245 |
|
|
10.1.1 Lose und eng gekoppelte Organisationen |
246 |
|
|
10.1.2 Windows Vista |
246 |
|
|
10.2 Netflix und Amazon |
246 |
|
|
10.3 Was kann man damit anfangen? |
247 |
|
|
10.4 Anpassung an Kommunikationswege |
247 |
|
|
10.5 Verantwortlichkeit für Services |
249 |
|
|
10.6 Gemeinschaftliche Verantwortlichkeit für Services |
249 |
|
|
10.6.1 Schwierige Aufspaltung |
249 |
|
|
10.6.2 Feature-Teams |
250 |
|
|
10.6.3 Engpässe bei der Auslieferung |
250 |
|
|
10.7 Interner Open-Source-Code |
251 |
|
|
10.7.1 Aufgaben der Koordinatoren |
252 |
|
|
10.7.2 Ausgereifte Services |
253 |
|
|
10.7.3 Werkzeugsammlungen |
253 |
|
|
10.8 Begrenzte Kontexte und Teamstrukturen |
253 |
|
|
10.9 Verwaiste Services? |
254 |
|
|
10.10 Fallstudie: RealEstate.com.au |
254 |
|
|
10.11 Conways Gesetz auf den Kopf gestellt |
256 |
|
|
10.12 Menschen |
257 |
|
|
10.13 Fazit |
258 |
|
|
Kapitel 11: Microservices skalieren |
259 |
|
|
11.1 Ausfälle gibt es immer |
259 |
|
|
11.2 Wie viel ist zu viel? |
260 |
|
|
11.3 Schrittweiser Abbau der Funktionalität |
261 |
|
|
11.4 Architektonische Sicherheitsmaßnahmen |
262 |
|
|
11.5 Die antifragile Organisation |
265 |
|
|
11.5.1 Timeouts |
266 |
|
|
11.5.2 Circuit Breaker |
266 |
|
|
11.5.3 Das Bulkhead-Pattern |
269 |
|
|
11.5.4 Isolierung |
270 |
|
|
11.6 Idempotenz |
270 |
|
|
11.7 Skalierung |
272 |
|
|
11.7.1 Mehr Leistung |
272 |
|
|
11.7.2 Arbeitslast aufteilen |
273 |
|
|
11.7.3 Risikoverteilung |
273 |
|
|
11.7.4 Lastverteilung |
274 |
|
|
11.7.5 Worker-Systeme |
276 |
|
|
11.7.6 Neuanfang |
277 |
|
|
11.8 Datenbanken skalieren |
278 |
|
|
11.8.1 Verfügbarkeit des Services kontra Lebensdauer der Daten |
278 |
|
|
11.8.2 Skalierung bei Lesevorgängen |
279 |
|
|
11.8.3 Skalierung bei Schreibvorgängen |
280 |
|
|
11.8.4 Gemeinsam genutzte Datenbankinfrastruktur |
281 |
|
|
11.8.5 CQRS |
281 |
|
|
11.9 Caching |
282 |
|
|
11.9.1 Clientseitiges Caching, Proxy und serverseitiges Caching |
283 |
|
|
11.9.2 Caching und HTTP |
284 |
|
|
11.9.3 Caching bei Schreibvorgängen |
285 |
|
|
11.9.4 Caching zur Erhöhung der Belastbarkeit |
286 |
|
|
11.9.5 Den Ursprung verbergen |
286 |
|
|
11.9.6 Möglichst einfach |
287 |
|
|
11.9.7 Cache Poisoning: Ein warnendes Beispiel |
288 |
|
|
11.10 Automatische Skalierung |
289 |
|
|
11.11 Das CAP-Theorem |
290 |
|
|
11.11.1 Aufgabe der Konsistenz |
292 |
|
|
11.11.2 Aufgabe der Verfügbarkeit |
292 |
|
|
11.11.3 Aufgabe der Partitionstoleranz? |
294 |
|
|
11.11.4 AP oder CP? |
294 |
|
|
11.11.5 Keine Frage eines Entweder-Oders |
294 |
|
|
11.11.6 Abbildung der Wirklichkeit |
295 |
|
|
11.12 Serviceerkennung |
296 |
|
|
11.12.1 DNS |
296 |
|
|
11.13 Dynamische Registrierung von Services |
298 |
|
|
11.13.1 Zookeeper |
298 |
|
|
11.13.2 Consul |
300 |
|
|
11.13.3 Eureka |
301 |
|
|
11.13.4 Eigene Serviceregistrierung |
301 |
|
|
11.13.5 Menschliches Interesse |
302 |
|
|
11.14 Services dokumentieren |
302 |
|
|
11.14.1 Swagger |
302 |
|
|
11.14.2 HAL und der HAL-Browser |
303 |
|
|
11.15 Ein sich selbst beschreibendes System |
304 |
|
|
11.16 Fazit |
305 |
|
|
Kapitel 12: Auf den Punkt gebracht |
307 |
|
|
12.1 Prinzipien |
307 |
|
|
12.1.1 Geschäftsvorgänge modellieren |
308 |
|
|
12.1.2 Automatisierung kultivieren |
308 |
|
|
12.1.3 Implementierungsdetails verbergen |
309 |
|
|
12.1.4 Dezentralisierung |
309 |
|
|
12.1.5 Unabhängiges Deployment |
310 |
|
|
12.1.6 Ausfälle eingrenzen |
310 |
|
|
12.1.7 Umfassendes Monitoring |
311 |
|
|
12.2 Wann sollte man auf Microservices verzichten? |
311 |
|
|
12.3 Schlusswort |
312 |
|
|
Stichwortverzeichnis |
313 |
|