在Perl中,对于中等大小的数据,最好的IPC机制是什么?

7
我正在设计一个Perl多层应用程序,想了解可用的各种IPC机制的优缺点。 我希望处理中等大小的数据,通常为几十千字节,但最多可达几兆字节,负载非常轻,最多每分钟几百个请求。
我的主要关注点是可维护性和性能(按顺序)。 我不认为我需要扩展到超过一个服务器,或者从我们的主平台(RHEL)进行端口转移,但我认为这是需要考虑的事情。
我可以想到以下选项:
- 临时文件 - 简单,可能是速度和存储需求方面最差的选择 - UNIX域套接字 - 不可移植,不可扩展 - Internet套接字 - 可移植,可扩展 - 管道 - 可移植,不可扩展(?)
考虑到可扩展性和可移植性不是我的主要关注点,我需要学习更多。哪个是最佳选择,为什么?如果您需要其他信息,请评论。

编辑: 我会尝试在ysth的问题的回复中提供更多详细信息(警告,下面是一堵文字墙)

  • 读者/作者是否处于一对一关系,还是更加复杂?
  • 如果读者不在或忙碌,您希望发生什么情况?
  • 反之亦然?
  • 您有关所需用途的其他信息是什么?

此时,我正在考虑三层方法,但我不确定每个层次中将有多少个进程。我认为我需要在左侧拥有更多的进程,而在右侧则需要较少的进程,但也许我应该在各方面都有相同数量:

 .---------.          .----------.        .-------.
 | 请求管理器 |  ----->  | 业务逻辑 | -----> | 数据层 |
 `---------'          `----------'        `-------'
这些名称仍然是通用的,可能不会以这些形式实现。 请求管理器负责监听来自不同接口的请求,例如 Web 请求和 CLI(响应时间很重要)以及电子邮件(响应时间不那么重要)。它执行日志记录并管理对请求的响应(以适合请求类型的格式呈现)。
它将有关请求的数据发送到业务逻辑,后者根据业务规则执行日志记录、授权等操作。
如果需要,业务逻辑随后从数据层请求数据,该数据层可以与内部 MySQL 数据库或我们团队无法控制的某些其他数据源(例如我们组织的主要 LDAP 服务器或我们的 DB2 员工信息数据库等)进行通信。这主要是一个包装器,以统一的方式格式化数据,以便在业务逻辑中更容易处理。
然后信息流回请求管理器进行呈现。
如果数据向右流动时,读者正在忙碌,对于交互请求,我希望只需等待适当的时间,如果在这段时间内无法获得访问权限,则返回超时错误(例如,“稍后再试”)。对于非交互式请求(例如电子邮件),轮询系统可以简单地退出,并在下一次调用时再次尝试(这可能是每1-3分钟一次)。
当数据向另一个方向流动时,不应该有任何等待情况。如果其中一个进程在尝试向左移动时死亡,我实际上只能记录并退出。
总之,那很啰嗦,而且由于我仍处于早期设计阶段,我可能仍然有一些混乱的想法。我提到的一些内容可能与使用IPC系统的问题不相关。我对设计的其他建议持开放态度,但我试图将问题限制在范围内(例如,也许我应该考虑折叠到两个层级,这对于IPC来说更简单)。你有什么想法?
6个回答

6
如果您目前不确定确切的需求,请尝试考虑一个简单的界面,您可以编写任何IPC实现(无论是临时文件、TCP/IP还是其他)所需的界面。然后,您可以选择特定的IPC方式(我会从最容易和/或最容易调试的方式开始——可能是临时文件),并使用该方式实现接口。如果发现速度太慢,请使用例如TCP/IP实现接口。实际上,实现接口并不需要太多工作,因为您基本上只需要将调用转发到某个现有库。
重点在于,您有一个高级任务要执行(“从程序A传输数据到程序B”),这与如何执行此任务的细节或多或少无关。通过建立接口并编码,您隔离了主程序与实现更改之间的关系,以防需要更改实现。
请注意,您不需要使用任何重量级Perl语言机制来利用具有接口的想法。您可以简单地拥有例如3个不同的包(用于临时文件、TCP/IP、Unix域套接字),每个包都导出相同的方法集。在主程序中选择要使用哪个实现相当于选择要使用哪个模块。

4

临时文件除了这个问题之外还有其他问题。我认为Internet套接字确实是最好的选择。它们有很好的文档支持,正如你所说的,可扩展和可移植。即使这不是核心要求,你也几乎可以免费获得它。套接字的处理相当容易,而且有大量的文档。你可以在库中构建出你的数据共享机制和协议,以后就不用再去看它了!


4

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

但是,我的真正建议是不要自己编写此类代码。在服务器端,您应该使用POE(或Coro等),而不是自己对套接字进行选择操作。此外,如果您的接口将是RPC风格,请使用来自CPAN的类似JSON-RPC-Common/ 的东西。

最后,可能适合您的是IPC::PubSub。


非常感谢!我希望能够获得一些有用的Perl资源。 - Adam Bellaire

3

UNIX域套接字在不同的Unix系统之间可移植。它的可移植性不亚于管道,而且比IP套接字更高效。

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

消息队列也是一种可能性,尽管您必须更改内核选项才能处理这样大的消息。否则,它们具有许多理想的接口,而且在我看来它们被大大低估了。

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


谢谢!你说得对,共享内存和消息队列甚至没有出现在我的脑海中。 - Adam Bellaire

2
对于“交互式”请求(在等待响应时保持连接打开(异步或非异步)):HTTP + JSON。JSON :: XS速度非常快。每个人和事物都可以使用HTTP,并且很容易进行负载平衡、调试等操作。
对于排队请求(“请执行此操作,谢谢!”):BeanstalkdBeanstalk::Client。使用JSON将请求序列化到beanstalk队列中。
根据您的应用程序,Thrift也可能值得一看。

2

有很多不同的选择,因为它们大多数针对某些特定情况更好,但你并没有提供任何可以确定你情况的信息。

读写器是否处于一对一的关系,或者更加复杂? 如果读取器不存在或忙碌,您希望发生什么?反之亦然? 您对所需用途还有哪些其他信息?


谢谢您的回复,我已经为问题添加了更多细节。 - Adam Bellaire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接