Dezember 21, 2025
14 Min. Lesezeit

Interviewfragen für erfahrene Site Reliability Engineers: Der umfassende Leitfaden

interview
career-advice
job-search
Interviewfragen für erfahrene Site Reliability Engineers: Der umfassende Leitfaden
MB

Milad Bonakdar

Autor

Meistern Sie fortgeschrittene SRE-Konzepte mit umfassenden Interviewfragen zu Kapazitätsplanung, Chaos Engineering, verteilten Systemen, SLO-Design, Incident Leadership und organisatorischen SRE-Praktiken für leitende Positionen.


Einführung

Von leitenden Site Reliability Engineers wird erwartet, dass sie zuverlässige Systeme in großem Maßstab entwerfen, Incident Responses leiten, die SRE-Kultur vorantreiben und strategische Entscheidungen über Investitionen in die Zuverlässigkeit treffen. Diese Rolle erfordert fundiertes technisches Fachwissen, Führungsqualitäten und die Fähigkeit, Zuverlässigkeit mit Geschäftsentwicklung in Einklang zu bringen.

Dieser umfassende Leitfaden behandelt wichtige Fragen für Vorstellungsgespräche mit leitenden SREs, wobei der Schwerpunkt auf fortgeschrittenen Konzepten, Systemdesign und organisatorischen Auswirkungen liegt. Jede Frage enthält detaillierte Erklärungen und praktische Beispiele.


Fortgeschrittenes SLO-Design

1. Wie entwirfst du SLIs und SLOs für einen neuen Dienst mit begrenzten Daten?

Antwort: Das Entwerfen von SLOs für neue Dienste erfordert ein ausgewogenes Verhältnis zwischen Anspruch und Erreichbarkeit:

Ansatz:

1. Beginne mit der User Journey Mapping:

# Identifiziere kritische User Journeys
user_journeys = {
    'search_product': {
        'steps': ['search_query', 'results_display', 'product_click'],
        'criticality': 'high',
        'expected_latency': '< 500ms'
    },
    'checkout': {
        'steps': ['add_to_cart', 'payment', 'confirmation'],
        'criticality': 'critical',
        'expected_latency': '< 2s'
    },
    'browse_recommendations': {
        'steps': ['load_page', 'fetch_recommendations'],
        'criticality': 'medium',
        'expected_latency': '< 1s'
    }
}

2. Definiere SLIs basierend auf der User Experience:

# SLI Spezifikation
slis:
  availability:
    description: "Prozentsatz erfolgreicher Anfragen"
    measurement: "count(http_status < 500) / count(http_requests)"
    
  latency:
    description: "95. Perzentil der Anfrage-Latenz"
    measurement: "histogram_quantile(0.95, http_request_duration_seconds)"
    
  correctness:
    description: "Prozentsatz der Anfragen, die korrekte Daten zurückgeben"
    measurement: "count(validation_passed) / count(requests)"

3. Setze anfängliche SLOs konservativ:

def calculate_initial_slo(service_type, criticality):
    """
    Berechne das anfängliche SLO basierend auf den Dienstmerkmalen
    """
    base_slos = {
        'critical': {
            'availability': 0.999,  # 99,9%
            'latency_p95': 1.0,     # 1 Sekunde
            'latency_p99': 2.0      # 2 Sekunden
        },
        'high': {
            'availability': 0.995,  # 99,5%
            'latency_p95': 2.0,
            'latency_p99': 5.0
        },
        'medium': {
            'availability': 0.99,   # 99%
            'latency_p95': 5.0,
            'latency_p99': 10.0
        }
    }
    
    return base_slos.get(criticality, base_slos['medium'])

# Beispiel
checkout_slo = calculate_initial_slo('payment', 'critical')
print(f"Checkout SLO: {checkout_slo}")

4. Plane für Iteration:

  • Starte mit einem 4-wöchigen Messfenster
  • Überprüfe die SLO-Performance wöchentlich
  • Passe sie basierend auf der tatsächlichen Performance und dem Benutzer-Feedback an
  • Verschärfe die SLOs, wenn das System ausgereifter ist

5. Dokumentiere Annahmen:

## SLO Annahmen (Initial)

