带有 Mappedbus 的 Java IPC - 在 EOF 上重置文件
Posted
技术标签:
【中文标题】带有 Mappedbus 的 Java IPC - 在 EOF 上重置文件【英文标题】:Java IPC with Mappedbus - reset file on EOF 【发布时间】:2016-12-21 13:34:18 【问题描述】:我在两个 JVM(oracle jdk 1.8、linux arm)之间使用 Mappedbus 进行 IPC; 我希望看到 IPC“永远”工作,但由于内存映射(或共享内存)文件是有限的,因此在编写器之前或之后会收到 EOFException。
所以我尝试重置写入器(和读取器),但在关闭并重新打开写入器后,读取器无法读取新记录。
所以,问题是,如何使以下测试用例工作,即在编写者和阅读器工作的情况下永远持续下去?
// intentionally low, for this test case
final long FILE_SIZE = 2000L;
private final String fileName = "/dev/shm/ipc-message";
@Test
public void hello() throws IOException
MappedBusReader reader;
MappedBusWriter writer;
writer = new MappedBusWriter(fileName, FILE_SIZE, 128, false);
writer.open();
reader = new MappedBusReader(fileName, FILE_SIZE, 128);
reader.open();
int writeCounter = 0;
int readCounter = 0;
while (true)
IpcMessage message = new IpcMessage();
message.source = 1;
message.value = 1;
message.destination = 2;
message.body = new byte [32];
try
writer.write(message);
catch (EOFException ex)
System.out.println("write EXCEPTION");
writer.close();
writer = new MappedBusWriter(fileName, FILE_SIZE, 128, false);
writer.open();
System.out.println("write: " + writeCounter++);
try
if (reader.next())
boolean recovered = reader.hasRecovered();
int type = reader.readType();
System.out.println("read: " + readCounter++);
reader.readMessage(message);
catch (EOFException ex)
System.out.println("read EXCEPTION");
reader.close();
reader = new MappedBusReader(fileName, FILE_SIZE, 128);
reader.open();
IpcMessage 在哪里:
public class IpcMessage implements MappedBusMessage, Serializable
public static final int TYPE = 0;
public int messageType;
public int value;
public int source;
public int destination;
@Override
public void write(MemoryMappedFile mem, long pos)
mem.putInt(pos, messageType);
mem.putInt(pos + 4, value);
mem.putInt(pos + 8, source);
mem.putInt(pos + 12, destination);
@Override
public void read(MemoryMappedFile mem, long pos)
messageType = mem.getInt(pos);
value = mem.getInt(pos + 4);
source = mem.getInt(pos + 8);
destination = mem.getInt(pos + 12);
@Override
public int type()
return TYPE;
我从这个测试用例得到的输出是:
write: 0
read: 0
write: 1
read: 1
write: 2
read: 2
...
write: 8
read: 8
write: 9
read: 9
write: 10
read: 10
write: 11
read: 11
write: 12
read: 12
write: 13
read: 13
write EXCEPTION
write: 14
write: 15
write: 16
write: 17
write: 18
write: 19
write: 20
write: 21
write: 22
write: 23
【问题讨论】:
我会冒险猜测你会从套接字获得更好的性能,因为你似乎在做线性 IO,尽管这当然取决于用例。 参见例如this answer 类似的问题。 FWIW,SHM不是内存映射的文件,磁盘 IO 会消耗大量性能并增加管理 EOF 等复杂性。 @LukeBriggs:实际上我在不同的 JVM 中有三个进程在它们之间进行通信,所以像 Jgroups 这样的多播套接字解决方案可能是解决方案。 【参考方案1】:我收到了来自 Mappedbus 开发者的电子邮件对我的问题的回答,我认为这很有趣,所以我在这里复制它:
这里简要回答了这个问题: https://github.com/caplogic/Mappedbus/issues/1
简而言之,mappedbus 适用于需要存储所有 消息。如果你不需要这样做,它可能不是正确的 解决方案。
如果您确实需要存储它们,只需使文件足够大即可 能够包含系统生命周期中的所有消息 (例如一天)。然后有一段时间你停止一切 组件,重命名文件并重新启动它们。
【讨论】:
以上是关于带有 Mappedbus 的 Java IPC - 在 EOF 上重置文件的主要内容,如果未能解决你的问题,请参考以下文章