我有多个应用程序进程,每个进程都连接到服务器并从中接收数据。通常,连接的服务器和要检索的数据在进程之间重叠。因此,整个网络上存在大量不必要的数据重复,连接数量超过了必要的数量(这增加了服务器的负担),并且数据最终被冗余地存储在应用程序的内存中。

一种解决方案是将多个应用程序流程组合为一个流程-但在大多数情况下,它们在逻辑上确实是截然不同的,并且可能需要花费多年的时间。

不幸的是,延迟至关重要,并且数据量巨大(任何一个数据可能都不会太大,但是一旦客户端发出请求,服务器就会随着数据的变化而发送快速的更新流,这可能超过20MB/s,并且所有这些都必须以尽可能短的延迟提供给发出请求的应用程序。

想到的解决方案是对本地守护进程进行编码,应用程序将从中请求数据。守护程序将检查与适当服务器的连接是否已经存在,如果没有建立连接。然后它将检索数据并使用共享内存(由于担心延迟,否则我将使用套接字)将数据提供给发出请求的应用程序。

短期内只能解决冗余连接的一个更简单的想法是使用unix域套接字(它将在unix操作系统上运行,尽管我更愿意在可能的情况下坚持跨平台的库)以在所有进程,因此它们共享一个连接。这样做的问题是占用了缓冲区-我希望所有进程都能看到套接字上的所有内容,如果我正确理解这种方法,那么在套接字上读入一个进程将阻止其他进程在其上看到相同的数据下次读取(共享描述符中的偏移量会增加)。

最佳答案

我相信最好的选择是通过共享内存公开数据的专用服务。第二个服务是通过命名管道多播数据的服务,除了您的目标是Unix变体而不是Windows。

另一个选择是UDP多播,以便数据复制在硬件或驱动程序级别进行。唯一的问题是,不能保证UDP数据的传递是有序的,也不能保证完全传递。

我认为共享物理套接字是一种hack,应该避免,您最好实现一个驱动程序,该驱动程序可以透明地执行您希望守护程序执行的操作(例如,进程将套接字视为普通套接字,但内部将套接字映射到单个套接字,其中存在用于在虚拟套接字之间重新广播数据的逻辑。)不幸的是,要使其正确使用需要付出很大的努力,并且如果需要时间来完成,则共享套接字并不是一个真正的好方法。采取(无论是在驱动程序级别完成,还是通过其他一些卑鄙的手段(例如共享套接字描述符跨进程)完成)。

共享套接字还假定它是仅推送连接,例如。在应用程序级别无需进行流量协商(例如,对数据的请求或对数据接收的确认)。

完成任务的捷径可能是看诸如BNC之类的项目并转换代码,或者劫持一般的想法,以完成所需的工作。将流量复制到本地套接字不会引起巨大的延迟,尽管您将对所有数据复制使用NIC(和关联的缓冲区),并且如果您接近硬件的限制(或者驱动程序和/或驱动器性能不佳) TCP堆栈的实现),那么您可能会死掉一台服务器。在我工作的地方,我们已经看到数据复制在驱动程序级别上存储了一个千兆位以太卡,因此这并不是闻所未闻的。

如果您想保持平台独立性和高性能,同时又不引入任何可能由于内核或硬件/驱动程序更改而在5年后变得不支持的功能,那么共享内存是最好的选择。

10-04 14:44
查看更多