LINUX.ORG.RU

ООП ГМ, переходящий в АП ГМ.

 , , ,


2

5

Я тут всё голову ломаю на счёт REST и RPC, органично сочетающиеся с идеологией моего движка в рамках мультипроектных многонодовых решений.

И в голове рождается такая фигня.

Назову это для затравки Object-RPC. Или Agent-RPC. Нечто по сути промежуточнон. Классический объект, всё же, располагается на одной ноде. Агент — по сути то же самое, но передающееся по сети. А тут... Ну, вот, практический пример. Межнодовая/межхостовая аутентификация, скажем.

Задача:

Есть сервер, на котором БД юзеров.

Есть другой сервер, в отдельном проекте, котором при этом должен авторизовать пользователей через первый сервер.

Лобовое решение — на том же REST. Первый сервер предоставляет для второго API. Второй его использует. Проблема в избыточной писанине каждой такой задачи и привязка к API.

Более хитрое решение (то, что я делаю сейчас) — первый сервер обеспечивает некоторый стандартный объектный API, который позволяет в итоге через нетолстую прослойку реализовать единообразную работу как с локальными, так и с удалёнными объектами. Просто во втором случае идёт отсылка параметров на методы удалённого объекта и возврат значений по сети. Проблема в том, что придётся гонять по сети, подчас, небезопасные данные или просто слишком объёмные.

В голову приходит третий вариант. Что, если удалённый сервер предоставляет экспорт части методов локальному, так, что частично реализация методов становится локальной, частично — удалённой. Например, объект аутентификации может передать клиенту^W вторичному сервер метод необратимого шифрования, так, что пароль пользователя не уйдёт дальше второго сервера, а на первый пойдёт только хеш, на удалённый метод, который будет уже что надо делать с его локальным бэкендом (проверять доступ, возвращать ключ авторизации и т.п.)

То есть по сути объект становится распределённым, находясь частично на сервере, частично на клиенте.

Или, что близко к тому, можно рассужать в рамках парных объектов, объекта и хелпера, с передачей клиенту второго, который уже гвоздями (API) прибит к первому.

Так вот, вопрос в чём. Такое где-то практикуется? Есть устоявшаяся терминология? Чтобы не плодить в очередной раз свои контекстные велосипедные названия?

★★★★★

куча проектов на одном движке плохая идея, я бы держал копии движков пусть это и избыточно, практика показывает что в час икс проблема на вагон меньше, да и гибче в общем

trashymichael ★★★ ()
Ответ на: комментарий от trashymichael

куча проектов на одном движке плохая идея, я бы держал копии движков

Под «движком» ты подразумеваешь ноду/хост? Иначе вопрос копий непонятен :)

Собственно, речь и идёт о реализации распределённой системы.

KRoN73 ★★★★★ ()
Ответ на: комментарий от vertexua

Что значит «передать метод»?

В случае одноплатформенного решения — можно буквально исходный код метода перекинуть. Или, например, на Java или Python — сразу готовый объект (через класслоадеры первой или через pickle на втором).

В первом варианте можно и так сделать, всё равно пока в ближней перспективе только PHP.

Вот в дальней перспективе интересен вопрос взаимодействия, как минимум, с решениями на Play Framework. Так что надо думать о кроссплатформенных решениях. Мысли есть, я даже на ЛОР пару дней назад набил большую тему по ним, но стёр не отправив, решив, что пока надо ещё многое самому обдумать :)

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

фреймворк, хотя если ты его вообще не меняешь то может и прокатит

trashymichael ★★★ ()

Что-то мне кажется, что ерунду ты делаешь. Для аутентификации и предоставления API с авторизацией доступа придумали OAuth2, к которому можно обращаться из JS скриптов, серверных приложений на разных языках и кучей других способов. При этом технология хорошо продумана для надежного решения широкого круга задач.

В случае одноплатформенного решения — можно буквально исходный код метода перекинуть. Или, например, на Java или Python — сразу готовый объект (через класслоадеры первой или через pickle на втором).

