Приложение на Rails. После ввода пользователем реквизитов необходимо открыть SSH соединение (использую Net::Ssh), и очень бы не хотелось, чтобы при каждом запросе к приложению SSH соединение открывалось заново. Подскажите, как можно сохранять подключение через Net::Ssh и использовать его при каждом запросе к сайту.
Ответ
Соединение штука несериализуемая и между процессами передаваемая с трудом даже в пределах одной машины, что уж говорить о множестве машин — ведь воркеры вовсе не обязаны все быть на одной машине.
Совсем простое решение: всё равно осуществлять SSH-соединения в процессе веб-сервера.
Надо с осторожностью отнестись к тому, как там устроены ввод-вывод и многопоточность, чтобы код обработки HTTP-запросов и SSH-соединений не мешал друг другу. А проблему установления нескольких соединений от разных серсеров можно решить "липкими сессиями" на балансировщике, с помощью которых пользователь будет закреплён за конкретным процессом. Есть реализация в nginx, опция sticky. При этом nginx сам должен знать о каждом воркере, чтобы иметь возможность "прилеплять" пользователей, это не со всякой конфигурацией вебсервера совместимо: в конфиге nginx воркеры должны быть перечислены явно.
Но это довольно грустное решение в том плане, что взаимодействие по HTTP практически не требует поддержки какого-либо состояния, что удобно, т. к. даёт возможность держать много идентичных процессов и обслуживать любые запросы любым из них, не боясь аномалий.
К тому же, в зависимости от того, насколько у вас разнятся нагрузки от отдельных пользователей, nginx может распределить нагрузку между воркерами не вполне равномерно.
И обратите внимание на то, что у вас будет происходить, если от пользователя придут два запроса на SSH-соединение практически одновременно, когда у вас оно ещё не установлено. Примите меры, чтобы не установить два соединения.
Менее грустным решением была бы отдельная служба, которая держит SSH-соединения и общается с вебсервером по какому-нибудь внутреннему протоколу.
Хотя как только начнутся проблемы с удержанием большого количества SSH-соединений на одном сервере (это вопрос уже к вам, какого роста нагрузок вы ждёте), вам придётся делать похожую систему: с помощью подобия "липких сессий" (важно: принадлежащих пользователям, а не воркерам вебсерверов) распределять соединения по нескольким процессам/хостам с этой выделенной службой. Только вместо того, чтобы возиться с куками, отвечающий за соединение сервер можно зашить прямо в идентификатор соединения, используемый в общении между серверами.
Сложно, да? Что поделать. Вы пытаетесь связать очень разнородные вещи.
Комментариев нет:
Отправить комментарий