Ответ
В Go leader election можно реализовать с помощью distributed locks или consensus алгоритмов (например, Raft). Часто используют etcd или ZooKeeper для координации.
Пример с etcd:
client, err := clientv3.New(clientv3.Config{
Endpoints: []string{"localhost:2379"},
DialTimeout: 5 * time.Second,
})
session, err := concurrency.NewSession(client)
defer session.Close()
mutex := concurrency.NewMutex(session, "/leader-election")
err = mutex.Lock(ctx) // Блокируем до получения лидерства
// Теперь мы лидер
go func() {
<-session.Done() // Следим за потерей лидерства
log.Println("Lost leadership")
}()
Ключевые моменты:
- Ноды конкурируют за лок
- Победитель становится лидером
- При потере соединения лок освобождается
- Остальные ноды получают уведомление и могут попытаться стать лидером
Для простых случаев можно использовать memory-based решения, но они не fault-tolerant.