А что будет, если захочешь сменить язык на одной ноде или, например, обновить версию PHP, а на другой оставить как есть. Также можешь захотеть обновить версии php на обоих нодах, но это придется делать одновременно на обоих и на время обновления выключить их (иначе на короткий период будет ситуация, что на одной ноде php уже новый, а на другой старый). Я это к тому, что таких зависимостей быть не должно. Чем меньше связанность, тем надежнее приложение. Потому в OAuth2 аутентификация сделана через редиректы, если что-то не работает (нет подключения, например), то ты получишь connection timeout и прерывание всей операции, а не сбой в сложной схеме, при том, что такой сбой нужно отследить и далее правильно вернуть ошибку с раскруткой разных стеков вызовов, возможно, на нескольких нодах. Набор маленьких, независимых операций рулит. Он надежнее, чем сложная схема, когда клиент коннектится к серверу, тот еще к трем службам, которые коннектятся друг к другу и если где-то что-то сбойнуло, то ошибку нужно правильно обработать (отследить, затем вернуть код возврата всем заинтересованным сторонам, которые тоже все должны правильно обработать).

IMHO, если нужен API без авторизации, то однозначно REST, если с авторизацией, то OAuth2. Если быстрый бинарный обмен данными, то protobuf. А необходимость велосипеда должна быть ну очень серьезно обоснована (с учетом того, что любое приложение со временем развивается, т.е. заранее все требования знать нельзя - появятся новые, то шансов у велосипеда очень мало).

x_hash ()

Или, что близко к тому, можно рассужать в рамках парных объектов, объекта и хелпера, с передачей клиенту второго, который уже гвоздями (API) прибит к первому.

Это как в жабе Model<->DAO?

GateKeeper ★★ ()
Ответ на: комментарий от KRoN73

Или, например, на Java или Python — сразу готовый объект (через класслоадеры первой или через pickle на втором).

И там, и там, ЕМНИП, требуется наличие классов/pyo для объекта, который ты кидаешь по сети. В питоне есть PyroES, собственно, почти делает то, что ты хочешь.

GateKeeper ★★ ()

Насколько я смог понять, большинство из изобретаемого тобой уже реализовано в Erlang's OTP. Только насчет всяких авторизаций там всё проще (соединенные в кластер ноды и код на них по дефолту доверяют друг другу), а если надо усложнять, то придется дописывать самому.
Может и для более сложных случаев всё уже написано, но я в той стороне решений не искал за ненадобностью.

blexey ★★★★★ ()

То есть по сути объект становится распределённым, находясь частично на сервере, частично на клиенте

Похоже на CORBA, в частности «объекты по значению»

no-such-file ★★★★★ ()

erlang, cloud haskell - используется и там и там все сделано проще, есть ноды и процессы на нодах, которым можно слать сообщения (данные или «функции») т.е. код вида:

send "auth-service" (AuthObject  .., me)
x <- receive  :: AuthorizationResult
-- or
let checkAuth x = do
       u <- validateUser x
       if (head (userName u) == "a") then (AuthorizationOK u)
                                     else (AuthorizationErr u)
send "auth-service" ($(mkClosure checkAuth) x)

В любом случае у тебя будет прибит апи, разве что возможно не «гвоздями», а «жидким клеем». Если собираешься такое часто использовать и не собираешься менять язык, то городить велосипед вполне можно.

qnikst ★★★★★ ()
Ответ на: комментарий от x_hash

Для аутентификации и предоставления API

Это только иллюстрация. В который раз вижу удивительных людей, которые в примерах почему-то ищут задачу, а не иллюстрацию метода. Вопрос ни разу не в авторизации. А в распределённой объектной системе.

KRoN73 ★★★★★ ()
Ответ на: комментарий от blexey

большинство из изобретаемого тобой уже реализовано в Erlang's OTP

Erlang — слишком маргинален для меня и, кроме того, как я писал, хочется кроссплатформенности в перспективе :)

KRoN73 ★★★★★ ()

насколько понимаю, тебе нужна поддержка единой сессии на нодах кластера? Или только авторизация? Или и того и другого, желательно без хлеба?

swwwfactory ★★ ()
Ответ на: комментарий от KRoN73

Ну, OTP вполне кросс-платформенная. Наверно такую штуку проще всего было реализовать именно на функциональном языке, раз для других до сих пор приходят в головы идеи изобретать какие-то велосипеды.

