Границы между службами, фильтрами и кодеками в Финагле

Netty, который используется в Finagle, использует конвейер "обработчиков" для последовательной обработки входящих и исходящих данных. Примеры Netty и включенные библиотеки показывают различные обработчики, используемые для таких вещей, как аутентификация, протокольные кодеки и фактическая бизнес-логика службы.

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

Каковы ключевые точки принятия решений и плюсы/минусы для размещения определенной части потока обработки в кодеке против фильтра против сингулярного сервиса? Если есть вероятность того, что трубопровод может быть расширен дальше, если вместо этого логика обслуживания будет помещена в фильтр, с услугой "noop" в конце трубопровода? Учитывая гибкость в упорядочении фильтров (в качестве обработчиков в конвейере), по сравнению с единственным кодеком на одном конце и службой на другом конце, почему бы не "все" быть фильтром?

Ответ 1

Finagle и Netty структурированы совершенно по-другому.

Службы, фильтры и кодеки на самом деле являются довольно ортогональными. Позвольте мне попытаться объяснить. Как пользователь - т.е. а не разработчиком кодека - вам нужно только знать о сервисах и фильтрах.

Во-первых, кодек отвечает за превращение потока байтов в дискретные запросы или ответы. Например, HTTP-кодек считывает байтовый поток и создает объекты HttpRequest или HttpResponse.

A Service - это объект, который при задании создает a Future ответа - его простую функцию (и, действительно, она распространяется Function). Интересная вещь об услугах заключается в том, что они симметричны. Клиент использует услугу, сервер обеспечивает ее. Важная информация об услугах заключается в том, что (1) они работают по дискретным запросам и ответам и (2) соответствуют запросам ответов - все это подразумевается по типу. Вот почему мы называем finagle системой "RPC" - пары запроса/ответа являются определяющей характеристикой RPC.

Итак, у нас есть Сервисы, но полезно и важно изменить поведение службы независимо от самой службы. Например, нам может потребоваться предоставить тайм-аут или повторить попытку. Это то, что делают Filter. Они предоставляют независимый от службы метод изменения поведения службы. Это улучшенная модульность и повторное использование. Например, таймауты в finagle реализованы как фильтр и могут применяться к любой службе.

Более подробную информацию об услугах и фильтрах можно найти в Scala школе.

*

Итак, давайте сравним это с обработчиками Nettys. Это обычные обработчики событий, которые также могут быть стекируемыми. Вы можете делать с ними много похожих вещей, но базовая модель - это поток событий, которые привязаны к соединению. Это затрудняет создание общих модулей (например, для выполнения попыток, тайм-аутов, начислений сбоев, отслеживания, отчетов об исключениях и т.д.), Потому что вы не можете сделать много предположений о конвейере, с которым вы работаете.

Протоколы Netty также объединяют реализацию протокола с обработчиками приложений. Финагл четко разделяет два, а модульность усиливается из-за этого.

Netty - замечательный набор абстракций, но для RPC-серверов finagle предлагает большую модульность и композитность.

*

Резюмируя, вы можете сказать, что Netty "ориентирован на поток", а finagle - "ориентирован на обслуживание". Это важное различие, и это позволяет нам внедрять надежные службы RPC модульным способом. Например, объединение пулов и балансировка нагрузки, что крайне важно для клиентов RPC, естественно выпадают из модели обслуживания, но не вписываются в модель потока.

Ответ 2

Я не думаю, что это должно быть решение между кодеком или фильтром. Кодеки скорее будут обернуты фильтрами.

Что касается логики принятия решения, где разместить его, будет зависеть от решений, которые должны быть приняты. Бизнес-решения должны идти с вашей бизнес-логикой, в то время как некоторые решения, такие как маршрутизация, балансировка нагрузки, определенные типы контроля доступа и т.д., Могут также вписываться в фильтр.

Службы, как правило, сидят в конце строки, и Finagle с его фильтрами доставит вас туда.

Не знаю, имеет ли это смысл?

Просто отшатнитесь от технической детали на мгновение и посмотрите на логику. Что должно быть ответственным за то, а затем получить технологию в соответствии с вашим дизайном. Не сгибайте свой дизайн слишком сильно, чтобы соответствовать этой технологии.

Кстати, я реализовал сервер шлюза поверх Finagle, и я должен сказать: это хорошая библиотека для работы.

Я не знаю, что вы пытаетесь построить, но посмотрите на возможные альтернативы: Spray, Blueeyes, Unfiltered, Play-Mini и т.д. Это может помочь вам лучше понять, что происходит.