7

我正在用 Perl 设计一个多层应用程序,我想知道我可以使用的各种 IPC 机制的优缺点。我正在研究处理中等大小的数据,通常为几十 KB,但最多为几兆字节,并且负载非常轻,每分钟最多几百个请求。

我主要关心的是可维护性和性能(按此顺序)。我认为我不需要扩展到一台以上的服务器,或者从我们的主平台 (RHEL) 移植,但我认为这是需要考虑的事情。

我可以想到以下选项:

  • 临时文件 - 简单,可能是速度和存储要求方面最差的选择
  • UNIX 域套接字 - 不可移植,不可扩展
  • Internet Sockets - 便携、可扩展
  • 管道 - 可移植,不可扩展(?)

考虑到可扩展性和可移植性不是我最关心的问题,我需要了解更多。什么是最好的选择,为什么?如果您需要更多信息,请发表评论。


编辑:我将尝试提供更多详细信息以回答ysth 的问题 (警告,文字墙如下)

  • 读者/作者是一对一的关系,还是更复杂的关系?
  • 如果读者不在或忙,你希望作者怎么办?
  • 反之亦然?
  • 关于您想要的用途,您还有哪些其他信息?

在这一点上,我正在考虑采用三层方法,但我不确定每一层有多少进程。我认为我需要在左侧有更多的流程,而在右侧有更少的流程,但也许我应该有相同的数字:

.---------。.---------。.--------。
 | 请求 | -----> | 商业 | -----> | 数据 |
 | 经理 | <----- | 逻辑 | <----- | 层 |
 `---------' `----------' `--------'

这些名称仍然是通用的,可能不会以这些形式进入实现。

请求管理器负责监听来自不同接口的请求,例如 Web 请求和 CLI(响应时间很重要)和电子邮件(响应时间不太重要)。它执行日志记录并管理对请求的响应(以适合请求类型的格式呈现)。

它将有关请求的数据发送到业务逻辑,业务逻辑根据业务规则执行日志记录、授权等。

然后业务逻辑(如果需要)从数据层请求数据,数据层可以(最常见)与内部 MySQL 数据库或我们团队无法控制的其他数据源(例如,我们组织的主 LDAP 服务器或我们的DB2 员工信息数据库等)。这主要是一个简单的包装器,它以统一的方式格式化数据,以便在业务逻辑中更容易地处理它。

然后信息流回请求管理器进行呈现。

如果,当数据向右流动时,读者很忙,对于交互式请求,我只想等待一段合适的时间,如果我在这段时间内没有访问权限,则返回超时错误(例如“稍后再试”)。对于非交互请求(例如电子邮件),轮询系统可以简单地退出并在下一次调用时重试(可能每 1-3 分钟一次)。

当数据在另一个方向流动时,不应该有任何等待的情况。如果在尝试返回左侧时其中一个进程已经死亡,那么我真正能做的就是登录并退出。

无论如何,这非常冗长,而且由于我仍处于早期设计阶段,因此我可能仍然有一些混乱的想法。我提到的一些内容可能与使用哪个 IPC 系统的问题无关。我对设计的其他建议持开放态度,但我试图将问题限制在范围内(例如,也许我应该考虑分解为两层,这对于 IPC 来说要简单得多)。你怎么认为?

4

6 回答 6

6

如果您目前不确定您的确切要求,请尝试考虑一个您可以编码的简单接口,任何IPC 实现(无论是临时文件、TCP/IP 还是其他)都需要支持。然后,您可以选择特定的 IPC 风格(我会从最容易和/或最容易调试的任何东西开始——可能是临时文件)并使用它来实现接口。如果结果太慢,请使用 TCP/IP 等实现接口。实际上实现接口并不涉及太多工作,因为您基本上只是将调用转发到一些现有的库。

关键是您有一个高级任务要执行(“将数据从程序 A 传输到程序 B”),它或多或少独立于其执行方式的细节。通过建立接口并对其进行编码,您可以在需要更改实现的情况下将主程序与更改隔离开来。

请注意,您不需要使用任何重量级的 Perl 语言机制来利用具有接口的想法。您可以简单地拥有例如 3 个不同的包(用于临时文件、TCP/IP、Unix 域套接字),每个包都导出相同的方法集。选择要在主程序中使用的实现相当于选择要使用的模块use

于 2009-01-11T04:40:27.057 回答
4

除此之外,临时文件还有其他问题。我觉得网袜真的是最好的选择。它们有据可查,正如您所说,可扩展且可移植。即使这不是核心要求,您也几乎可以免费获得它。套接字很容易处理,同样有大量的文档。您可以在库中构建您的数据共享机制和协议,而无需再次查看!

于 2009-01-10T20:13:57.127 回答
4

临时文件(和相关的东西,如共享内存区域)可能是一个糟糕的选择。如果你想在一台机器上运行你的服务器而在另一台机器上运行你的客户端,你将需要重写你的应用程序。如果您选择任何其他选项,至少语义基本相同,如果您需要在以后在它们之间切换。

不过,我唯一真正的建议是不要自己写这个。在服务器端,你应该使用 POE(或 Coro 等),而不是自己select在 socket 上做。此外,如果您的接口将是 RPC-ish,请使用CPAN 中的JSON-RPC-Common/之类的东西。

最后,还有 IPC::PubSub,它可能对你有用。

于 2009-01-11T01:11:14.030 回答
3

UNIX 域套接字可跨单元移植。它的便携性不亚于管道。它也比 IP 套接字更有效。

无论如何,您错过了一些选项,例如共享内存。有些人会将数据库添加到该列表中,但我会说这是一个相当重量级的解决方案。

消息队列也是一种可能,尽管您必须更改内核选项才能处理如此大的消息。否则,它们对很多事情都有理想的界面,恕我直言,它们的使用率很低。

尽管我普遍同意使用现有解决方案比构建自己的解决方案要好。我不知道您的问题的具体情况,但我建议您查看 CPAN 的IPC部分

于 2009-01-11T01:33:27.653 回答
2

有很多不同的选择,因为它们中的大多数更适合某些特定情况,但是您并没有真正提供任何可以识别您的情况的信息。

读者/作者是一对一的关系,还是更复杂的关系?如果读者不在或忙,你希望作者怎么办?反之亦然?关于您想要的用途,您还有哪些其他信息?

于 2009-01-11T09:08:39.497 回答
2

对于“交互式”请求(在等待响应(异步或非异步)时保持连接打开):HTTP + JSON。JSON ::XS非常快。每个人都可以说 HTTP,并且很容易进行负载平衡、调试、.. .

对于排队的请求(“请这样做,谢谢!”):BeanstalkdBeanstalk::Client。使用 JSON 序列化 beanstalk 队列中的请求。

根据您的应用程序,Thrift也可能值得研究。

于 2009-02-05T10:03:13.480 回答