декабря 21, 2025
13 мин. чтения

Вопросы для собеседования на позицию старшего инженера по надежности сайта: Полное руководство

interview
career-advice
job-search
Вопросы для собеседования на позицию старшего инженера по надежности сайта: Полное руководство
MB

Milad Bonakdar

Автор

Освойте продвинутые концепции SRE с помощью исчерпывающих вопросов для собеседования, охватывающих планирование ресурсов, хаос-инжиниринг, распределенные системы, проектирование SLO, руководство при инцидентах и организационные практики SRE для руководящих должностей.


Введение

От старших инженеров SRE ожидают проектирование надежных систем в масштабе, руководство реагированием на инциденты, продвижение культуры SRE и принятие стратегических решений об инвестициях в надежность. Эта роль требует глубокой технической экспертизы, лидерских качеств и способности балансировать между надежностью и скоростью бизнеса.

Это подробное руководство охватывает основные вопросы для собеседования старших SRE, уделяя особое внимание продвинутым концепциям, проектированию систем и организационному воздействию. Каждый вопрос включает подробные объяснения и практические примеры.


Продвинутое проектирование SLO

1. Как вы разрабатываете SLI и SLO для нового сервиса с ограниченным объемом данных?

Ответ: Разработка SLO для новых сервисов требует баланса между амбициями и достижимостью:

Подход:

1. Начните с картирования пути пользователя:

# Определите критические пути пользователей
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. Определите SLI на основе пользовательского опыта:

# Спецификация SLI
slis:
  availability:
    description: "Процент успешных запросов"
    measurement: "count(http_status < 500) / count(http_requests)"
    
  latency:
    description: "95-й процентиль задержки запроса"
    measurement: "histogram_quantile(0.95, http_request_duration_seconds)"
    
  correctness:
    description: "Процент запросов, возвращающих корректные данные"
    measurement: "count(validation_passed) / count(requests)"

3. Установите начальные SLO консервативно:

def calculate_initial_slo(service_type, criticality):
    """
    Рассчитайте начальный SLO на основе характеристик сервиса
    """
    base_slos = {
        'critical': {
            'availability': 0.999,  # 99.9%
            'latency_p95': 1.0,     # 1 секунда
            'latency_p99': 2.0      # 2 секунды
        },
        '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'])

# Пример
checkout_slo = calculate_initial_slo('payment', 'critical')
print(f"Checkout SLO: {checkout_slo}")

4. Запланируйте итерации:

  • Начните с 4-недельного окна измерений
  • Еженедельно проверяйте производительность SLO
  • Корректируйте на основе фактической производительности и отзывов пользователей
  • Ужесточайте SLO по мере развития системы

5. Задокументируйте предположения:

## Предположения SLO (начальные)

### Доступность: 99,9%
- Предполагается: Стандартная надежность облачной инфраструктуры
- Бюджет ошибок: 43 минуты/месяц
- Обзор: После 3 месяцев данных

### Задержка (p95): < 1 с
- Предполагается: Запросы к базе данных < 100 мс
- Предполагается: Отсутствие сложных вычислений
- Обзор: Если шаблоны запросов изменятся

### Зависимости
- Доступность внешнего API: 99,95%
- Доступность базы данных: 99,99%

Редкость: Распространенный
Сложность: Высокий


2. Как вы справляетесь с конфликтующими SLO для разных сегментов пользователей?

Ответ: Разные сегменты пользователей часто имеют разные потребности в надежности:

Стратегия: Многоуровневые SLO

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

# Определите уровни
tiers = {
    'premium': SLOTier(
        name='Premium',
        availability=0.9999,  # 99.99% - 4.3 мин/месяц
        latency_p95=0.5,
        latency_p99=1.0
    ),
    'standard': SLOTier(
        name='Standard',
        availability=0.999,   # 99.9% - 43 мин/месяц
        latency_p95=1.0,
        latency_p99=2.0
    ),
    'free': SLOTier(
        name='Free',
        availability=0.99,    # 99% - 7.2 часа/месяц
        latency_p95=2.0,
        latency_p99=5.0
    )
}

