Hot Reload и Система Алертов
Hot Reload и Система Алертов
🔄 Hot Reload Конфигурации
Обзор
Система hot reload позволяет изменять конфигурацию приложения без перезапуска. Изменения в файле configs/config.yaml автоматически применяются в реальном времени.
Архитектура Hot Reload
sequenceDiagram
participant User as Пользователь
participant FS as Файловая система
participant Watcher as Config Watcher
participant Manager as Config Manager
participant Validator as Config Validator
participant Subscribers as Подписчики
User->>FS: Изменяет config.yaml
FS->>Watcher: Событие изменения
Watcher->>Manager: Обнаружено изменение
Manager->>FS: Чтение файла
Manager->>Validator: Валидация конфигурации
alt Валидация успешна
Validator->>Manager: OK
Manager->>Subscribers: Уведомление об изменениях
Subscribers->>Subscribers: Обновление конфигурации
else Валидация не прошла
Validator->>Manager: Ошибка
Manager->>Manager: Откат изменений
endВозможности
- Автоматическое отслеживание изменений в файле конфигурации
- Валидация конфигурации перед применением
- Уведомления подписчиков об изменениях
- Graceful применение изменений без прерывания работы
Использование
1. Изменение конфигурации
# Редактируем конфигурацию
vim configs/config.yaml
# Изменения применяются автоматически
# Логи покажут результат применения
2. Подписка на изменения
// Подписываемся на изменения конфигурации
configManager.Subscribe("worker_pool", func(oldConfig, newConfig *model.Config) error {
// Обновляем worker pool с новыми настройками
workerPool.UpdateConfig(newConfig.SystemSetup.WorkerPool)
return nil
})
3. Принудительная перезагрузка
// Принудительно перезагружаем конфигурацию
err := configManager.Reload()
if err != nil {
log.Error("Ошибка перезагрузки конфигурации", slog.String("error", err.Error()))
}
Валидация конфигурации
Система автоматически валидирует:
- Положительные значения для портов и размеров
- Обязательные поля (URL, hostnames)
- Корректность структуры данных
- Наличие хотя бы одной биржи
Логирование
✅ ConfigManager инициализирован config_path=configs/config.yaml
🔍 Мониторинг изменений конфигурации file=configs/config.yaml
📝 Обнаружено изменение конфигурации file=configs/config.yaml operation=WRITE
✅ Конфигурация успешно перезагружена
🚨 Система Алертов
Обзор
Система алертов обеспечивает мониторинг состояния приложения и уведомления о проблемах через различные каналы.
Архитектура системы алертов
graph TB
subgraph "Система алертов"
RULES[Alert Rules]
EVALUATOR[Rule Evaluator]
MANAGER[Alert Manager]
end
subgraph "Каналы уведомлений"
LOG[Log Channel]
CONSOLE[Console Channel]
FILE[File Channel]
WEBHOOK[Webhook Channel]
SLACK[Slack Channel]
end
subgraph "Источники данных"
METRICS[Prometheus Metrics]
HEALTH[Health Checks]
SYSTEM[System Stats]
end
METRICS --> RULES
HEALTH --> RULES
SYSTEM --> RULES
RULES --> EVALUATOR
EVALUATOR --> MANAGER
MANAGER --> LOG
MANAGER --> CONSOLE
MANAGER --> FILE
MANAGER --> WEBHOOK
MANAGER --> SLACKУровни алертов
- Info - информационные сообщения
- Warning - предупреждения
- Error - ошибки
- Critical - критические проблемы
Каналы уведомлений
1. Логирование
// Автоматически настроен
logChannel := alerts.NewLogChannel(log)
alertingService.AddChannel(logChannel)
2. Консоль
consoleChannel := alerts.NewConsoleChannel("[{{.Time}}] {{.Level}} - {{.Name}}: {{.Message}}")
alertingService.AddChannel(consoleChannel)
3. Файл
fileChannel, err := alerts.NewFileChannel("logs/alerts.log")
if err == nil {
alertingService.AddChannel(fileChannel)
}
4. Webhook
export ALERT_WEBHOOK_URL="https://api.example.com/alerts"
// Автоматически добавляется при наличии переменной окружения
webhookChannel := alerts.NewWebhookChannel(webhookURL, 10*time.Second)
5. Slack
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export SLACK_CHANNEL="#alerts"
// Автоматически добавляется при наличии переменных окружения
slackChannel := alerts.NewSlackChannel(webhookURL, channel, "Quotes Worker", 10*time.Second)
Готовые правила алертов
Системные правила
- high_memory_usage - высокое потребление памяти (>80%)
- high_goroutines - много горутин (>1000)
Circuit Breaker правила
- circuit_breaker_open_name - Circuit Breaker открыт
- circuit_breaker_high_errors_name - много ошибок (>10)
Data Manager правила
- data_manager_stale_data - данные устарели (>1 час)
- data_manager_high_memory - много памяти (>1GB)
- data_manager_low_data - мало данных (<1000 записей)
База данных
- database_unavailable - БД недоступна
Создание пользовательских правил
1. Простое правило
rule := &alerts.AlertRule{
Name: "custom_rule",
Description: "Описание правила",
Level: alerts.AlertLevelWarning,
Condition: func() (bool, error) {
// Логика проверки
return someCondition, nil
},
Duration: 5 * time.Minute,
Labels: map[string]string{
"component": "custom",
"type": "monitoring",
},
}
alertingService.AddRule(rule)
2. Правило с пороговым значением
rule := ruleFactory.CreateThresholdRule(
"high_error_rate",
"Высокий процент ошибок",
alerts.AlertLevelError,
func() (float64, error) {
return getErrorRate(), nil
},
5.0, // 5%
">",
2*time.Minute,
)
3. Правило с метриками
rule := ruleFactory.CreateCustomRule(
"slow_response_time",
"Медленное время ответа",
alerts.AlertLevelWarning,
func() (bool, error) {
avgResponseTime := getAverageResponseTime()
return avgResponseTime > 1000*time.Millisecond, nil
},
1*time.Minute,
map[string]string{
"component": "api",
"type": "performance",
},
)
Метрики алертов
Prometheus метрики
alerts_total{level,status}- общее количество алертовalerts_active{level}- активные алертыalert_duration_seconds{level}- длительность алертовalert_rule_evaluations_total{rule_name,result}- оценки правилalert_rule_errors_total{rule_name}- ошибки правил
Пример запроса Grafana
# Количество активных алертов по уровням
alerts_active
# Длительность алертов
histogram_quantile(0.95, alert_duration_seconds_bucket)
# Частота срабатывания правил
rate(alert_rule_evaluations_total[5m])
API для алертов
Получение активных алертов
activeAlerts := alertingService.GetActiveAlerts()
for _, alert := range activeAlerts {
fmt.Printf("Активный алерт: %s - %s\n", alert.Name, alert.Message)
}
Статистика
stats := alertingService.GetStats()
fmt.Printf("Правил: %d, Каналов: %d, Активных алертов: %d\n",
stats["rules_count"], stats["channels_count"], stats["active_alerts"])
Конфигурация через переменные окружения
Каналы уведомлений
# Webhook
export ALERT_WEBHOOK_URL="https://api.example.com/alerts"
# Slack
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export SLACK_CHANNEL="#alerts"
# Email (заглушка)
export ALERT_EMAIL_TO="admin@example.com"
export ALERT_EMAIL_FROM="alerts@example.com"
export ALERT_SMTP_URL="smtp://localhost:587"
Настройки алертов
# Интервал проверки правил (по умолчанию 30с)
export ALERT_CHECK_INTERVAL="30s"
# Уровень логирования алертов
export ALERT_LOG_LEVEL="info"
Мониторинг и отладка
Логи алертов
🚀 Система алертов запущена
✅ Каналы уведомлений настроены
✅ Правила алертов настроены
🚨 Алерт сработал rule=high_memory_usage level=warning alert_id=high_memory_usage_1234567890
✅ Алерт разрешен rule=high_memory_usage alert_id=high_memory_usage_1234567890 duration=5m30s
Проверка состояния
# Проверка активных алертов
curl http://localhost:8080/metrics | grep alerts_active
# Статистика системы алертов
curl http://localhost:8080/health | jq '.alerting_service'
Интеграция с существующими компонентами
ServiceContainer
// Автоматическая инициализация
configManager, err := config.NewConfigManager("configs/config.yaml", log)
alertingService := alerts.NewAlertingService(log, 30*time.Second)
// Настройка в HotStart
serviceContainer.setupAlertChannels()
serviceContainer.setupAlertRules()
alertingService.Start()
Graceful shutdown
// Автоматическое завершение
defer serviceContainer.Close()
// Останавливает ConfigManager и AlertingService
Примеры использования
1. Мониторинг производительности
// Правило на медленные запросы
rule := ruleFactory.CreateThresholdRule(
"slow_queries",
"Медленные запросы к БД",
alerts.AlertLevelWarning,
func() (float64, error) {
return getAverageQueryTime().Milliseconds(), nil
},
1000.0, // 1 секунда
">",
1*time.Minute,
)
2. Мониторинг доступности
// Правило на недоступность внешних сервисов
rule := ruleFactory.CreateCustomRule(
"external_service_down",
"Внешний сервис недоступен",
alerts.AlertLevelCritical,
func() (bool, error) {
return !isExternalServiceAvailable(), nil
},
30*time.Second,
map[string]string{
"component": "external_api",
"type": "connectivity",
},
)
3. Мониторинг бизнес-метрик
// Правило на низкую производительность торговли
rule := ruleFactory.CreateThresholdRule(
"low_trading_performance",
"Низкая производительность торговли",
alerts.AlertLevelWarning,
func() (float64, error) {
return getTradingSuccessRate(), nil
},
0.8, // 80%
"<",
5*time.Minute,
)
Troubleshooting
Проблемы с hot reload
- Файл не отслеживается: Проверьте путь к файлу конфигурации
- Ошибки валидации: Проверьте синтаксис YAML и обязательные поля
- Подписчики не уведомляются: Проверьте логи на ошибки в callback
Проблемы с алертами
- Алерты не срабатывают: Проверьте логику условий в правилах
- Уведомления не отправляются: Проверьте настройки каналов
- Много ложных срабатываний: Настройте Duration для правил
Заключение
Система hot reload и алертов обеспечивает:
- Гибкость - изменение конфигурации без перезапуска
- Надежность - мониторинг состояния системы
- Производительность - быстрая реакция на проблемы
- Масштабируемость - легко добавлять новые правила и каналы
Все компоненты интегрированы в существующую архитектуру и работают автоматически.