基本的 Apache Camel LoadBalancer 故障转移示例

Posted

技术标签:

【中文标题】基本的 Apache Camel LoadBalancer 故障转移示例【英文标题】:Basic Apache Camel LoadBalancer Failover Example 【发布时间】:2013-11-13 18:37:30 【问题描述】:

首先,我只想让您知道我是 Camel 的新手,最近我掌握了它的主要概念。

我正在尝试创建一个基本的工作示例,使用 Apache-Camel 和 ActiveMQ 作为代理,并使用 jms-component 作为负载均衡器的客户端,使用故障转移构造。所有这些都仅使用 Java DSL 完成(如果可能的话)。

该示例包含 4 个主要应用程序,分别称为 MyApp-A、MyApp-B、MyApp-C 和 MyApp-D。在正常情况下,MyApp-A 从我的计算机中读取文件,然后将其转换为消息。然后它将该消息发送到 MyApp-B,MyApp-B 将其发送到 MyApp-C。

但是,有一个失败的场景。在这种情况下,MyApp-A 无法将消息发送到 MyApp-B。然后它将消息发送到 MyApp-D,MyApp-D 又将消息发送到 MyApp-C。

下面是我的 MyApp-A 代码

public class MyApp-A 

    public static void main(String args[]) throws Exception 
        // create CamelContext
        CamelContext context = new DefaultCamelContext();

        // connect to embedded ActiveMQ JMS broker
        ConnectionFactory connectionFactory = 
            new ActiveMQConnectionFactory("vm://localhost");
        context.addComponent("jms",
            JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));

        // add our route to the CamelContext
        context.addRoutes(new RouteBuilder() 
            @Override
            public void configure() 
                from("file:data/inbox?noop=true")loadbalancer().failover().to("MyApp-B:incomingOrders").to("MyApp-D:incomingOrders").end();
            
        );

        // start the route and let it do its work
        context.start();
        Thread.sleep(10000);

        // stop the CamelContext
        context.stop();
    

我曾考虑使用camel-ftp,但它不起作用,因为 MyApp-C 不知道 MyApp-B 死了,也不知道它必须从 MyApp-D 获取。

现在我有几个问题和疑问:

    如何将消息(在本例中为文件)从 MyApp-A 发送到另一个应用程序的 MyApp-B?我应该在 Java DSL 的 .to(String) 方法中实际放入什么? 我如何实际编码 MyApp-B?如何让它接收来自 A 的消息(这是一个不同的应用程序,可能在不同的机器上)并将其发送到 MyApp-C(我假设如果我知道如何从 MyApp-A 发送到 MyApp-B,我会知道如何从 MyApp-B 发送到 MyApp-C)? MyApp-A 将如何检测 MyApp-B 失败? 我应该使用哪种骆驼组件?

如果您能就我的代码以及如何解决问题提供任何反馈,我将不胜感激。

【问题讨论】:

【参考方案1】:

经过一番努力,我找到了一种方法来实现这一点,基于 apache 提供的负载均衡器示例。

我已将 eclipse 项目上传到我的 github 帐户,您可以在这里查看它是否正常工作:

https://github.com/Fl4m3Ph03n1x/***/tree/master/loadbalancer-failover-springdsl-example

虽然我的示例确实尊重整体预期架构,但它确实有一些差异,如下所述:

它使用 Spring DSL 而不是 Java DSL MyApp-A 是负载平衡器。它每 10 次生成一个报告(而不是读取文件)并将其发送到 MyApp-B。 MyApp-B 对应 localhost:9991 上的 MINA 服务器 1 MyApp-C 对应 localhost:9993 上的 MINA 服务器 3 MyApp-D 对应 localhost:9992 上的 MINA 服务器 2 MyApp-C 收到报告后,会将其发送回 MyApp-A

此外,还不清楚 MyApp-C 何时、何地或为什么用更改后的报告回复 MyApp-A。 Spring DSL 代码中没有指定这种行为,到目前为止,没有人能够向我解释为什么会发生这种情况。

所以还有两个问题:

    如何使用 Java DSL 完成此操作 为什么 MyApp-C 会回复 MyApp-A,它是如何回复的?

如果您有兴趣,这里是我创建的 README.txt,其中包含对问题的准确描述:

负载均衡与 MINA 示例

本示例展示了如何轻松使用 Camel-MINA 组件 设计一个允许容错解决方案的解决方案 当服务器关闭时重定向请求。这些服务器很简单 TCP/IP 服务器由 Apache MINA 框架创建并运行在 独立的 JVM。

在此示例中,负载均衡器客户端将在每个 10 秒,然后将该报告发送到运行的 MINA 服务器 本地主机:9991。然后该服务器将报告转发给 MINA 在 localhost:9993 上运行的服务器,然后将报告返回到 客户端,以便它可以在控制台上打印它。每个 MINA 服务器将 更改消息的正文,以便您可以看到 报告不得不使用。如果出于某种原因(假设您按下了 CTRL+C), 在 localhost:9991 上运行的 MINA 服务器死了,然后 loadbalancer 将自动开始使用运行在 本地主机:9992。一旦这个 MINA 服务器收到报告,它会 将其发送回在 localhost:9993 上运行的 MINA 服务器,例如 什么都没发生。如果 localhost:9991 再次恢复,那么 负载均衡器将再次开始使用它。

负载均衡器将始终尝试使用 localhost:9991 之前 无论如何都尝试使用 localhost:9992。

运行示例

要在您的 maven 存储库中编译和安装项目,请执行 在项目的根目录下执行以下命令

mvn 全新安装

要运行示例,然后在 相应文件夹:

米娜1: mvn exec:java -Pmina1

米娜2: mvn exec:java -Pmina2

米娜3: mvn exec:java -Pmina3

负载平衡: mvn exec:java -Ploadbalancer

如果您遇到任何问题,请在 Camel 论坛上告诉我们http://camel.apache.org/discussion-forums.html


佩德罗·马丁斯!


编辑

在上一篇文章中,我有两个问题: 1.如何在java dsl中做到这一点 2. 为什么mina服务器会回复。

我最终会攻击问题 1,但我只想说明问题 2 的解决方案在这里: http://camel.465427.n5.nabble.com/Load-balancing-using-Mina-example-with-Java-DSL-td5742566.html#a5742585

感谢克劳斯先生的回答和建议。


编辑

这两个问题现在都解决了,它们都在同一个 git 存储库中。我希望我的代码可以帮助人们。

【讨论】:

以上是关于基本的 Apache Camel LoadBalancer 故障转移示例的主要内容,如果未能解决你的问题,请参考以下文章

带有 ActiveMQ 集群的 Apache Camel

[每日一学]apache camel|BDD方式开发apache camel|Groovy|Spock

Apache Camel

apache camel 条件路由

如何在apache camel中附加速度文件内容

Apache Camel 压缩包