# Маршрутизируйте запросы на основе уровня
def get_user_tier(user_id):
    # Поиск уровня подписки пользователя
    return user_subscription_tier(user_id)

def apply_slo_policy(user_id, request):
    tier = get_user_tier(user_id)
    slo = tiers[tier]
    
    # Примените политики, специфичные для уровня
    request.timeout = slo.latency_p99
    request.priority = tier  # Для приоритизации очереди
    request.retry_budget = calculate_retry_budget(slo.error_budget)
    
    return request

Реализация с маршрутизацией трафика:

# Пример Kubernetes: Отдельные развертывания для каждого уровня
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"

Мониторинг по уровням:

# Доступность по уровням
sum(rate(http_requests_total{status!~"5.."}[5m])) by (tier)
/
sum(rate(http_requests_total[5m])) by (tier)

# Задержка по уровням
histogram_quantile(0.95,
  rate(http_request_duration_seconds_bucket[5m])
) by (tier)

Редкость: Необычный
Сложность: Высокий


Планирование ресурсов

3. Опишите свой процесс планирования ресурсов для быстрорастущего сервиса.

Ответ: Планирование ресурсов обеспечивает соответствие ресурсов спросу при оптимизации затрат:

Структура планирования ресурсов:

Loading diagram...

1. Измерение базового уровня:

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):
        """Анализ исторических тенденций"""
        metric_data = self.data[metric_name].tail(days * 24)  # Почасовые данные
        
        # Рассчитайте темп роста
        start_value = metric_data.iloc[0]
        end_value = metric_data.iloc[-1]
        growth_rate = ((end_value - start_value) / start_value) * 100
        
        # Определите пиковое использование
        peak_value = metric_data.max()
        peak_time = metric_data.idxmax()
        
        # Рассчитайте процентили
        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):
        """Прогнозирование будущих потребностей в ресурсах"""
        # Подготовьте данные
        df = self.data[[metric_name]].reset_index()
        df['days'] = (df.index / 24).astype(int)  # Преобразование часов в дни
        
        # Обучите модель
        X = df[['days']].values
        y = df[metric_name].values
        
        model = LinearRegression()
        model.fit(X, y)
        
        # Прогноз
        future_days = np.array([[df['days'].max() + (30 * months_ahead)]])
        forecast = model.predict(future_days)[0]
        
        # Добавьте запас прочности (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):
        """Рассчитайте требуемые экземпляры"""
        # Базовая емкость
        base_instances = np.ceil(requests_per_second / requests_per_instance)
        
        # Добавьте запас прочности для скачков и обслуживания
        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)
        }

# Пример использования
metrics = {
    'requests_per_second': [100, 105, 110, 115, 120, ...],  # Исторические данные
    'cpu_usage': [45, 48, 50, 52, 55, ...],
    'memory_usage': [60, 62, 65, 67, 70, ...]
}

planner = CapacityPlanner(metrics)

# Анализ тенденций
trends = planner.analyze_trends('requests_per_second', days=30)
print(f"Темп роста: {trends['growth_rate']:.2f}%")
print(f"Пиковый RPS: {trends['peak_value']}")

# Прогнозирование ресурсов
forecast = planner.forecast_capacity('requests_per_second', months_ahead=3)
print(f"Прогнозируемый RPS через 3 месяца: {forecast['forecast']:.0f}")
print(f"С запасом прочности: {forecast['with_margin']:.0f}")

# Рассчитайте потребности в ресурсах
resources = planner.calculate_resource_needs(
    requests_per_second=forecast['with_margin'],
    requests_per_instance=100,
    headroom=0.3
)
print(f"Требуемые экземпляры: {resources['total_instances']}")

2. Учитывайте драйверы роста:

  • Темп роста пользователей
  • Запуск новых функций
  • Сезонные закономерности
  • Маркетинговые кампании
  • Географическое расширение

3. Планируйте резерв:

  • N+1: Пережить отказ одного экземпляра
  • N+2: Пережить два отказа или одно отключение зоны
  • Скачки трафика: 2-3-кратная нормальная емкость
  • Окна обслуживания: 20-30% накладных расходов

4. Оптимизация затрат:

