【问题标题】:Boundaries between Services, Filters, and Codecs in FinagleFinagle 中服务、过滤器和编解码器之间的边界
【发布时间】:2012-07-18 22:28:48
【问题描述】:

在 Finagle 中使用的 Netty 使用“处理程序”管道来顺序处理输入和输出数据。 Netty 示例和包含的库显示了用于身份验证、协议编解码器和服务的实际业务逻辑等各种处理程序。

Finagle 似乎采用了处理程序的概念,而是直接为 API 用户提供编解码器、过滤器和服务。虽然这些具有不同的签名,但 Finagle 的新用户需要决定使用哪个来实现其整个服务器的每个部分。他们现在需要决定哪个部分应该是编解码器的一部分,而不是任何过滤器,还是链末端的单一服务,而不是仅仅决定在哪里将链分解为各种 Netty 处理程序。总而言之,虽然 Finagle 是一个比 Netty 更高级别的库,并且应该使构建服务的任务更容易,但 API 用户可能有更多的选择。

将处理流的特定部分放入编解码器、过滤器还是单一服务的关键决策点和优缺点是什么?如果管道有可能进一步扩展,是否应该将服务逻辑放入过滤器中,在管道末端使用“noop”服务?鉴于排序过滤器(作为管道中的处理程序)的灵活性,而不是一端的单一编解码器和另一端的服务,为什么“一切”不应该是一个过滤器?

【问题讨论】:

    标签: scala netty finagle


    【解决方案1】:

    Finagle 和 Netty 的结构完全不同。

    服务、过滤器和编解码器实际上是非常正交的概念。让我试着解释一下。作为用户——即。不是编解码器的实现者——您应该只需要了解服务和过滤器。

    首先,编解码器负责将字节流转换为离散的请求或响应。例如,HTTP 编解码器读取字节流,并生成 HttpRequestHttpResponse 对象。

    Service 是一个对象,给定一个请求,它会产生一个Future 的回复——它是一个简单的函数(实际上它扩展了Function)。服务的有趣之处在于它们是对称的。客户端使用服务,服务器提供服务。服务的重要之处在于(1)它们对离散的请求和响应进行操作,以及(2)它们将请求与响应相匹配——所有这些都隐含在其类型中。这就是我们将 finagle 称为“RPC”系统的原因——请求/响应对是 RPC 的定义特征。

    所以,我们有服务,但修改服务行为独立于服务本身是有用且重要的。例如,我们可能想要提供超时功能或重试。这就是Filters 所做的。它们提供了一种修改服务行为的服务独立方法。这增强了模块化和重用性。例如,finagle 中的超时被实现为过滤器,并且可以应用于任何服务。

    您可以在Scala School 中找到有关服务和过滤器的更多详细信息。

    *

    因此,让我们将其与 Netty 的处理程序进行对比。这些是通用事件处理程序,也是可堆叠的。您可以用它们做许多类似的事情,但底层模型是附加到连接的事件的。这使得编写通用模块(例如,实现重试、超时、故障累积、跟踪、异常报告等)变得更加困难,因为您无法对正在使用的管道做出很多假设。

    Netty 管道还将协议实现与应用程序处理程序混为一谈。 Finagle 将两者完全分开,模块化也因此得到增强。

    Netty 是一组很棒的抽象,但是对于 RPC 服务器,finagle 提供了更高的模块化和可组合性。

    *

    粗略地总结一下,你可以说 Netty 是“面向流的”,而 finagle 是“面向服务的”。这是一个重要的区别,它使我们能够以模块化的方式实现健壮的 RPC 服务。例如,连接池和负载平衡(对 RPC 客户端至关重要)自然会脱离服务模型,但不适合流模型。

    【讨论】:

    • 哦,我想更简洁地回答最后一段中的问题:服务公开应用程序行为,过滤器用于以通用和模块化的方式修改其行为。因此,例如,您可能有一个服务于 HTTP 端点的服务,但有一个过滤器将异常转换为漂亮的 HTTP 500 消息。
    • 感谢 Marius,您清楚地阐明了使用 Finagle 而不是一堆 Netty 处理程序可以获得什么。
    【解决方案2】:

    我认为这不应该是编解码器或过滤器之间的决定。编解码器宁愿被包裹在过滤器中。

    至于决策逻辑,将其放置在何处取决于必须做出的决策。业务决策应符合您的业务逻辑,而路由、负载平衡、某些类型的访问控制等某些决策可以很好地适应过滤器。

    服务通常排在最后,带有过滤器的 Finagle 将带您到达那里。

    不知道这是否有意义?

    暂时离开技术细节,看看逻辑。什么应该负责什么,然后让技术适合你的设计。不要过度弯曲您的设计以适应技术。

    顺便说一句,我在 Finagle 上实现了一个网关服务器,我必须说:这是一个很好的库。

    我不知道您要构建什么,但也可以看看可能的替代品:Spray、Blueeyes、Unfiltered、Play-Mini 等。它可能会帮助您更好地了解什么是去哪里。

    【讨论】:

    • 如果您查看 Finagle 的 ServerBuilder 类的源代码,您会发现离散步骤确实是通过向管道添加更多处理程序来实现的。该顺序围绕各种选项(例如统计接收器选项)固定。我的问题的要点是,Finagle 用户可能更容易理解,并提供更大的灵活性,只需坚持一个过滤器的概念(即:Netty 处理程序),并提供更多关于如何订购它们的示例得到你想要的结果。编解码器、stats 选项、ssl 等都是处理程序。
    • 处理程序的标准设置/顺序可以很容易地在库中提供,用户可以使用“andThen”链构建自己的。这种方法可以通过减少特殊概念的数量来减少学习 Finagle 所涉及的认知负荷。此外,谁能说有人不想编码某些东西,然后将结果发送到不同的编解码器以进行进一步包装?线路另一端的 Finagle 服务也是如此。当您希望其他服务直接在之后发生时会发生什么?
    • 酷,如果我误解了,我深表歉意。我正要建议你在 Finaglers 论坛上发布这个,但有人这样做了。 groups.google.com/forum/?fromgroups#!topic/finaglers/…
    猜你喜欢
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    相关资源
    最近更新 更多