Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic Apache Camel LoadBalancer Failover Example

To start I just want to let you know I am new to Camel and very recently I grasped its main concepts.

I am trying to create a basic working example using Apache-Camel with ActiveMQ as a broker and using jms-component as a client of a loadbalancer using the failover construct. All this is done using the Java DSL only (if possible).

The example consists of 4 main apps, called MyApp-A, MyApp-B, MyApp-C and MyApp-D. In a normal scenario MyApp-A reads a file from my computer and then transforms it into a message. Then it sends that message to MyApp-B and MyApp-B sends it to MyApp-C.

enter image description here

However, there is a fail scenario. In this scenario, MyApp-A fails to send the message to MyApp-B. It then send the message to MyApp-D, which in turn sends it to MyApp-C.

enter image description here

Bellow is the my code for 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();
    }
}

I have considered using the camel-ftp but it would not work because MyApp-C would not know that MyApp-B died and would not know that it had to fetch from MyApp-D.

Now I have several problems and questions:

  1. How do I send a message (in this case, the file) from MyApp-A to MyApp-B which is a different application? What should I actually put in the .to(String) method of the Java DSL?
  2. How do I actually code MyApp-B? How do I make it receive a message from A (which is a different application, possibly in a different machine) and send it to MyApp-C (I assume that if I find out how to send from MyApp-A to MyApp-B, I will know how to send from MyApp-B to MyApp-C)?
  3. How will MyApp-A detect that MyApp-B failed?
  4. Which camel component should I use?

If you could provide any feedback on my code and on how to fix the problem I would be more then grateful.

like image 363
Flame_Phoenix Avatar asked Oct 20 '22 21:10

Flame_Phoenix


1 Answers

After much effort, I have found a way to implement this basing myself on the loadbalancer example provided by apache.

I have uploadded the eclipse project to my github account, you can check it working here:

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

Although my example does respect the overall intended architecture, it does have few differences as explained bellow:

  • It uses the Spring DSL instead of the Java DSL
  • MyApp-A is the loadbalancer. Every 10 it generates a report (instead of reading a file) and it sends it to MyApp-B.
  • MyApp-B corresponds to MINA server 1 on localhost:9991
  • MyApp-C corresponds to MINA server 3 on localhost:9993
  • MyApp-D corresponds to MINA server 2 on localhost:9992
  • When MyApp-C receives the report, it sends it back to MyApp-A

Furthermore, it is also not clear when, where or why MyApp-C replies to MyApp-A with the changed report. This behavior is not specified in the Spring DSL code and so far no one was able to explain to me why this is even happening.

So two problems remain:

  1. How would this be done using the Java DSL
  2. Why is the MyApp-C replying to MyApp-A and how is it doing it?

In case you are interested, Here is the README.txt I created, with an accurate description of the problem:

Load balancing with MINA Example

This example shows how you can easily use the Camel-MINA component to design a solution allowing for a fault tolerant solution that redirects requests when a server is down. These servers are simple TCP/IP servers created by the Apache MINA framework and run in separate JVMs.

In this example, the load balancer client will generate a report every 10 seconds and send that report to the MINA server running on localhost:9991. This server then forwards the report to the MINA server running on localhost:9993, which then returns the report to the client so it can print it on the console. Each MINA server will change the body of the message so you can see the routes that the report had to use. If for some reason (lets say you pressed CTRL+C), the MINA server running on localhost:9991 is dead, then the loadbalancer will automatically start using the MINA server running on localhost:9992. Once the this MINA server receives the report, it will send it back to the MINA server running on localhost:9993 like nothing has ever happened. If localhost:9991 gets back up again, then the loadbalancer will start using it again.

The load balancer will always attempt to use localhost:9991 before trying to use localhost:9992 no matter what.

Running the example

To compile and install the project in your maven repo, execute the following command on the root of the project

mvn clean install

To run the example, then execute the following command in the respective folder:

mina1:
mvn exec:java -Pmina1

mina2: mvn exec:java -Pmina2

mina3: mvn exec:java -Pmina3

loadbalancing: mvn exec:java -Ploadbalancer

If you hit any problems please let us know on the Camel Forums
http://camel.apache.org/discussion-forums.html


Pedro Martins !


EDIT

In the previous post I had 2 questions: 1. how to do this in java dsl 2. why are the mina servers sending replies.

I will attack problem 1 eventually, but I just want to state that the solution to problem 2 is here: http://camel.465427.n5.nabble.com/Load-balancing-using-Mina-example-with-Java-DSL-td5742566.html#a5742585

Kudos to Mr. Claus for the answer and suggestions.


EDIT

Both problems are now solved and they are both in the same git repository. I hope my code helps people.

like image 92
Flame_Phoenix Avatar answered Oct 29 '22 22:10

Flame_Phoenix