def optimize_instance_mix(workload_profile):
    """
    Оптимизируйте типы экземпляров для снижения затрат
    """
    # Сочетание типов экземпляров
    instance_types = {
        'on_demand': {
            'cost_per_hour': 0.10,
            'reliability': 1.0,
            'percentage': 0.3  # 30% по требованию для базового уровня
        },
        'spot': {
            'cost_per_hour': 0.03,
            'reliability': 0.95,
            'percentage': 0.5  # 50% спотовых для экономии затрат
        },
        'reserved': {
            'cost_per_hour': 0.06,
            'reliability': 1.0,
            'percentage': 0.2  # 20% зарезервированных для предсказуемой нагрузки
        }
    }
    
    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

Редкость: Очень распространенный
Сложность: Высокий


Хаос-инжиниринг

4. Как вы реализуете хаос-инжиниринг в production?

Ответ: Хаос-инжиниринг активно тестирует устойчивость системы путем внедрения отказов:

Принципы хаос-инжиниринга:

  1. Постройте гипотезу вокруг устойчивого состояния
  2. Варьируйте реальные события
  3. Проводите эксперименты в production
  4. Автоматизируйте эксперименты
  5. Минимизируйте радиус поражения

Реализация:

# Структура хаос-эксперимента
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  # Процент затронутого трафика
    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):
        """Выполните хаос-эксперимент с проверками безопасности"""
        print(f"Запуск эксперимента: {experiment.name}")
        
        # 1. Измерьте базовый уровень
        experiment.metrics_before = self.measure_metrics()
        print(f"Базовые метрики: {experiment.metrics_before}")
        
        # 2. Убедитесь, что система работоспособна
        if not self.is_system_healthy(experiment.metrics_before):
            print("Система неработоспособна, прерываем эксперимент")
            return False
        
        # 3. Внедрите отказ
        experiment.status = ExperimentStatus.RUNNING
        failure_injection = self.inject_failure(experiment)
        
        try:
            # 4. Мониторинг во время эксперимента
            start_time = time.time()
            while time.time() - start_time < experiment.duration_seconds:
                experiment.metrics_during = self.measure_metrics()
                
                # Проверьте критерии отката
                if self.should_rollback(experiment):
                    print("Критерии отката выполнены, останавливаем эксперимент")
                    self.rollback(failure_injection)
                    experiment.status = ExperimentStatus.ABORTED
                    return False
                
                time.sleep(10)  # Проверяйте каждые 10 секунд
            
            # 5. Откат внедрения отказа
            self.rollback(failure_injection)
            
            # 6. Измерьте восстановление
            time.sleep(60)  # Подождите, пока система стабилизируется
            experiment.metrics_after = self.measure_metrics()
            
            # 7. Проанализируйте результаты
            experiment.status = ExperimentStatus.COMPLETED
            return self.analyze_results(experiment)
            
        except Exception as e:
            print(f"Эксперимент не удался: {e}")
            self.rollback(failure_injection)
            experiment.status = ExperimentStatus.ABORTED
            return False
    
    def inject_failure(self, experiment):
        """Внедрите определенный тип отказа"""
        # Реализация зависит от типа отказа
        pass
    
    def measure_metrics(self):
        """Измерьте ключевые системные метрики"""
        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):
        """Проверьте, соответствует ли система SLO"""
        return (
            metrics['error_rate'] < 0.01 and  # < 1% ошибок
            metrics['latency_p95'] < 1.0 and  # < 1с задержки
            metrics['availability'] > 0.999   # > 99.9% доступности
        )
    
    def should_rollback(self, experiment):
        """Проверьте, следует ли прервать эксперимент"""
        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):
        """Удалите внедрение отказа"""
        print("Откат внедрения отказа")
        # Реализация зависит от типа отказа
    
    def analyze_results(self, experiment):
        """Проанализируйте результаты эксперимента"""
        before = experiment.metrics_before
        during = experiment.metrics_during
        after = experiment.metrics_after
        
        print(f"\nРезультаты эксперимента: {experiment.name}")
        print(f"Гипотеза: {experiment.hypothesis}")
        print(f"\nМетрики:")
        print(f"  До: {before}")
        print(f"  Во время: {during}")
        print(f"  После: {after}")
        
        # Определите, была ли подтверждена гипотеза
        hypothesis_validated = (
            during['availability'] >= experiment.rollback_criteria['min_availability']
        )
        
        return hypothesis_validated