blexey ★★★★★ ()

То что ты хочешь сделать, называется шлюз или прокси.

no-dashi ★★★★★ ()
Ответ на: комментарий от blexey

маловероятно, что ставится задача сделать гибридную систему (которая автоматом будет понимать локальный запрос или нет, и уметь делать «Например, объект аутентификации может передать клиенту^W вторичному сервер метод необратимого шифрования, » без привязки к языку.

qnikst ★★★★★ ()
Ответ на: комментарий от blexey

а в haskell зато есть LIO, библиотека, которая позволяет запускать чужой код гарантируя, что он не выполнит запрещенных действий и не получит данные, к которым у него нет доступа.

qnikst ★★★★★ ()
Ответ на: комментарий от blexey

Ну, OTP вполне кросс-платформенная.

Я про _языковую_ кроссплатформенность :)

KRoN73 ★★★★★ ()

Мой опыт мне подсказывает, что нельзя делать сеть прозрачной для распределенного приложения.

Вообще мне не понятна цель твоих изобретений. Намутить распределенку и так довольно простая задача в первом приближении. Вон в спринге есть HttpInvokerServiceExporter, через него вытаскиваешь свой фасад авторизации, пишешь для этого фасада простейшую обертку, которая умеет шифровать пароли на клиенте, получаетя клиент.

dizza ★★★★★ ()
Ответ на: комментарий от dizza

Вообще мне не понятна цель твоих изобретений.

У меня много проектов, которые должны быть независимы и при этом удобно обмениваться объектами. При этом проекты могут быть как на одном хосте, так и на разных. В идеале хочется вообще независимости от хоста, чтобы можно было спокойно перемещать ноды по машинам, распределяя нагрузку.

Сейчас все связанные проекты используются в рамках одного хоста и взаимодействую напрямую в едином процессе. Но теперь возникает задача взаимодействия процессов на разных хостах.

KRoN73 ★★★★★ ()

первая задница случается с сохранением единообразного интерфейса при добавлений асинхронных вызовов

Deleted ()
Ответ на: комментарий от Deleted

первая задница случается с сохранением единообразного интерфейса при добавлений асинхронных вызовов

В чём она ожидается? Конкретный пример можно? А то асинхронность, как раз, вполне подразумевается.

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

да хотябы в том что вызов синхронного метода и асинхронного

res = object.func(args)

object.func(args, resultCallback)

отличаются, а в классических языках это плохо совместимо, кроме того асинхронные в таком виде придется вызвать из другого потока - а это очень важное условие

в итоге у тебя интерфейсы локальных объектов и удаленных уже отличаются - либо придется городить для локальных такойже интерфейс.

затем как делать вызов из другого потока в разных языках программирования? (в java - просто, а в python, php?)

Deleted ()
Ответ на: комментарий от Deleted

А, понял. Ты про асинхронность в рамках одной ноды. Мне оно не актуально, так как смысла в такой асинхронности не вижу. Всё равно в PHP каждый запрос — отдельный процесс, в Java же нет проблем с запуском отдельного треда-обработчика.

У меня вопрос стоит совсем с другой же стороны.

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

я про асинхронность в рамках API, а детали реализации - дело десятое, танненбаум это давно описал, и множество тонкостей

Deleted ()
Ответ на: комментарий от KRoN73

Ну дык вот решение - функциональность распихиваешь по сервисам, если нужно разнести по сети, сервис легко пробрасывается по http. Если нужна многоязычность, то можно заюзать thrift.

dizza ★★★★★ ()
Ответ на: комментарий от dizza

Ну дык вот решение - функциональность распихиваешь по сервисам

Это само собой. Вопрос стоит о дальнейшем — об удобной реализации доступа к удалённой функциональности :)

сервис легко пробрасывается по http

Я рассуждаю об обёртке вокруг этого проброса.

KRoN73 ★★★★★ ()

микросервисы у Мартина Фаулера

cast KRoN73

сорри за некропостинг, но недавно вот наткнулся про микросервисы: у Левенчука у Мартина Фаулера

ещё например с хабра, интересный способ интегации про агентов и шину сообщений

может, пригодится. и натолкнёт на какие-то мысли.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.