### Verfügbarkeit: 99,9%
- Annahme: Standardmäßige Cloud-Infrastruktur-Zuverlässigkeit
- Fehlerbudget: 43 Minuten/Monat
- Überprüfung: Nach 3 Monaten Daten

### Latenz (p95): < 1s
- Annahme: Datenbankabfragen < 100ms
- Annahme: Keine komplexen Berechnungen
- Überprüfung: Wenn sich die Abfragemuster ändern

### Abhängigkeiten
- Verfügbarkeit der externen API: 99,95%
- Verfügbarkeit der Datenbank: 99,99%

Seltenheit: Häufig
Schwierigkeit: Schwer


2. Wie gehst du mit widersprüchlichen SLOs über verschiedene Benutzersegmente hinweg um?

Antwort: Verschiedene Benutzersegmente haben oft unterschiedliche Zuverlässigkeitsanforderungen:

Strategie: Multi-Tier SLOs

class SLOTier:
    def __init__(self, name, availability, latency_p95, latency_p99):
        self.name = name
        self.availability = availability
        self.latency_p95 = latency_p95
        self.latency_p99 = latency_p99
        self.error_budget = 1 - availability

# Definiere Tiers
tiers = {
    'premium': SLOTier(
        name='Premium',
        availability=0.9999,  # 99,99% - 4,3 min/Monat
        latency_p95=0.5,
        latency_p99=1.0
    ),
    'standard': SLOTier(
        name='Standard',
        availability=0.999,   # 99,9% - 43 min/Monat
        latency_p95=1.0,
        latency_p99=2.0
    ),
    'free': SLOTier(
        name='Free',
        availability=0.99,    # 99% - 7,2 Stunden/Monat
        latency_p95=2.0,
        latency_p99=5.0
    )
}

# Leite Anfragen basierend auf dem Tier weiter
def get_user_tier(user_id):
    # Suche den Abonnement-Tier des Benutzers
    return user_subscription_tier(user_id)

def apply_slo_policy(user_id, request):
    tier = get_user_tier(user_id)
    slo = tiers[tier]
    
    # Wende tier-spezifische Richtlinien an
    request.timeout = slo.latency_p99
    request.priority = tier  # Für die Priorisierung der Warteschlange
    request.retry_budget = calculate_retry_budget(slo.error_budget)
    
    return request

Implementierung mit Traffic Routing:

# Kubernetes Beispiel: Separate Deployments pro Tier
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-premium
spec:
  replicas: 10
  template:
    spec:
      containers:
      - name: api
        resources:
          requests:
            cpu: "2"
            memory: "4Gi"
          limits:
            cpu: "4"
            memory: "8Gi"
      priorityClassName: high-priority
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-standard
spec:
  replicas: 5
  template:
    spec:
      containers:
      - name: api
        resources:
          requests:
            cpu: "1"
            memory: "2Gi"

Monitoring pro Tier:

# Verfügbarkeit nach Tier
sum(rate(http_requests_total{status!~"5.."}[5m])) by (tier)
/
sum(rate(http_requests_total[5m])) by (tier)

# Latenz nach Tier
histogram_quantile(0.95,
  rate(http_request_duration_seconds_bucket[5m])
) by (tier)

Seltenheit: Ungewöhnlich
Schwierigkeit: Schwer


Kapazitätsplanung

3. Beschreibe deinen Kapazitätsplanungsprozess für einen schnell wachsenden Dienst.

Antwort: Die Kapazitätsplanung stellt sicher, dass die Ressourcen den Bedarf decken und gleichzeitig die Kosten optimiert werden:

Framework für die Kapazitätsplanung:

Loading diagram...

1. Messe die Baseline:

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression

class CapacityPlanner:
    def __init__(self, metrics_data):
        self.data = pd.DataFrame(metrics_data)
    
    def analyze_trends(self, metric_name, days=30):
        """Analysiere historische Trends"""
        metric_data = self.data[metric_name].tail(days * 24)  # Stündliche Daten
        
        # Berechne die Wachstumsrate
        start_value = metric_data.iloc[0]
        end_value = metric_data.iloc[-1]
        growth_rate = ((end_value - start_value) / start_value) * 100
        
        # Identifiziere die Spitzenauslastung
        peak_value = metric_data.max()
        peak_time = metric_data.idxmax()
        
        # Berechne Perzentile
        p50 = metric_data.quantile(0.50)
        p95 = metric_data.quantile(0.95)
        p99 = metric_data.quantile(0.99)
        
        return {
            'growth_rate': growth_rate,
            'peak_value': peak_value,
            'peak_time': peak_time,
            'p50': p50,
            'p95': p95,
            'p99': p99
        }
    
    def forecast_capacity(self, metric_name, months_ahead=3):
        """Prognostiziere den zukünftigen Kapazitätsbedarf"""
        # Bereite die Daten vor
        df = self.data[[metric_name]].reset_index()
        df['days'] = (df.index / 24).astype(int)  # Konvertiere Stunden in Tage
        
        # Trainiere das Modell
        X = df[['days']].values
        y = df[metric_name].values
        
        model = LinearRegression()
        model.fit(X, y)
        
        # Prognostiziere
        future_days = np.array([[df['days'].max() + (30 * months_ahead)]])
        forecast = model.predict(future_days)[0]
        
        # Füge eine Sicherheitsmarge hinzu (20%)
        forecast_with_margin = forecast * 1.2
        
        return {
            'forecast': forecast,
            'with_margin': forecast_with_margin,
            'current': y[-1],
            'growth_factor': forecast / y[-1]
        }
    
    def calculate_resource_needs(self, requests_per_second, 
                                 requests_per_instance=100,
                                 headroom=0.3):
        """Berechne die benötigten Instanzen"""
        # Basiskapazität
        base_instances = np.ceil(requests_per_second / requests_per_instance)
        
        # Füge Headroom für Spitzen und Wartung hinzu
        total_instances = np.ceil(base_instances * (1 + headroom))
        
        return {
            'base_instances': int(base_instances),
            'total_instances': int(total_instances),
            'headroom_instances': int(total_instances - base_instances)
        }

# Beispielhafte Verwendung
metrics = {
    'requests_per_second': [100, 105, 110, 115, 120, ...],  # Historische Daten
    'cpu_usage': [45, 48, 50, 52, 55, ...],
    'memory_usage': [60, 62, 65, 67, 70, ...]
}

planner = CapacityPlanner(metrics)

# Analysiere Trends
trends = planner.analyze_trends('requests_per_second', days=30)
print(f"Wachstumsrate: {trends['growth_rate']:.2f}%")
print(f"Peak RPS: {trends['peak_value']}")

# Prognostiziere die Kapazität
forecast = planner.forecast_capacity('requests_per_second', months_ahead=3)
print(f"Prognostizierte RPS in 3 Monaten: {forecast['forecast']:.0f}")
print(f"Mit Sicherheitsmarge: {forecast['with_margin']:.0f}")

# Berechne den Ressourcenbedarf
resources = planner.calculate_resource_needs(
    requests_per_second=forecast['with_margin'],
    requests_per_instance=100,
    headroom=0.3
)
print(f"Benötigte Instanzen: {resources['total_instances']}")

2. Berücksichtige Wachstumstreiber:

  • Benutzerwachstumsrate
  • Feature-Launches
  • Saisonale Muster
  • Marketingkampagnen
  • Geografische Expansion

3. Plane für Headroom:

  • N+1: Überlebe einen Instanzausfall
  • N+2: Überlebe zwei Ausfälle oder einen Zonenausfall
  • Traffic-Spitzen: 2-3x normale Kapazität
  • Wartungsfenster: 20-30% Overhead

4. Kostenoptimierung:

def optimize_instance_mix(workload_profile):
    """
    Optimiere Instanztypen für Kosten
    """
    # Mix aus Instanztypen
    instance_types = {
        'on_demand': {
            'cost_per_hour': 0.10,
            'reliability': 1.0,
            'percentage': 0.3  # 30% On-Demand für die Baseline
        },
        'spot': {
            'cost_per_hour': 0.03,
            'reliability': 0.95,
            'percentage': 0.5  # 50% Spot für Kosteneinsparungen
        },
        'reserved': {
            'cost_per_hour': 0.06,
            'reliability': 1.0,
            'percentage': 0.2  # 20% Reserved für vorhersehbare Last
        }
    }
    
    total_instances = workload_profile['total_instances']
    
    allocation = {}
    for instance_type, config in instance_types.items():
        count = int(total_instances * config['percentage'])
        allocation[instance_type] = {
            'count': count,
            'monthly_cost': count * config['cost_per_hour'] * 730
        }
    
    return allocation

