dezembro 21, 2025
15 min de leitura

Perguntas de entrevista para Senior Site Reliability Engineer

interview
career-advice
job-search
Perguntas de entrevista para Senior Site Reliability Engineer
Milad Bonakdar

Milad Bonakdar

Autor

Prepare-se para entrevistas sênior de SRE com perguntas práticas sobre SLOs, error budgets, capacidade, incidentes, chaos testing, plantão e decisões de confiabilidade.


Introdução

Espera-se que os Engenheiros de Confiabilidade de Site (SREs) seniores projetem sistemas confiáveis em escala, liderem respostas a incidentes, promovam a cultura SRE e tomem decisões estratégicas sobre investimentos em confiabilidade. Essa função exige profundo conhecimento técnico, habilidades de liderança e a capacidade de equilibrar confiabilidade com a velocidade dos negócios.

Este guia abrangente aborda as principais perguntas de entrevistas para SREs seniores, com foco em conceitos avançados, design de sistemas e impacto organizacional. Cada pergunta inclui explicações detalhadas e exemplos práticos.


Design Avançado de SLO

1. Como você projeta SLIs e SLOs para um novo serviço com dados limitados?

Resposta: Projetar SLOs para novos serviços exige equilibrar ambição com capacidade de realização:

Abordagem:

1. Comece com o mapeamento da jornada do usuário:

# Identifique as jornadas críticas do usuário
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. Defina SLIs com base na experiência do usuário:

# Especificação SLI
slis:
  availability:
    description: "Porcentagem de solicitações bem-sucedidas"
    measurement: "count(http_status < 500) / count(http_requests)"
    
  latency:
    description: "Latência de solicitação do percentil 95"
    measurement: "histogram_quantile(0.95, http_request_duration_seconds)"
    
  correctness:
    description: "Porcentagem de solicitações que retornam dados corretos"
    measurement: "count(validation_passed) / count(requests)"

3. Defina SLOs iniciais de forma conservadora:

def calculate_initial_slo(service_type, criticality):
    """
    Calcular SLO inicial com base nas características do serviço
    """
    base_slos = {
        'critical': {
            'availability': 0.999,  # 99,9%
            'latency_p95': 1.0,     # 1 segundo
            'latency_p99': 2.0      # 2 segundos
        },
        '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'])

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

4. Planeje a iteração:

  • Comece com uma janela de medição de 4 semanas
  • Revise o desempenho do SLO semanalmente
  • Ajuste com base no desempenho real e no feedback do usuário
  • Aperte os SLOs à medida que o sistema amadurece

5. Documente as premissas:

## Premissas do SLO (Inicial)

### Disponibilidade: 99,9%
- Assume: Confiabilidade padrão da infraestrutura de nuvem
- Orçamento de erro: 43 minutos/mês
- Revisão: Após 3 meses de dados

### Latência (p95): < 1s
- Assume: Consultas de banco de dados < 100ms
- Assume: Sem cálculos complexos
- Revisão: Se os padrões de consulta mudarem

### Dependências
- Disponibilidade da API externa: 99,95%
- Disponibilidade do banco de dados: 99,99%

Raridade: Comum
Dificuldade: Difícil


2. Como você lida com SLOs conflitantes entre diferentes segmentos de usuários?

Resposta: Diferentes segmentos de usuários geralmente têm diferentes necessidades de confiabilidade:

Estratégia: SLOs de vários níveis

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

# Defina os níveis
tiers = {
    'premium': SLOTier(
        name='Premium',
        availability=0.9999,  # 99,99% - 4,3 min/mês
        latency_p95=0.5,
        latency_p99=1.0
    ),
    'standard': SLOTier(
        name='Standard',
        availability=0.999,   # 99,9% - 43 min/mês
        latency_p95=1.0,
        latency_p99=2.0
    ),
    'free': SLOTier(
        name='Free',
        availability=0.99,    # 99% - 7,2 horas/mês
        latency_p95=2.0,
        latency_p99=5.0
    )
}

# Rota as solicitações com base no nível
def get_user_tier(user_id):
    # Consulte o nível de assinatura do usuário
    return user_subscription_tier(user_id)

def apply_slo_policy(user_id, request):
    tier = get_user_tier(user_id)
    slo = tiers[tier]
    
    # Aplique políticas específicas de nível
    request.timeout = slo.latency_p99
    request.priority = tier  # Para priorização de fila
    request.retry_budget = calculate_retry_budget(slo.error_budget)
    
    return request

