我应该如何使用 VM 传输
常见问题解答 > 使用 Apache ActiveMQ Classic > 我应该如何使用 VM 传输
适用于 ActiveMQ Classic 3.x/4.x
使用 VM 传输 连接到 JVM 内部的代理是速度最快、效率最高的传输方式。
这是因为默认情况下,不会进行序列化到套接字或操作系统套接字资源,它纯粹是一个 JVM 内部的列表,用于与客户端和代理交换消息。 有时候你希望 VM 传输像异步 SEDA 队列一样工作;其他时候你希望内联处理,这样线程上下文切换就会减少,从而在高性能场景中提高吞吐量。
需要注意的是,使用 VM 传输时,消息是通过引用传递的。 对此的一个小例外是 JMS ObjectMessage。 (有关如何在 ActiveMQ Classic 4.x 中禁用它的详细信息,请参见下文)
还可以通过将 **copyMessageOnSend** 属性设置为 false 来进一步优化,这避免了对 ObjectMessage 进行复制以发送; 不过,这假设你不会尝试重用 ObjectMessage 实例; 你只需创建一次并发送一次,并且不要尝试在发送后更改消息体。
小心类加载器
请注意,只有在所有生产者和消费者都在兼容的类加载器中时,才应执行上述优化。 例如,如果你有两个 WAR,它们有自己的 jar 文件相互发送消息,你可能会遇到奇怪的 ClassCastExceptions,因为同一个类在每个类加载器中都被加载; 所以,有时候序列化 ObjectMessage 是避免类路径地狱的好方法 - 只有在你确定类路径没有问题时才进行上述优化。
为 ActiveMQ Classic 4.x 禁用 ObjectMessage 的对象序列化
JMS 规范规定,在调用 send() 时必须对 ObjectMessage 的主体进行序列化,以避免对象在你脚下发生变化,从而影响消费者看到对象的视图。
你可以通过将 **objectMessageSerializationDefered** 标志设置为 ActiveMQConnectionFactory(或 ActiveMQConnection)上的 true 来禁用 ObjectMessage 负载的自动序列化,这样对象将在 4.x 中按值传递。
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://127.0.0.1");
factory.setObjectMessageSerializationDefered(true);