blob: ba618a516112f61faf29f02ff55e6e35f6efffe9 [file]
= Master Component
:doctitle: Master
:shortname: master
:artifactid: camel-master
:description: Have only a single consumer in a cluster consuming from a given endpoint; with automatic failover if the JVM dies.
:since: 2.20
:supportlevel: Stable
:tabs-sync-option:
:component-header: Only consumer is supported
*Since Camel {since}*
*{component-header}*
The Camel-Master endpoint provides a way to ensure only a single consumer in a cluster consumes from a given endpoint;
with automatic fail over if that JVM dies.
This can be handy if you need to consume from some legacy back end that either doesn't support concurrent
consumption or due to commercial or stability reasons, you can only have a single connection at any point in time.
== URI format
----
master:namespace:endpoint[?options]
----
Where endpoint is any Camel endpoint, you want to run in master/slave mode.
// component options: START
include::partial$component-configure-options.adoc[]
include::partial$component-endpoint-options.adoc[]
include::partial$component-endpoint-headers.adoc[]
// component options: END
== Usage
=== Starting the delegated consumer
When a node takes the leadership, the delegated consumer is started in the background, and the start is
retried when it fails, for instance because the back end it consumes from is not reachable yet. The retries
are configured on the component with `backOffDelay` (the delay between attempts, 5000 millis by default)
and `backOffMaxAttempts` (the number of attempts, 10 by default).
Once the attempts are used up, the node keeps the leadership but consumes nothing until the leadership
changes again, which is logged at ERROR level. Set `backOffMaxAttempts` to 0 to keep retrying for as long as
the node is the leader instead.
=== Using the master endpoint
Prefix any camel endpoint with **master:someName:** where _someName_ is a logical name and is
used to acquire the master lock.
For instance:
[tabs]
====
Java::
+
[source,java]
----
from("master:cheese:jms:foo")
.to("activemq:wine");
----
XML::
+
[source,xml]
----
<route>
<from uri="master:cheese:jms:foo"/>
<to uri="activemq:wine"/>
</route>
----
YAML::
+
[source,yaml]
----
- route:
from:
uri: master:cheese:jms:foo
steps:
- to:
uri: activemq:wine
----
====
In this example, the master component ensures that the route is only active in one node, at any given time, in the cluster.
So if there are 8 nodes in the cluster, then the master component will elect one route to be the leader, and only
this route will be active, and hence only this route will consume messages from `jms:foo`.
In case this route is stopped or unexpectedly terminated, then the master component will detect this,
and re-elect another node to be active, which will then become active and start consuming messages from `jms:foo`.
TIP: Apache ActiveMQ 5.x has such a feature out of the box called https://activemq.apache.org/exclusive-consumer.html[Exclusive Consumers].
== Example
You can protect a clustered Camel application to only consume files from one active node.
._Java-only: string concatenation to build the master endpoint URI_
[source,java]
----
// the file endpoint we want to consume from
String url = "file:target/inbox?delete=true";
// use the camel master component in the clustered group named myGroup
// to run a master/slave mode in the following Camel url
from("master:myGroup:" + url)
.log(name + " - Received file: ${file:name}")
.delay(delay)
.log(name + " - Done file: ${file:name}")
.to("file:target/outbox");
----
The master component leverages CamelClusterService you can configure using
* *Java*
+
._Java-only: programmatic ZooKeeperClusterService configuration_
[source,java]
----
ZooKeeperClusterService service = new ZooKeeperClusterService();
service.setId("camel-node-1");
service.setNodes("myzk:2181");
service.setBasePath("/camel/cluster");
context.addService(service)
----
* *Xml (Spring)*
+
[source,xml]
----
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="cluster" class="org.apache.camel.component.zookeeper.cluster.ZooKeeperClusterService">
<property name="id" value="camel-node-1"/>
<property name="basePath" value="/camel/cluster"/>
<property name="nodes" value="myzk:2181"/>
</bean>
<camelContext xmlns="http://camel.apache.org/schema/spring" autoStartup="false">
...
</camelContext>
</beans>
----
* *Camel Main / Spring Boot*
+
[source,properties]
----
camel.cluster.zookeeper.enabled = true
camel.cluster.zookeeper.id = camel-node-1
camel.cluster.zookeeper.basePath = /camel/cluster
camel.cluster.zookeeper.nodes = myzk:2181
----
== Implementations
Camel provides the following ClusterService implementations:
- camel-consul
- camel-file
- camel-infinispan
- camel-jgroups-raft
- camel-jgroups
- camel-kubernetes
- camel-zookeeper