Implementação com Roteamento de Tráfego:

# Exemplo do Kubernetes: Implantações separadas por nível
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"

Monitoramento por nível:

# Disponibilidade por nível
sum(rate(http_requests_total{status!~"5.."}[5m])) by (tier)
/
sum(rate(http_requests_total[5m])) by (tier)

# Latência por nível
histogram_quantile(0.95,
  rate(http_request_duration_seconds_bucket[5m])
) by (tier)

Raridade: Incomum
Dificuldade: Difícil


Planejamento de Capacidade

3. Descreva seu processo de planejamento de capacidade para um serviço em rápido crescimento.

Resposta: O planejamento de capacidade garante que os recursos atendam à demanda, otimizando os custos:

Estrutura de Planejamento de Capacidade:

Loading diagram...

1. Medir a linha de base:

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):
        """Analisar tendências históricas"""
        metric_data = self.data[metric_name].tail(days * 24)  # Dados por hora
        
        # Calcular taxa de crescimento
        start_value = metric_data.iloc[0]
        end_value = metric_data.iloc[-1]
        growth_rate = ((end_value - start_value) / start_value) * 100
        
        # Identificar o pico de uso
        peak_value = metric_data.max()
        peak_time = metric_data.idxmax()
        
        # Calcular percentis
        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):
        """Prever necessidades futuras de capacidade"""
        # Preparar dados
        df = self.data[[metric_name]].reset_index()
        df['days'] = (df.index / 24).astype(int)  # Converter horas em dias
        
        # Treinar modelo
        X = df[['days']].values
        y = df[metric_name].values
        
        model = LinearRegression()
        model.fit(X, y)
        
        # Prever
        future_days = np.array([[df['days'].max() + (30 * months_ahead)]])
        forecast = model.predict(future_days)[0]
        
        # Adicionar margem de segurança (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):
        """Calcular instâncias necessárias"""
        # Capacidade base
        base_instances = np.ceil(requests_per_second / requests_per_instance)
        
        # Adicionar margem de segurança para picos e manutenção
        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)
        }

# Exemplo de uso
metrics = {
    'requests_per_second': [100, 105, 110, 115, 120, ...],  # Dados históricos
    'cpu_usage': [45, 48, 50, 52, 55, ...],
    'memory_usage': [60, 62, 65, 67, 70, ...]
}

planner = CapacityPlanner(metrics)

# Analisar tendências
trends = planner.analyze_trends('requests_per_second', days=30)
print(f"Taxa de crescimento: {trends['growth_rate']:.2f}%")
print(f"Pico de RPS: {trends['peak_value']}")

# Prever capacidade
forecast = planner.forecast_capacity('requests_per_second', months_ahead=3)
print(f"RPS previsto em 3 meses: {forecast['forecast']:.0f}")
print(f"Com margem de segurança: {forecast['with_margin']:.0f}")

# Calcular necessidades de recursos
resources = planner.calculate_resource_needs(
    requests_per_second=forecast['with_margin'],
    requests_per_instance=100,
    headroom=0.3
)
print(f"Instâncias necessárias: {resources['total_instances']}")

2. Considere os impulsionadores de crescimento:

  • Taxa de crescimento do usuário
  • Lançamentos de recursos
  • Padrões sazonais
  • Campanhas de marketing
  • Expansão geográfica

3. Planeje a margem de segurança:

  • N+1: Sobreviva a uma falha de instância
  • N+2: Sobreviva a duas falhas ou uma interrupção de zona
  • Picos de tráfego: 2-3x a capacidade normal
  • Janelas de manutenção: 20-30% de sobrecarga

4. Otimização de custos:

def optimize_instance_mix(workload_profile):
    """
    Otimizar tipos de instância para custo
    """
    # Combinação de tipos de instância
    instance_types = {
        'on_demand': {
            'cost_per_hour': 0.10,
            'reliability': 1.0,
            'percentage': 0.3  # 30% sob demanda para linha de base
        },
        'spot': {
            'cost_per_hour': 0.03,
            'reliability': 0.95,
            'percentage': 0.5  # 50% spot para economia de custos
        },
        'reserved': {
            'cost_per_hour': 0.06,
            'reliability': 1.0,
            'percentage': 0.2  # 20% reservado para carga previsível
        }
    }
    
    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

Raridade: Muito Comum
Dificuldade: Difícil