# Пример эксперимента
experiment = ChaosExperiment(
    name="Тест переключения базы данных",
    hypothesis="Система остается доступной во время переключения базы данных",
    blast_radius=0.1,  # 10% трафика
    duration_seconds=300,  # 5 минут
    rollback_criteria={
        'max_error_rate': 0.05,
        'max_latency': 5.0,
        'min_availability': 0.99
    }
)

Распространенные хаос-эксперименты:

1. Задержка сети:

# Использование tc (traffic control) для добавления задержки
tc qdisc add dev eth0 root netem delay 100ms 20ms

# Откат
tc qdisc del dev eth0 root

2. Отказ Pod (Kubernetes):

# Уничтожьте случайные pod
kubectl delete pod -l app=myapp --random=1

# Использование 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. Исчерпание ресурсов:

# Нагрузка на ЦП
stress-ng --cpu 4 --timeout 60s

# Нагрузка на память
stress-ng --vm 2 --vm-bytes 2G --timeout 60s

Редкость: Распространенный
Сложность: Высокий


Руководство при инцидентах

5. Как вы руководите инцидентом высокой степени тяжести от обнаружения до посмертного анализа?

Ответ: Старшие SRE часто выступают в качестве руководителей инцидентов при критических сбоях:

Структура управления инцидентами:

Loading diagram...

Обязанности руководителя инцидента:

1. Первоначальный ответ (0-5 минут):

## Чек-лист руководителя инцидента

### Немедленные действия
- [ ] Подтвердите инцидент
- [ ] Оцените степень тяжести (SEV-1, SEV-2, SEV-3)
- [ ] Создайте канал инцидента (#incident-YYYY-MM-DD-NNN)
- [ ] Оповестите соответствующие команды
- [ ] Назначьте роли:
  - [ ] Технический руководитель
  - [ ] Руководитель по коммуникациям
  - [ ] Писец (документируйте хронологию)

### Оценка степени тяжести
**SEV-1 (Критический):**
- Полное отключение сервиса
- Потеря данных
- Нарушение безопасности
- Затронуто > 50% пользователей

**SEV-2 (Высокий):**
- Частичное отключение
- Ухудшение производительности
- Затронуто 10-50% пользователей

**SEV-3 (Средний):**
- Незначительное ухудшение
- Затронуто < 10% пользователей
- Доступно обходное решение

2. Фаза расследования:

class IncidentCommander:
    def __init__(self, incident_id):
        self.incident_id = incident_id
        self.timeline = []
        self.status_updates = []
        self.action_items = []
    
    def coordinate_investigation(self):
        """Координируйте техническое расследование"""
        # Параллельные направления расследования
        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):
        """Примите решение в ограниченный срок"""
        print(f"Решение необходимо принять в течение {deadline_minutes} минут")
        print(f"Варианты: {options}")
        
        # Соберите информацию от технических руководителей
        # Примите решение на основе:
        # - Влияния на пользователя
        # - Риска каждого варианта
        # - Времени на реализацию
        # - Обратимости
        
        return selected_option
    
    def communicate_status(self, interval_minutes=15):
        """Регулярные обновления статуса"""
        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)
        }
        
        # Отправьте заинтересованным сторонам
        self.send_status_update(update)
        self.status_updates.append(update)
    
    def log_timeline_event(self, event, timestamp=None):
        """Документируйте ход инцидента"""
        self.timeline.append({
            'timestamp': timestamp or datetime.now(),
            'event': event,
            'logged_by': self.get_current_user()
        })

3. Стратегии смягчения последствий:

