Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java TCP/IP套接字延迟-停留在50μ;秒(微秒)?(用于Java IPC)_Java_Ipc_Tcp_Interprocess_Low Latency - Fatal编程技术网

Java TCP/IP套接字延迟-停留在50μ;秒(微秒)?(用于Java IPC)

Java TCP/IP套接字延迟-停留在50μ;秒(微秒)?(用于Java IPC),java,ipc,tcp,interprocess,low-latency,Java,Ipc,Tcp,Interprocess,Low Latency,我们一直在分析和分析我们的应用程序,以尽可能减少延迟。我们的应用程序由3个独立的Java进程组成,它们都运行在同一台服务器上,通过TCP/IP套接字相互传递消息 我们已经将第一个组件中的处理时间减少到25μs,但是我们看到(在本地主机上)到下一个组件的TCP/IP套接字写入总是需要大约50μs。我们看到另一种异常行为,即接受连接的组件可以更快地写入(即如果使用本地库是一种选择,我会考虑照常执行IPC(搜索IPC、MMAP、SHMYOPEN等)。 使用JNI会带来很多开销,但至少比使用套接字或管道

我们一直在分析和分析我们的应用程序,以尽可能减少延迟。我们的应用程序由3个独立的Java进程组成,它们都运行在同一台服务器上,通过TCP/IP套接字相互传递消息

我们已经将第一个组件中的处理时间减少到25μs,但是我们看到(在本地主机上)到下一个组件的TCP/IP套接字写入总是需要大约50μs。我们看到另一种异常行为,即接受连接的组件可以更快地写入(即<50μs)。目前,除套接字通信外,所有组件的运行时间均小于100μs

作为一名TCP/IP专家,我不知道该怎么做才能加快速度。Unix域套接字会更快吗?记忆档案?还有哪些机制可以更快地将数据从一个Java进程传递到另一个Java进程

更新6/21/2011 我们创建了2个基准应用程序,java和C++中的一个,比较紧密地比较TCP/IP。java应用程序使用了NIO(阻塞模式),C++使用Boost ASIO TCP库。其结果大致相当,C++应用程序比java快4μs(但在java打败C++测试中)。而且,两个版本在每条消息的时间上都表现出很大的变化

我认为我们同意一个基本结论,即共享内存实现将是最快的。(虽然我们也愿意评估信息产品,只要它符合预算。)

< P>如果使用本地库是一种选择,我会考虑照常执行IPC(搜索IPC、MMAP、SHMYOPEN等)。 使用JNI会带来很多开销,但至少比使用套接字或管道进行任何操作所需的完整系统调用要少一点。通过JNI使用轮询共享内存IPC实现,您很可能能够获得大约3微秒的单向延迟。(请确保使用-xcompJVM选项或调整编译阈值;否则您的前10000个示例将非常糟糕。这会带来很大的不同。)

我有点惊讶,TCP套接字写入需要50微秒——大多数操作系统在某种程度上优化了TCP环回。Solaris实际上通过一种叫做。如果有任何环回通信的优化,通常是TCP。UDP往往会被忽略,所以在这种情况下,我不会为它操心。我也不会为管道(stdin/stdout或您自己命名的管道等)而烦恼,因为它们会更慢

一般来说,您看到的许多延迟可能来自于信令——要么等待IO选择器(如套接字中的select()),要么等待信号量,或者等待其他东西。如果您想要尽可能低的延迟,就必须烧掉一个处于紧循环轮询中的内核以获取新数据


当然,总有一条路——我碰巧知道,这条路肯定会很快解决你的问题——但当然它确实需要钱。为了充分披露:我为Informatica的低延迟消息软件工作。(作为一名工程师,我的真实观点是,这是一款非常棒的软件,当然值得在这个项目中使用。)

请参阅我的答案-使用内存映射文件(共享内存)java到java的延迟可以降低到0.3微秒

内存配置文件对于低延迟IPC根本不是可行的解决方案-如果映射的内存段得到更新,它最终将同步到磁盘,从而引入不可预测的延迟,至少以毫秒为单位。对于低延迟,可以尝试共享内存+消息队列(通知)或共享内存+信号量的组合。这适用于所有Unix,特别是SystemV版本(不是POSIX),但如果您在Linux上运行应用程序,那么POSIX IPC(大多数功能在2.6内核中可用)是的,您将需要JNI来完成这项工作

UPD:我忘了这是JVM-JVM IPC,我们已经有了我们无法完全控制的GCs,因此由于操作系统文件缓冲区闪存到磁盘而引入额外的几毫秒暂停可能是可以接受的

O'Reilly关于NIO的书(JavaNIO,第84页)似乎对 内存映射是否保留在内存中。可能只是说 就像其他内存一样,如果物理内存用完,就会进行交换 返回到磁盘,但在其他方面不是吗?”

Linuxmmap()。内存映射缓冲区可以从内存中逐出(理论上),除非它是mlocke'd(mlock())。这在理论上是正确的。在实践中,我认为如果您的系统不交换,这几乎是不可能的。在这种情况下,第一个受害者是页面缓冲区

退房

它是使用共享内存的本地Java套接字的低延迟替代品


在现代CPU上,两个进程之间的RTT延迟远低于1U。

微秒的SI缩写是μs,而不是μ(数量和单位之间应该有一个空格)。我为你修正了它。我也不是一个专家,我会冒险猜测UDP可能会降低你的延迟,因为它是一个更轻量级的协议。当然,如果你的应用程序必须手动实现TCP提供的开箱即用的可靠性保证,那么编程时要痛苦得多,也可能不会带来任何好处。stdin/stdout/stderr如何(例如,第一个进程启动另外两个进程,而通信只发生在这个“主进程”和两个从进程之间)?这是一个选项吗?这三个进程不能共享同一个JVM有什么原因吗?@Marcelo:谢谢!波因