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

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

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

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


person scaling_out    schedule 19.07.2012    source источник


Ответы (2)


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

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

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

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

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

Подробнее о сервисах и фильтрах можно узнать в школе Scala.

*

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

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

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

*

Подводя грубый итог, можно сказать, что Netty «ориентирована на поток», а finagle — «ориентирована на сервис». Это важное отличие, которое позволяет нам реализовывать надежные сервисы RPC по модульному принципу. Например, пул соединений и балансировка нагрузки — крайне важные для RPC-клиентов — естественным образом выпадают из сервисной модели, но не вписываются в потоковую модель.

person marius a. eriksen    schedule 21.07.2012
comment
О, и я думаю, чтобы более кратко ответить на вопрос в вашем последнем абзаце: служба раскрывает поведение приложения, а фильтры используются для изменения их поведения общим и модульным образом. Так, например, у вас может быть служба, которая обслуживает конечную точку HTTP, но фильтр, который преобразует исключения в хорошие сообщения HTTP 500. - person marius a. eriksen; 21.07.2012
comment
Спасибо, Мариус, за четкое разъяснение того, что можно получить, используя Finagle вместо стека обработчиков Netty. - person scaling_out; 22.07.2012

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

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

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

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

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

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

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

person Jack    schedule 19.07.2012
comment
Если вы посмотрите на исходный код класса Finagle ServerBuilder, вы увидите, что отдельные шаги действительно реализованы путем добавления дополнительных обработчиков в конвейер. Порядок фиксирован вокруг различных опций (таких как опция получения статистики). Суть моего вопроса заключается в том, что пользователям Finagle может быть проще понять, а также обеспечить большую гибкость, просто придерживаясь единой концепции фильтра (например, обработчик Netty) и предоставляя больше примеров того, как их упорядочить. чтобы получить желаемые результаты. Кодек, параметр статистики, ssl и другие — все это обработчики. - person scaling_out; 19.07.2012
comment
Стандартные настройки/порядки обработчиков могут быть легко предложены в библиотеке, а пользователи могут создавать свои собственные с помощью цепочек andThen. Этот подход может снизить когнитивную нагрузку, связанную с изучением Finagle, за счет уменьшения количества специальных понятий. Кроме того, кто может сказать, что кто-то не захочет что-то закодировать, а затем отправить результаты в другой кодек для дальнейшей упаковки? То же самое касается службы Finagle на другом конце линии. Что происходит, когда вы хотите, чтобы другая услуга следовала сразу за ней? - person scaling_out; 19.07.2012
comment
Круто, извиняюсь, если неправильно понял. Я собирался предложить вам опубликовать это на форуме Finaglers, но кто-то только что это сделал. groups.google.com/forum/?fromgroups#!topic/finaglers/ - person Jack; 19.07.2012