def evaluate_mitigation_options():
    """Оцените и расставьте приоритеты для вариантов смягчения последствий"""
    options = [
        {
            'action': 'Откат развертывания',
            'time_to_implement': 5,  # минуты
            'risk': 'low',
            'effectiveness': 'high',
            'reversible': True
        },
        {
            'action': 'Масштабирование ресурсов',
            'time_to_implement': 2,
            'risk': 'low',
            'effectiveness': 'medium',
            'reversible': True
        },
        {
            'action': 'Отключение флага функции',
            'time_to_implement': 1,
            'risk': 'low',
            'effectiveness': 'high',
            'reversible': True
        },
        {
            'action': 'Переключение базы данных',
            'time_to_implement': 10,
            'risk': 'medium',
            'effectiveness': 'high',
            'reversible': False
        }
    ]
    
    # Сортировка по: низкому риску, высокой эффективности, быстрой реализации
    sorted_options = sorted(
        options,
        key=lambda x: (
            x['risk'] == 'low',
            x['effectiveness'] == 'high',
            -x['time_to_implement']
        ),
        reverse=True
    )
    
    return sorted_options

4. Посмертный анализ (без обвинений):

# Посмертный анализ инцидента: Отключение API

**Дата:** 2024-11-25  
**Продолжительность:** 45 минут  
**Степень тяжести:** SEV-1  
**Руководитель инцидента:** Алиса  
**Технический руководитель:** Боб

## Краткое описание
Полное отключение API, затронувшее всех пользователей из-за исчерпания пула подключений к базе данных.

## Влияние
- **Затронутые пользователи:** 100% (все пользователи)
- **Продолжительность:** 45 минут
- **Влияние на доход:** ~$50 000
- **Влияние на SLO:** Израсходовано 75% месячного бюджета ошибок

## Основная причина
Пул подключений к базе данных исчерпан из-за утечки подключений в новой функции, развернутой за 2 часа до инцидента.

## Хронология
| Время | Событие |
|------|-------|
| 14:00 | Развертывание v2.5.0 |
| 15:45 | Первые предупреждения об увеличении задержки |
| 15:50 | Полное отключение API |
| 15:52 | Объявлен инцидент (SEV-1) |
| 15:55 | База данных определена как узкое место |
| 16:05 | Решение об откате развертывания |
| 16:15 | Откат завершен |
| 16:20 | Сервис восстанавливается |
| 16:35 | Подтверждено полное восстановление |

## Что прошло хорошо
- Быстрое обнаружение (5 минут с момента первого симптома)
- Четкая структура управления инцидентами
- Быстрое решение об откате
- Хорошая коммуникация с заинтересованными сторонами

## Что пошло не так
- Утечка подключений не была обнаружена при тестировании
- Отсутствует мониторинг пула подключений
- Развертывание в часы пик

## Элементы действий
| Действие | Владелец | Срок выполнения | Статус |
|--------|-------|----------|--------|
| Добавьте мониторинг пула подключений | Алиса | 2024-12-01 | Открыто |
| Реализуйте обнаружение утечек подключений в тестах | Боб | 2024-12-05 | Открыто |
| Обновите политику развертывания (избегайте часов пик) | Чарли | 2024-11-30 | Открыто |
| Добавьте автоматический выключатель для подключений к базе данных | Дэвид | 2024-12-10 | Открыто |

## Извлеченные уроки
- Пробелы в мониторинге могут скрыть критические проблемы
- Время развертывания имеет значение
- Необходимы более качественные интеграционные тесты для утечек ресурсов

Редкость: Очень распространенный
Сложность: Высокий


Надежность распределенных систем

6. Как вы обеспечиваете надежность в распределенной архитектуре микросервисов?

Ответ: Распределенные системы создают уникальные проблемы с надежностью:

Ключевые шаблоны:

1. Service Mesh для устойчивости:

# Пример Istio: Circuit breaking и повторы
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. Распределенная трассировка:

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

# Настройка трассировки
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)
)
Newsletter subscription

Еженедельные советы по карьере, которые действительно работают

Получайте последние идеи прямо на вашу почту

Похожие посты

Decorative doodle

Ваше следующее собеседование — всего одно резюме

Создайте профессиональное оптимизированное резюме за несколько минут. Не нужны навыки дизайна—только проверенные результаты.

Создать моё резюме

Поделиться этим постом

Используйте Свои 6 Секунд По Максимуму

Рекрутеры просматривают резюме в среднем всего 6-7 секунд. Наши проверенные шаблоны разработаны так, чтобы мгновенно привлекать внимание и заставлять продолжать чтение.