Seltenheit: Sehr häufig
Schwierigkeit: Schwer


Chaos Engineering

4. Wie implementierst du Chaos Engineering in der Produktion?

Antwort: Chaos Engineering testet proaktiv die Systemresilienz, indem Fehler injiziert werden:

Prinzipien des Chaos Engineerings:

  1. Baue Hypothesen um den stabilen Zustand herum auf
  2. Variiere reale Ereignisse
  3. Führe Experimente in der Produktion durch
  4. Automatisiere Experimente
  5. Minimiere den Blast Radius

Implementierung:

# Chaos-Experiment-Framework
from dataclasses import dataclass
from enum import Enum
import random
import time

class ExperimentStatus(Enum):
    PLANNED = "planned"
    RUNNING = "running"
    COMPLETED = "completed"
    ABORTED = "aborted"

@dataclass
class ChaosExperiment:
    name: str
    hypothesis: str
    blast_radius: float  # Prozentsatz des betroffenen Traffics
    duration_seconds: int
    rollback_criteria: dict
    
    def __post_init__(self):
        self.status = ExperimentStatus.PLANNED
        self.metrics_before = {}
        self.metrics_during = {}
        self.metrics_after = {}

class ChaosRunner:
    def __init__(self, monitoring_client):
        self.monitoring = monitoring_client
        self.experiments = []
    
    def run_experiment(self, experiment: ChaosExperiment):
        """Führe ein Chaos-Experiment mit Sicherheitsprüfungen durch"""
        print(f"Starte Experiment: {experiment.name}")
        
        # 1. Messe die Baseline
        experiment.metrics_before = self.measure_metrics()
        print(f"Baseline-Metriken: {experiment.metrics_before}")
        
        # 2. Verifiziere, dass das System gesund ist
        if not self.is_system_healthy(experiment.metrics_before):
            print("System ist ungesund, breche Experiment ab")
            return False
        
        # 3. Injiziere Fehler
        experiment.status = ExperimentStatus.RUNNING
        failure_injection = self.inject_failure(experiment)
        
        try:
            # 4. Überwache während des Experiments
            start_time = time.time()
            while time.time() - start_time < experiment.duration_seconds:
                experiment.metrics_during = self.measure_metrics()
                
                # Überprüfe die Rollback-Kriterien
                if self.should_rollback(experiment):
                    print("Rollback-Kriterien erfüllt, stoppe Experiment")
                    self.rollback(failure_injection)
                    experiment.status = ExperimentStatus.ABORTED
                    return False
                
                time.sleep(10)  # Überprüfe alle 10 Sekunden
            
            # 5. Rolle die Fehlerinjektion zurück
            self.rollback(failure_injection)
            
            # 6. Messe die Wiederherstellung
            time.sleep(60)  # Warte, bis sich das System stabilisiert hat
            experiment.metrics_after = self.measure_metrics()
            
            # 7. Analysiere die Ergebnisse
            experiment.status = ExperimentStatus.COMPLETED
            return self.analyze_results(experiment)
            
        except Exception as e:
            print(f"Experiment fehlgeschlagen: {e}")
            self.rollback(failure_injection)
            experiment.status = ExperimentStatus.ABORTED
            return False
    
    def inject_failure(self, experiment):
        """Injiziere einen bestimmten Fehlertyp"""
        # Die Implementierung hängt vom Fehlertyp ab
        pass
    
    def measure_metrics(self):
        """Messe wichtige Systemmetriken"""
        return {
            'error_rate': self.monitoring.get_error_rate(),
            'latency_p95': self.monitoring.get_latency_p95(),
            'requests_per_second': self.monitoring.get_rps(),
            'availability': self.monitoring.get_availability()
        }
    
    def is_system_healthy(self, metrics):
        """Überprüfe, ob das System die SLOs erfüllt"""
        return (
            metrics['error_rate'] < 0.01 and  # < 1% Fehler
            metrics['latency_p95'] < 1.0 and  # < 1s Latenz
            metrics['availability'] > 0.999   # > 99,9% verfügbar
        )
    
    def should_rollback(self, experiment):
        """Überprüfe, ob das Experiment abgebrochen werden soll"""
        current = experiment.metrics_during
        criteria = experiment.rollback_criteria
        
        return (
            current['error_rate'] > criteria.get('max_error_rate', 0.05) or
            current['latency_p95'] > criteria.get('max_latency', 5.0) or
            current['availability'] < criteria.get('min_availability', 0.99)
        )
    
    def rollback(self, failure_injection):
        """Entferne die Fehlerinjektion"""
        print("Rolle die Fehlerinjektion zurück")
        # Die Implementierung hängt vom Fehlertyp ab
    
    def analyze_results(self, experiment):
        """Analysiere die Experimentergebnisse"""
        before = experiment.metrics_before
        during = experiment.metrics_during
        after = experiment.metrics_after
        
        print(f"\nExperimentergebnisse: {experiment.name}")
        print(f"Hypothese: {experiment.hypothesis}")
        print(f"\nMetriken:")
        print(f"  Vorher: {before}")
        print(f"  Während: {during}")
        print(f"  Nachher: {after}")
        
        # Stelle fest, ob die Hypothese validiert wurde
        hypothesis_validated = (
            during['availability'] >= experiment.rollback_criteria['min_availability']
        )
        
        return hypothesis_validated