Engenharia do Caos

4. Como você implementa a engenharia do caos em produção?

Resposta: A engenharia do caos testa proativamente a resiliência do sistema, injetando falhas:

Princípios da Engenharia do Caos:

  1. Construa uma hipótese em torno do estado estável
  2. Varie eventos do mundo real
  3. Execute experimentos em produção
  4. Automatize experimentos
  5. Minimize o raio de explosão

Implementação:

# Estrutura de experimento de caos
from dataclasses import dataclass
from enum import Enum
import random
import time

class ExperimentStatus(Enum):
    PLANNED = "planejado"
    RUNNING = "em_execução"
    COMPLETED = "concluído"
    ABORTED = "abortado"

@dataclass
class ChaosExperiment:
    name: str
    hypothesis: str
    blast_radius: float  # Porcentagem do tráfego afetado
    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):
        """Executar experimento de caos com verificações de segurança"""
        print(f"Iniciando experimento: {experiment.name}")
        
        # 1. Medir a linha de base
        experiment.metrics_before = self.measure_metrics()
        print(f"Métricas de linha de base: {experiment.metrics_before}")
        
        # 2. Verificar se o sistema está saudável
        if not self.is_system_healthy(experiment.metrics_before):
            print("Sistema não saudável, abortando o experimento")
            return False
        
        # 3. Injetar falha
        experiment.status = ExperimentStatus.RUNNING
        failure_injection = self.inject_failure(experiment)
        
        try:
            # 4. Monitorar durante o experimento
            start_time = time.time()
            while time.time() - start_time < experiment.duration_seconds:
                experiment.metrics_during = self.measure_metrics()
                
                # Verificar critérios de reversão
                if self.should_rollback(experiment):
                    print("Critérios de reversão atendidos, interrompendo o experimento")
                    self.rollback(failure_injection)
                    experiment.status = ExperimentStatus.ABORTED
                    return False
                
                time.sleep(10)  # Verificar a cada 10 segundos
            
            # 5. Reverter a injeção de falha
            self.rollback(failure_injection)
            
            # 6. Medir a recuperação
            time.sleep(60)  # Aguardar a estabilização do sistema
            experiment.metrics_after = self.measure_metrics()
            
            # 7. Analisar os resultados
            experiment.status = ExperimentStatus.COMPLETED
            return self.analyze_results(experiment)
            
        except Exception as e:
            print(f"Experimento falhou: {e}")
            self.rollback(failure_injection)
            experiment.status = ExperimentStatus.ABORTED
            return False
    
    def inject_failure(self, experiment):
        """Injetar tipo de falha específico"""
        # A implementação depende do tipo de falha
        pass
    
    def measure_metrics(self):
        """Medir as principais métricas do sistema"""
        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):
        """Verificar se o sistema atende aos SLOs"""
        return (
            metrics['error_rate'] < 0.01 and  # < 1% de erros
            metrics['latency_p95'] < 1.0 and  # < 1s de latência
            metrics['availability'] > 0.999   # > 99,9% disponível
        )
    
    def should_rollback(self, experiment):
        """Verificar se o experimento deve ser abortado"""
        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):
        """Remover a injeção de falha"""
        print("Revertendo a injeção de falha")
        # A implementação depende do tipo de falha
    
    def analyze_results(self, experiment):
        """Analisar os resultados do experimento"""
        before = experiment.metrics_before
        during = experiment.metrics_during
        after = experiment.metrics_after
        
        print(f"\nResultados do Experimento: {experiment.name}")
        print(f"Hipótese: {experiment.hypothesis}")
        print(f"\nMétricas:")
        print(f"  Antes: {before}")
        print(f"  Durante: {during}")
        print(f"  Depois: {after}")
        
        # Determinar se a hipótese foi validada
        hypothesis_validated = (
            during['availability'] >= experiment.rollback_criteria['min_availability']
        )
        
        return hypothesis_validated

# Exemplo de experimento
experiment = ChaosExperiment(
    name="Teste de Failover do Banco de Dados",
    hypothesis="O sistema permanece disponível durante o failover do banco de dados",
    blast_radius=0.1,  # 10% do tráfego
    duration_seconds=300,  # 5 minutos
    rollback_criteria={
        'max_error_rate': 0.05,
        'max_latency': 5.0,
        'min_availability': 0.99
    }
)

Experimentos de Caos Comuns:

1. Latência de Rede:

