Finagle中服务,过滤器和编解码器之间的边界

时间:2012-07-19 17:09:02

标签: scala netty finagle

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

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

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

2 个答案:

答案 0 :(得分:18)

Finagle和Netty的结构完全不同。

服务,过滤器和编解码器实际上是非常正交的概念。让我试试吧说明。作为用户 - 即。不是编解码器的实现者 - 您只需要了解服务和过滤器。

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

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

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

您可以找到有关服务的更多详情。 Scala School中的过滤器。

*

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

Netty管道还将协议实现与应用程序处理程序混为一谈。 Finagle干净利落地将两者区分开来,因此模块化得到了增强。

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

*

粗略地总结一下,你可以说Netty是“面向流的”,而finagle则是“面向服务”。这是一个重要的区别,它允许我们以模块化方式实现强大的RPC服务。例如,连接池和负载平衡 - 对RPC客户端至关重要 - 从服务模型中自然消失,但不适合流模型。

答案 1 :(得分:0)

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

至于决策逻辑,放置它的位置取决于必须做出的决定。业务决策应该与您的业务逻辑一致,而路由,负载平衡,某些类型的访问控制等一些决策可以很好地适合作为过滤器。

服务通常位于该行的末尾,Finagle及其过滤器将帮助您实现目标。

不知道这是否有意义?

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

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

我不知道你想要建造什么,但也看看可能的替代方案:Spray,Blueeyes,Unfiltered,Play-Mini等。它可以帮助你更好地理解究竟是什么。< / p>