Как перезагрузить сервис на Go так, чтобы сохранить текущие WS соединения?
У меня есть сервис на Go, который держит большое количество клиентов по Websocket, слушащих данные. Типа, круглосуточно, и нежелательно чтобы соединение оборвалось. Допустим, мне надо сделать апдейт сервиса. Можно ли перезагрузить его так, чтобы клиентам не пришлось переподключаться?
Собственно, варианта пока что вижу два:
а) заложить такой функционал на стороне клиента (который я тоже пишу, но не хотелось бы так делать): сервис шлёт сообщение о своей перезагрузке, а клиент пытается переподключиться через время.
б) разбить сервер на две части, одна - только логика, другая - только обслуживание соединений, взаимодействие через MongoDB Capped Collection (что собственно подошло бы: данные со временем протухают, но вопрос в её производительности: отправлять данные надо как можно скорее).
Возможно, есть какое-то более элегантное / нативное решение?
Заранее спасибо.
Спасибо.
есть такая штука как https://golang.org/pkg/plugin/
не знаю подойдет ли, но если подойдет - то разделить приложение на 2 части - одна - веб-сервер, вторая - вся логика, которая подключается как плагин. Вот его, насколько я понял, можно менять по-горячему
Если не подойдет, и вопрос сохранения соединений критичен, то все-равно разделить на две части, но они между собой должны общаться по какому-то IPC каналу (tcp/unix/whaterver). Это позволит вторую часть перезагружать не трогая первую.
IlliaKharytonov: вы их можете сохранить где угодно.
в файле, во вспомогательном сервисе.
вы можете их прочитать из файла, передать в качестве параметров командной строки.
как угодно.
В чём проблема сделать на клиенте переподключение при обрыве? В любом случае это надо делать на случай проблем подключения к интернету у клиента.
Если совсем-совсем нельзя даунтайм иметь, можете сначала запустить новый сервис, перевести у клиентов все подключения на него и только потом гасить старый. Правда, ИМХО, это сильно более запарно чем автореконнект на клиенте.
На случай это конечно будет. Но в идеале хотелось бы, чтобы о перезагрузке клиент даже не узнал. Т.е. единственный симптом для него - это задержка по данным на пару секунд.
Ещё один вариант вам придумал, делаете очень тонкий сервис-прослойку, который держит соединения с клиентами и перенаправляет их на бэкэнд. Чтобы при рестарте бекенда рвалось только соединение прослойка-бэкенд, а прослойка-клиент оставалось установленным.
stoitli: Может я ошибаюсь, но Graceful Restart катит только если соединения регулярно устанавливаются и рвутся. При переключении сокета, новые соединения пойдут на новый инстанс сервиса, а старые дообработаются старым инстансом и закроются.
Здесь же соединения в установленном состоянии могут висеть днями, вы устанете ждать их завершения, чтобы закрыть старый инстанс.
IlliaKharytonov: в прослойку входит вебсокет и выходит вебсокет, всё просто. Задача прослойки не закрывать вебсокет на клиента, пока бэкенд переподключается.