如何使用持久性消息加载平衡ActiveMQ

时间:2013-08-12 11:37:01

标签: activemq apache-camel load-balancing jbossfuse

我有一个基于Apache Camel的中间件,它做了这样的事务:

from("amq:job-input")
  to("inOut:businessInvoker-one") // Into business processor
  to("inOut:businessInvoker-two")
  to("amq:job-out");

目前它完美无缺。但我无法扩大规模,比如从100 TPS到500 TPS。我已经

  1. 提升并发使用者设置并使用空businessProcessor
  2. 配置JAVA_XMX和PERMGEN
  3. 加快交易。

    根据Active MQ Web控制台,在场景500TPS上等待处理的消息太多了。我猜,其中一个解决方案是扩展ActiveMQ。所以我想在群集中使用多个代理。

    根据http://fuse.fusesource.org/mq/docs/mq-fabric.html(“拓扑”部分),在群集模式下配置ActiveMQ适用于非持久性消息。恕我直言,这是不合适的,因为所有正在运行的经纪人都使用相同的商店文件。但是,如何分离商店文件?现在可能吧?

    有人可以解释一下吗?如果不可能,那么对持久性消息进行负载均衡的最佳方法是什么?

    由于

5 个答案:

答案 0 :(得分:1)

您可以通过创建2个主/从对来共享持久消息的负载。主服务器和从服务器通过数据库或共享文件系统共享其状态,因此您需要复制该设置。

创建2个主从对,并在2对之间配置所谓的“网络连接器”。这样可以使您的表现翻倍,而不会丢失消息。

请参阅http://activemq.apache.org/networks-of-brokers.html

答案 1 :(得分:0)

如果所有正在运行的代理使用相同的存储文件或tx支持的数据库进行持久化,则只有第一个要启动的代理将处于活动状态,而其他代理处于待机状态,直到第一个代理失去锁定。

如果你想平衡你的持久性,我们可以尝试两种方式:

  1. 在网桥模式下配置多个代理,然后发送消息 来自其中一个以上的任何消息和消费者消息。它可以 负载均衡经纪人和负载均衡持久性。
  2. 覆盖persistenceAdapter并使用数据库分片中间件 (例如tddl:https://github.com/alibaba/tb_tddl)来存储 分区消息。

答案 2 :(得分:0)

此答案涉及添加Camel详细信息之前的问题版本。

目前还不清楚您想要负载均衡的原因是什么。消费者的消息?经纪人的生产者?你试图解决什么问题?

一般情况下,你应该避免使用经纪人网络,除非你试图解决某种地理用例,有太多连接供签名经纪人处理,或者单个经纪人(可能是一对经纪人配置)在HA)没有给你所需的吞吐量(在90%的情况下它会)。

在代理网络中,每个节点都有自己的存储,并通过名为store-and-forward的机制传递消息。请阅读Understanding broker networks,了解其工作原理。

ActiveMQ已经作为一种负载均衡器工作,它通过在队列中的订阅者之间以循环方式均匀地分发消息。因此,如果队列中有2个订户,则向其发送消息流A,B,C,D;一名订阅者将获得A& C,而另一个接收B& D.

如果您想更进一步,并在队列中对相关消息进行分组,以便只有一个订阅者一致地处理它们,您应该考虑Message Groups

答案 3 :(得分:0)

添加消费者可能有所帮助(取决于您的服务器拥有的核心数/ cpu)。添加线程超出了“Camel服务器”利用所有可用CPU进行业务处理的程度毫无意义,并且可以提高效率。

可能需要添加更多ActiveMQ计算机。您可以使用ActiveMQ“网络”在具有分隔的持久性文件的实例之间进行通信。应该直接添加更多代理并将它们放入网络中。

确保您在路上进行性能测试,以确保代理可以处理哪种负载以及驼峰处理器可以处理的负载(如果在不同的计算机上)。

当您执行持久性消息传递时 - 您可能还需要事务。确保你使用它们。

答案 4 :(得分:-1)

您的第一步是增加从ActiveMQ处理的工作人员数量。执行此操作的方法是将?concurrentConsumers=10属性添加到起始URI。默认行为是只有一个线程从该端点消耗,导致ActiveMQ中的消息堆积。添加更多经纪人无济于事。

其次,您似乎正在做的事情可以从分阶段事件驱动架构(SEDA)中受益。在SEDA中,处理被分解为多个阶段,这些阶段可以具有不同数量的消费者以使吞吐量均匀。从ActiveMQ消耗的线程只执行该过程的一个步骤,将Exchange交给下一个阶段,然后返回从输入队列中提取消息。

因此,您可以将路线重写为2条较小的路线:

from("activemq:input?concurrentConsumers=10").id("FirstPhase")
    .process(businessInvokerOne)
    .to("seda:invokeSecondProcess");

from("seda:invokeSecondProcess?concurentConsumers=20").id("SecondPhase")
    .process(businessInvokerTwo)
    .to("activemq:output");

这两个阶段可以具有不同数量的并发使用者,因此来自输入队列的消息消耗率与输出率相匹配。如果其中一个调用者比另一个调用者慢得多,那么这很有用。

如果您想要消息持久性,seda:端点可以替换为另一个中间activemq:端点。

最后,为了提高吞吐量,您可以通过分析调用者自身并优化代码来专注于加快处理速度。