# Beispiel-Experiment
experiment = ChaosExperiment(
    name="Datenbank-Failover-Test",
    hypothesis="Das System bleibt während des Datenbank-Failovers verfügbar",
    blast_radius=0.1,  # 10% des Traffics
    duration_seconds=300,  # 5 Minuten
    rollback_criteria={
        'max_error_rate': 0.05,
        'max_latency': 5.0,
        'min_availability': 0.99
    }
)

Häufige Chaos-Experimente:

1. Netzwerklatenz:

# Verwende tc (Traffic Control), um Latenz hinzuzufügen
tc qdisc add dev eth0 root netem delay 100ms 20ms

# Rollback
tc qdisc del dev eth0 root

2. Pod-Ausfall (Kubernetes):

# Kill random pods
kubectl delete pod -l app=myapp --random=1

# Verwende Chaos Mesh
kubectl apply -f - <<EOF
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: pod-failure
spec:
  action: pod-failure
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app: myapp
  duration: "30s"
EOF

3. Ressourcenerschöpfung:

# CPU-Stress
stress-ng --cpu 4 --timeout 60s

# Speicher-Stress
stress-ng --vm 2 --vm-bytes 2G --timeout 60s

Seltenheit: Häufig
Schwierigkeit: Schwer


Incident Leadership

5. Wie leitest du einen Incident mit hohem Schweregrad von der Erkennung bis zur Postmortem?

Antwort: Senior SREs fungieren oft als Incident Commander für kritische Ausfälle:

Incident Command Struktur:

Loading diagram...

Verantwortlichkeiten des Incident Commanders:

1. Initial Response (0-5 Minuten):

## Checkliste für den Incident Commander

