Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start Camel routes on slave ActiveMQ only when slave becomes active in failover?

I have a durable consumer to a remote JMS queue in embedded Camel routing. Is it possible to have this kind of routing with master-slave configuration? Now it seems that the Camel routes are started and activated already when slave ActiveMQ is started and not when the actual failover happens.

Now it causes the slave instance to receive the same messages that are also sent to master and this causes duplicate messages to arrive to the queue on failover.

I'm using ActiveMQ 5.3 along with Apache Camel 2.1.

like image 446
Tommi L. Avatar asked Jan 14 '10 14:01

Tommi L.


2 Answers

Unfortunately, when the slave broker starts so does the CamelContext along with the routes. However you can accomplish this by doing the following:

On the camelContext deployed with slave broker add the following autoStartup attribute to prevent the routes from starting:

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring" autoStartup="false">

...

</camelContext>

Next you need to create a class that implements the ActiveMQ Service Interface. A sample of this would be as follows:

package com.fusesource.example;

import org.apache.activemq.Service;
import org.apache.camel.spring.SpringCamelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Example used to start and stop the camel context using the ActiveMQ Service interface
*
*/
public class CamelContextService implements Service
{
private final Logger LOG = LoggerFactory.getLogger(CamelContextService.class);
SpringCamelContext camel;

@Override
public void start() throws Exception {
    try {
        camel.start();
    } catch (Exception e) {
        LOG.error("Unable to start camel context: " + camel);
        e.printStackTrace();
    }
}

@Override
public void stop() throws Exception {
    try {
        camel.stop();
    } catch (Exception e) {
        LOG.error("Unable to stop camel context: " + camel);
        e.printStackTrace();
    }
}

public SpringCamelContext getCamel() {
    return camel;
}

public void setCamel(SpringCamelContext camel) {
    this.camel = camel;
}
}

Then in broker's configuration file, activemq.xml, add the following to register the service:

<services>
      <bean xmlns="http://www.springframework.org/schema/beans" class="com.fusesource.example.CamelContextService">
          <property name="camel" ref="camel"/>
      </bean>
</services>

Now, once the slave broker takes over as the master, the start method will be invoked on the service class and the routes will be started.

I have also posted a blog about this here: http://jason-sherman.blogspot.com/2012/04/activemq-how-to-startstop-camel-routes.html

like image 94
Jason Sherman Avatar answered Sep 20 '22 16:09

Jason Sherman


this shouldn't be an issue because the Camel context/routes on the slave will not start until it becomes the master (when the message store file lock is released by the master)

like image 40
Ben ODay Avatar answered Sep 19 '22 16:09

Ben ODay