# Usando tc (traffic control) para adicionar latência
tc qdisc add dev eth0 root netem delay 100ms 20ms

# Reverter
tc qdisc del dev eth0 root

2. Falha de Pod (Kubernetes):

# Matar pods aleatórios
kubectl delete pod -l app=myapp --random=1

# Usando 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. Esgotamento de Recursos:

# Estresse de CPU
stress-ng --cpu 4 --timeout 60s

# Estresse de memória
stress-ng --vm 2 --vm-bytes 2G --timeout 60s

Raridade: Comum
Dificuldade: Difícil


Liderança de Incidentes

5. Como você lidera um incidente de alta gravidade desde a detecção até o post-mortem?

Resposta: SREs seniores geralmente atuam como comandantes de incidentes para interrupções críticas:

Estrutura de Comando de Incidentes:

Loading diagram...

Responsabilidades do Comandante de Incidentes:

1. Resposta Inicial (0-5 minutos):

## Checklist do Comandante de Incidentes

### Ações Imediatas
- [ ] Reconhecer o incidente
- [ ] Avaliar a gravidade (SEV-1, SEV-2, SEV-3)
- [ ] Criar canal de incidente (#incident-AAAA-MM-DD-NNN)
- [ ] Acionar as equipes apropriadas
- [ ] Designar funções:
  - [ ] Líder Técnico
  - [ ] Líder de Comunicações
  - [ ] Escriba (documentar a linha do tempo)

### Avaliação de Gravidade
**SEV-1 (Crítico):**
- Interrupção completa do serviço
- Perda de dados
- Violação de segurança
- > 50% dos usuários afetados

**SEV-2 (Alto):**
- Interrupção parcial
- Desempenho degradado
- 10-50% dos usuários afetados

**SEV-3 (Médio):**
- Degradação menor
- < 10% dos usuários afetados
- Solução alternativa disponível

2. Fase de Investigação:

class IncidentCommander:
    def __init__(self, incident_id):
        self.incident_id = incident_id
        self.timeline = []
        self.status_updates = []
        self.action_items = []
    
    def coordinate_investigation(self):
        """Coordenar a investigação técnica"""
        # Rastreamentos de investigação paralelos
        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):
        """Tomar decisão com tempo limitado"""
        print(f"Decisão necessária em {deadline_minutes} minutos")
        print(f"Opções: {options}")
        
        # Coletar informações dos líderes técnicos
        # Tomar decisão com base em:
        # - Impacto no usuário
        # - Risco de cada opção
        # - Tempo para implementar
        # - Reversibilidade
        
        return selected_option
    
    def communicate_status(self, interval_minutes=15):
        """Atualizações regulares de status"""
        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)
        }
        
        # Enviar para as partes interessadas
        self.send_status_update(update)
        self.status_updates.append(update)
    
    def log_timeline_event(self, event, timestamp=None):
        """Documentar a linha do tempo do incidente"""
        self.timeline.append({
            'timestamp': timestamp or datetime.now(),
            'event': event,
            'logged_by': self.get_current_user()
        })

3. Estratégias de Mitigação:

def evaluate_mitigation_options():
    """Avaliar e priorizar opções de mitigação"""
    options = [
        {
            'action': 'Reverter implantação',
            'time_to_implement': 5,  # minutos
            'risk': 'low',
            'effectiveness': 'high',
            'reversible': True
        },
        {
            'action': 'Aumentar a escala dos recursos',
            'time_to_implement': 2,
            'risk': 'low',
            'effectiveness': 'medium',
            'reversible': True
        },
        {
            'action': 'Desativar o recurso',
            'time_to_implement': 1,
            'risk': 'low',
            'effectiveness': 'high',
            'reversible': True
        },
        {
            'action': 'Failover do banco de dados',
            'time_to_implement': 10,
            'risk': 'medium',
            'effectiveness': 'high',
            'reversible': False
        }
    ]
    
    # Classificar por: baixo risco, alta eficácia, implementação rápida
    sorted_options = sorted(
        options,
        key=lambda x: (
            x['risk'] == 'low',
            x['effectiveness'] == 'high',
            -x['time_to_implement']
        ),
        reverse=True
    )
    
    return sorted_options

4. Post-mortem (Sem Culpa):

# Post-mortem do Incidente: Interrupção da API

**Data:** 2024-11-25  
**Duração:** 45 minutos  
**Gravidade:** SEV-1  
**Comandante do Incidente:** Alice  
**Líder Técnico:** Bob