### Sofortmaßnahmen
- [ ] Incident bestätigen
- [ ] Schweregrad beurteilen (SEV-1, SEV-2, SEV-3)
- [ ] Incident Channel erstellen (#incident-YYYY-MM-DD-NNN)
- [ ] Geeignete Teams benachrichtigen
- [ ] Rollen zuweisen:
  - [ ] Technische Leitung
  - [ ] Kommunikationsleitung
  - [ ] Protokollführer (Dokumentation der Zeitleiste)

### Schweregradbeurteilung
**SEV-1 (Kritisch):**
- Vollständiger Dienstausfall
- Datenverlust
- Sicherheitsverletzung
- > 50% der Benutzer betroffen

**SEV-2 (Hoch):**
- Teilweiser Ausfall
- Beeinträchtigte Performance
- 10-50% der Benutzer betroffen

**SEV-3 (Mittel):**
- Geringfügige Beeinträchtigung
- < 10% der Benutzer betroffen
- Workaround verfügbar

2. Investigation Phase:

class IncidentCommander:
    def __init__(self, incident_id):
        self.incident_id = incident_id
        self.timeline = []
        self.status_updates = []
        self.action_items = []
    
    def coordinate_investigation(self):
        """Koordiniere die technische Untersuchung"""
        # Parallele Untersuchungsstränge
        tracks = {
            'recent_changes': self.check_recent_deployments(),
            'infrastructure': self.check_infrastructure_health(),
            'dependencies': self.check_external_dependencies(),
            'metrics': self.analyze_metrics_anomalies()
        }
        
        return tracks
    
    def make_decision(self, options, deadline_minutes=5):
        """Triff eine zeitlich begrenzte Entscheidung"""
        print(f"Entscheidung innerhalb von {deadline_minutes} Minuten erforderlich")
        print(f"Optionen: {options}")
        
        # Sammle Input von technischen Leitern
        # Triff eine Entscheidung basierend auf:
        # - Benutzer Auswirkungen
        # - Risiko jeder Option
        # - Zeit für die Implementierung
        # - Reversibilität
        
        return selected_option
    
    def communicate_status(self, interval_minutes=15):
        """Regelmäßige Statusaktualisierungen"""
        update = {
            'timestamp': datetime.now(),
            'status': self.get_current_status(),
            'impact': self.assess_user_impact(),
            'eta': self.estimate_resolution_time(),
            'next_update': datetime.now() + timedelta(minutes=interval_minutes)
        }
        
        # Sende an Stakeholder
        self.send_status_update(update)
        self.status_updates.append(update)
    
    def log_timeline_event(self, event, timestamp=None):
        """Dokumentiere die Incident-Zeitleiste"""
        self.timeline.append({
            'timestamp': timestamp or datetime.now(),
            'event': event,
            'logged_by': self.get_current_user()
        })

3. Mitigation Strategies:

def evaluate_mitigation_options():
    """Bewerte und priorisiere Mitigation Optionen"""
    options = [
        {
            'action': 'Rollback Deployment',
            'time_to_implement': 5,  # Minuten
            'risk': 'low',
            'effectiveness': 'high',
            'reversible': True
        },
        {
            'action': 'Skaliere Ressourcen hoch',
            'time_to_implement': 2,
            'risk': 'low',
            'effectiveness': 'medium',
            'reversible': True
        },
        {
            'action': 'Deaktiviere Feature Flag',
            'time_to_implement': 1,
            'risk': 'low',
            'effectiveness': 'high',
            'reversible': True
        },
        {
            'action': 'Datenbank-Failover',
            'time_to_implement': 10,
            'risk': 'medium',
            'effectiveness': 'high',
            'reversible': False
        }
    ]
    
    # Sortiere nach: niedrigem Risiko, hoher Effektivität, schneller Implementierung
    sorted_options = sorted(
        options,
        key=lambda x: (
            x['risk'] == 'low',
            x['effectiveness'] == 'high',
            -x['time_to_implement']
        ),
        reverse=True
    )
    
    return sorted_options

4. Postmortem (Blameless):

# Incident Postmortem: API-Ausfall

**Datum:** 2024-11-25  
**Dauer:** 45 Minuten  
**Schweregrad:** SEV-1  
**Incident Commander:** Alice  
**Technische Leitung:** Bob

## Zusammenfassung
Vollständiger API-Ausfall, der alle Benutzer aufgrund von Erschöpfung des Datenbank-Verbindungspools betrifft.

## Auswirkungen
- **Betroffene Benutzer:** 100% (alle Benutzer)
- **Dauer:** 45 Minuten
- **Umsatzauswirkungen:** ~$50.000
- **SLO-Auswirkungen:** 75% des monatlichen Fehlerbudgets verbraucht

## Ursache
Der Datenbank-Verbindungspool ist aufgrund eines Verbindungslecks in einem neuen Feature erschöpft, das 2 Stunden vor dem Incident bereitgestellt wurde.

## Zeitleiste
| Zeit | Ereignis |
|------|-------|
| 14:00 | Bereitstellung von v2.5.0 |
| 15:45 | Erste Warnungen für erhöhte Latenz |
| 15:50 | Vollständiger API-Ausfall |
| 15:52 | Incident erklärt (SEV-1) |
| 15:55 | Datenbank als Engpass identifiziert |
| 16:05 | Entscheidung zum Rollback des Deployments |
| 16:15 | Rollback abgeschlossen |
| 16:20 | Dienst erholt sich |
| 16:35 | Vollständige Wiederherstellung bestätigt |

## Was gut gelaufen ist
- Schnelle Erkennung (5 Minuten ab dem ersten Symptom)
- Klare Incident Command Struktur
- Schnelle Entscheidung zum Rollback
- Gute Kommunikation mit Stakeholdern

## Was schief gelaufen ist
- Verbindungsleck nicht in Tests erkannt
- Keine Überwachung des Verbindungspools
- Bereitstellung während der Hauptverkehrszeiten

## Maßnahmen
| Aktion | Verantwortlicher | Fälligkeitsdatum | Status |
|--------|-------|----------|--------|
| Überwachung des Verbindungspools hinzufügen | Alice | 2024-12-01 | Offen |
| Implementiere Erkennung von Verbindungslecks in Tests | Bob | 2024-12-05 | Offen |
| Aktualisiere die Bereitstellungsrichtlinie (vermeide Hauptverkehrszeiten) | Charlie | 2024-11-30 | Offen |
| Füge einen Circuit Breaker für Datenbankverbindungen hinzu | David | 2024-12-10 | Offen |

## Erkenntnisse
- Überwachungslücken können kritische Probleme verbergen
- Das Timing der Bereitstellung ist wichtig
- Benötigen bessere Integrationstests für Ressourcenlecks

Seltenheit: Sehr häufig
Schwierigkeit: Schwer


Zuverlässigkeit verteilter Systeme

6. Wie stellst du die Zuverlässigkeit in einer verteilten Microservices-Architektur sicher?

Antwort: Verteilte Systeme bringen einzigartige Herausforderungen für die Zuverlässigkeit mit sich:

Schlüsselmuster:

1. Service Mesh für Resilienz:

# Istio Beispiel: Circuit Breaking und Retries
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: api-service
spec:
  host: api-service
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        http1MaxPendingRequests: 50
        http2MaxRequests: 100
        maxRequestsPerConnection: 2
    outlierDetection:
      consecutiveErrors: 5
      interval: 30s
      baseEjectionTime: 30s
      maxEjectionPercent: 50
      minHealthPercent: 40
    loadBalancer:
      simple: LEAST_REQUEST
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: api-service
spec:
  hosts:
  - api-service
  http:
  - retries:
      attempts: 3
      perTryTimeout: 2s
      retryOn: 5xx,reset,connect-failure,refused-stream
    timeout: 10s
    route:
    - destination:
        host: api-service

2. Distributed Tracing:

from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.requests import RequestsInstrumentor

# Tracing einrichten
trace.set_tracer_provider(TracerProvider())
jaeger_exporter = JaegerExporter(
    agent_host_name="jaeger",
    agent_port=6831,
)
trace.get_tracer_provider().add_span_processor(
    BatchSpanProcessor(jaeger_exporter)
)

# Instrumentiere die Requests-Bibliothek
RequestsInstrumentor().instrument()

# Verwendung im Code
tracer = trace.get_tracer(__name__)

def process_order(order_id):
    with tracer.start_as_current_span("process_order") as span:
        span.set_attribute("order.id", order_id)
        
        # Rufe den Payment Service auf
        with tracer.start_as_current_span("call_payment_service"):
            payment_result = call_payment_service(order_id)
        
        # Rufe den Inventory Service auf
        with tracer.start_as_current_span("call_inventory_service"):
            inventory_result = call_inventory_service(order_id)
        
        return combine_results(payment_result, inventory_result)

3. Bulkhead Pattern:

import asyncio
from asyncio import Semaphore

class BulkheadExecutor
Newsletter subscription

Wöchentliche Karrieretipps, die wirklich funktionieren

Erhalten Sie die neuesten Einblicke direkt in Ihr Postfach

Decorative doodle

Heben Sie sich bei Recruitern ab und Landen Sie Ihren Traumjob

Schließen Sie sich Tausenden an, die ihre Karriere mit KI-gestützten Lebensläufen transformiert haben, die ATS passieren und Personalverantwortliche beeindrucken.

Jetzt erstellen

Diesen Beitrag teilen

Reduzieren Sie Ihre Lebenslauf-Schreibzeit um 90%

Der durchschnittliche Arbeitssuchende verbringt mehr als 3 Stunden mit der Formatierung eines Lebenslaufs. Unsere KI erledigt das in unter 15 Minuten und bringt Sie 12-mal schneller zur Bewerbungsphase.

Interviewfragen für erfahrene Site Reliability Engineers: Der umfassende Leitfaden | Minova - ATS Resume Builder