You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by SteveR <sr...@vonage.com> on 2015/09/29 16:48:20 UTC
Camel Load Balancer EIP with TCP Endpoints
I have a stand-alone Java application using Camel 2.15 and camel-netty4 which
is running on Linux RHEL6. I see that Camel supports a Load Balancer EIP and
I'm wondering if it would a good fit based on the following requirements for
my application:
*REQUIREMENTS:*
- Accept various incoming TCP connections (each TCP feed consists of
messages that start with <MSG> and end with </MSG>). So I'll be using a
DelimiterBasedFrameDecoder in my TcpServerPipelineFactory.
- No policing/rejection of incoming TCP connection requests is required,
just accept each one that attempts to connect to the well-known listen port
for this application.
- Filter out uninteresting messages. I'll be using a filter bean for this.
- Uniformly distribute, via TCP, the interesting messages to a set of 4 TCP
listeners
while failing over in round-robin fashion if a particular server is
unreachable for any reason.
- Maintain the TCP connections to the reachable servers (i.e. don't
establish/tear-down a TCP connection for each transmitted message).
I was thinking that the Camel Load Balancer EIP with a failover policy and
the roundRobin option would be a good choice. I'm hoping that the 4 routes
to the TCP listeners will be established by netty4 and stay connected!
Below is my Java DSL psuedo-code for the routes that I've initially come up
with.
Any thoughts about whether or not this approach would work is greatly
appreciated.
I know there are lots of URI parameters to consider and I want to be sure
I'm not missing
any important ones. Also any ideas for making this application more robust,
fault tolerant,
and better-performing would be great!
Thanks, SteveR
from("netty4:tcp://host:port?serverInitializerFactory=#TCP_SERVER_PIPELINE_FACTORY")
.to("seda:FILTER_QUEUE");
from("seda:FILTER_QUEUE?size=100000&concurrentConsumers=10&waitForTaskToComplete=Never&failIfNoConsumers=true&timeout=10000)
.threads(threadPoolSize /*poolSize*/, threadPoolSize * 2 /*maxPoolSize*/)
.filter()
.method(filterBeanName, "isInterestingMessage")
.to("seda:BALANCER_QUEUE");
.end();
from("seda:BALANCER_QUEUE?size=100000&concurrentConsumers=10&waitForTaskToComplete=IfReplyExpected&failIfNoConsumers=true&timeout=10000)
.loadBalance()
.failover(-1, /* Never give up (i.e. continuously try to failover) */,
false, /* Do not inherit route's ErrorHandler */,
true /* Operate in round-robin mode */)
.to("seda:TCP_LISTENER1", "seda:TCP_LISTENER2", "seda:TCP_LISTENER3",
"seda:TCP_LISTENER4")
.end();
from("seda:TCP_LISTENER1?size=100000&concurrentConsumers=10&waitForTaskToComplete=Never&failIfNoConsumers=true&timeout=10000")
.threads(threadPoolSize /*poolSize*/, threadPoolSize * 2 /*maxPoolSize*/)
.to("netty4:tcp://host:port&options ...");
from("seda:TCP_LISTENER2?size=100000&concurrentConsumers=10&waitForTaskToComplete=Never&failIfNoConsumers=true&timeout=10000")
.threads(threadPoolSize /*poolSize*/, threadPoolSize * 2 /*maxPoolSize*/)
.to("netty4:tcp://host:port&options ...");
from("seda:TCP_LISTENER3?size=100000&concurrentConsumers=10&waitForTaskToComplete=Never&failIfNoConsumers=true&timeout=10000")
.threads(threadPoolSize /*poolSize*/, threadPoolSize * 2 /*maxPoolSize*/)
.to("netty4:tcp://host:port&options ...");
from("seda:TCP_LISTENER4?size=100000&concurrentConsumers=10&waitForTaskToComplete=Never&failIfNoConsumers=true&timeout=10000")
.threads(threadPoolSize /*poolSize*/, threadPoolSize * 2 /*maxPoolSize*/)
.to("netty4:tcp://host:port&options ...");
--
View this message in context: http://camel.465427.n5.nabble.com/Camel-Load-Balancer-EIP-with-TCP-Endpoints-tp5772104.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: Camel Load Balancer EIP with TCP Endpoints
Posted by Cleocleo <se...@gmail.com>.
Ok, I'm not sure camel is going to solve this problem for you. You could get
a physical or software load balancer capable of load balancing the long
lived tcp connections. However, transparently switching a server if one
server is down seems challenging (without the client knowing). Seems like
people typically maintain a pool of servers on the client side and then
handle switching servers if the clients tcp closes. Maybe there's a better
solution - let me know what you find!
--
View this message in context: http://camel.465427.n5.nabble.com/Camel-Load-Balancer-EIP-with-TCP-Endpoints-tp5772104p5772335.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: Camel Load Balancer EIP with TCP Endpoints
Posted by SteveR <sr...@vonage.com>.
CleoCleo:
Thanks for the reply. These are long-standing TCP connections, meaning that
the client that connects to my Camel application establishes the connection
and in the "sunny-day" case continues to send a continual stream of messages
each of which are delimited by the <MSG> ... </MSG> tags. The message rate
is subject to busy-hour patterns, so it's high at certain peaks hours and
could slow to a trickle at non-peak hours.
For the load-balancing portion in the out-going direction, my Camel
application would also typically have long-standing TCP connections to each
recipient host.
Thanks, SteveR
--
View this message in context: http://camel.465427.n5.nabble.com/Camel-Load-Balancer-EIP-with-TCP-Endpoints-tp5772104p5772314.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: Camel Load Balancer EIP with TCP Endpoints
Posted by Cleocleo <se...@gmail.com>.
Are we talking about long or short lived TCP connections? E.g does the client
open a connection and continue to send/receive messages over a long period
of time (how long?) or does the client open a connection, send the message,
and then close the connection soon after getting a response/acknowledgment
back from a server?
Can't really speak on the topic of long lived TCP connections, but here are
some questions and patterns that might help if you're dealing with short
lived connections:
First, is the client-server communication synchronous or asynchronous in
nature? (e.g does the client wait for the server to do some processing of
the message before getting a response back / closing the connection, or does
the client not need to wait?)
If it's asynchronous, a common pattern would be to use a queue in between
the producer(s) and the consumer(s) handling the message. Could be
implemented as threads using an in-memory queue all the way to separate
physical servers depending on a queue (e.g. ActiveMQ, RabbitMQ, SQS, etc).
Really depends on your needs.
If it's synchronous, you wouldn't use the queuing pattern - load balancer
would be more appropriate. Again, there are many ways to implement this.
Since your sample code is using seda, you're heading down the asynchronous
path. Overall, your sample looks a little strange. Here's what's happening:
Your TCP message gets put onto a queue (and the TCP connection is closed).
You then have 10 consumers consuming those messages sending messages to 1 of
4 different queues using a load balancer, and then 10 consumers per
load-balanced queue consuming messages and sending the message to a TCP
endpoint... I can't imagine that's what you want to do :)
Can you provide some more details on the sync/async nature of this
communication? We can start there, and then we can talk about how distribute
(or not distribute) the message consumers based on your needs, and how camel
might fit into your solution.
--
View this message in context: http://camel.465427.n5.nabble.com/Camel-Load-Balancer-EIP-with-TCP-Endpoints-tp5772104p5772121.html
Sent from the Camel - Users mailing list archive at Nabble.com.