## Resumo Executivo
Interrupção completa da API afetando todos os usuários devido ao esgotamento do pool de conexões do banco de dados.

## Impacto
- **Usuários afetados:** 100% (todos os usuários)
- **Duração:** 45 minutos
- **Impacto na receita:** ~$50.000
- **Impacto no SLO:** Consumiu 75% do orçamento de erro mensal

## Causa Raiz
Pool de conexões do banco de dados esgotado devido ao vazamento de conexão no novo recurso implantado 2 horas antes do incidente.

## Linha do Tempo
| Hora  | Evento                                             |
|-------|----------------------------------------------------|
| 14:00 | Implantação da v2.5.0                              |
| 15:45 | Primeiros alertas para aumento da latência        |
| 15:50 | Interrupção completa da API                        |
| 15:52 | Incidente declarado (SEV-1)                        |
| 15:55 | Banco de dados identificado como gargalo          |
| 16:05 | Decisão de reverter a implantação                 |
| 16:15 | Reversão concluída                                 |
| 16:20 | Serviço em recuperação                             |
| 16:35 | Recuperação total confirmada                       |

## O Que Deu Certo
- Detecção rápida (5 minutos a partir do primeiro sintoma)
- Estrutura de comando de incidente clara
- Decisão rápida de reverter
- Boa comunicação com as partes interessadas

## O Que Deu Errado
- Vazamento de conexão não detectado nos testes
- Sem monitoramento do pool de conexões
- Implantação durante o horário de pico

## Itens de Ação
| Ação                                     | Proprietário | Data de Vencimento | Status |
|------------------------------------------|------------|-------------------|--------|
| Adicionar monitoramento do pool de conexões | Alice      | 2024-12-01        | Aberto |
| Implementar detecção de vazamento de conexão nos testes | Bob        | 2024-12-05        | Aberto |
| Atualizar política de implantação (evitar horários de pico) | Charlie    | 2024-11-30        | Aberto |
| Adicionar disjuntor para conexões de banco de dados | David      | 2024-12-10        | Aberto |

## Lições Aprendidas
- Lacunas de monitoramento podem ocultar problemas críticos
- O tempo de implantação é importante
- Necessidade de melhor teste de integração para vazamentos de recursos

Raridade: Muito Comum
Dificuldade: Difícil


Confiabilidade de Sistemas Distribuídos

6. Como você garante a confiabilidade em uma arquitetura de microsserviços distribuídos?

Resposta: Sistemas distribuídos introduzem desafios únicos de confiabilidade:

Padrões Chave:

1. Service Mesh para Resiliência:

# Exemplo do Istio: Disjuntor e tentativas
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. Rastreamento Distribuído:

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

# Configurar rastreamento
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)
)

# Instrumentar a biblioteca de solicitações
RequestsInstrumentor().instrument()

# Usar no código
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)
        
        # Chamar o serviço de pagamento
        with tracer.start_as_current_span("call_payment_service"):
            payment_result = call_payment_service(order_id)
        
        # Chamar o serviço de inventário
        with tracer.start_as_current_span("call_inventory_service"):
            inventory_result = call_inventory_service(

Conclusão

As melhores respostas de SRE sênior soam como julgamento de produção, não como definições decoradas. Pratique explicar como você define SLOs a partir de jornadas de usuário, usa error budgets para orientar risco de release, valida capacidade com dados reais de carga, executa experimentos de caos controlados, lidera incidentes com papéis claros e reduz toil sem esconder risco.

Antes da entrevista, prepare duas ou três histórias concretas: um incidente que você liderou, um tradeoff de confiabilidade que influenciou e uma melhoria de automação ou observabilidade que mudou o comportamento do time. Em cada história, cite o sinal, a decisão, o tradeoff e o acompanhamento posterior.

Newsletter subscription

Dicas de carreira semanais que realmente funcionam

Receba as últimas ideias diretamente na sua caixa de entrada

Crie um Currículo que Te Contrate 60% Mais Rápido

Em minutos, crie um currículo personalizado e compatível com ATS comprovado para conseguir 6 vezes mais entrevistas.

Crie um currículo melhor

Compartilhar esta publicação

Faça Seus 6 Segundos Contarem

Os recrutadores escaneiam currículos por uma média de apenas 6 a 7 segundos. Nossos modelos comprovados são projetados para capturar atenção instantaneamente e mantê-los lendo.