1
votes

I am new to Apache Camel and Netty and this is my first project. I am trying to use Camel with the Netty component to load balance heavy traffic in a back end load test scenario.This is the setup I have right now: from("netty:tcp:\\this-ip:9445?defaultCodec=false&sync=true").loadBalance().roundRobin().to("netty:tcp:\\backend1:9445?defaultCodec=false&sync=true,netty:tcp:\\backend2:9445?defaultCodec=false&sync=true)

The issue is unexpected buffer sizes that I am receiving in the response that I see in the client system sending tcp traffic to Camel. When I send multiple requests one after the other I see no issues and the buffer size is as expected. But, when I try running multiple users sending similar requests to Camel on the same port, I intermittently see unexpected buffer sizes, sometimes 0 bytes to sometimes even greater than the expected number of bytes. I tried playing around with multiple options mentioned in the Camel-Netty page like:

  • Increasing backlog
  • keepAlive
  • buffersizes
  • timeouts
  • poolSizes
  • workerCount
  • synchronous
  • stream caching (did not work)
  • disabled useOriginalMessage for performance
  • System level TCP parameters, etc. among others.

I am yet to resolve the issue. I am not sure if I'm fundamentally missing something. I did take a look at the encoder/decoders and guess if that could be an issue. But, I don't understand why a load balancer needs to encode/decode messages. I have worked with other load balancers which just require endpoint configurations and hence, I am assuming that Camel does not require this. Am I right? Please know that the issue is not with my client/backend as I ran a 2000 user load test from my client to the backend with less than 1% failures but see a large number of failure ( not that there are no successes) with Camel. I have the following questions:

1.Is this a valid use-case for Apache Camel- Netty? Should I be looking at Mina or others?

2.Can I try to route tcp traffic to JMS or other components and then finally to the tcp endpoint?

3.Do I need encoders/decoders or should this configuration work?

4.Should I continue with this approach or try some other load balancer?

Please let me know if you have any other suggestions. TIA.

Edit1:

I also tried the same approach with netty4 and mina components. The route looks similar to the one in netty. The route with netty4 is as follows: from("netty4:tcp:\\this-ip:9445?defaultCodec=false&sync=true").to("netty4:tcp:\\backend1:9445?defaultCodec=false&sync=true") I read a few posts which had the same issue but did not find any solution relevant to my issue.

Edit2:

I increased the receive timeout at my client and immediately noticed the mismatch in expected buffer length issue fall to less than 1%. However, I see that the response times for each transaction when using Camel and not using it is huge; almost 10 times higher. Can you help me with reducing the response times for each transaction? The message received back at my client varies from 5000 to 20000 bytes. Here is my latest route:

from("netty:tcp://this-ip:9445?sync=true&allowDefaultCodec=false&workerCount=20&requestTimeout=30000") .threads(20) .loadBalance() .roundRobin() .to("netty:tcp://backend-1:9445?sync=true&allowDefaultCodec=false","netty:tcp://backend-2:9445?sync=true&allowDefaultCodec=false")

I also used certain performance enhancements like: context.setAllowUseOriginalMessage(false); context.disableJMX(); context.setMessageHistory(false); context.setLazyLoadTypeConverters(true);

Can you point me in the right direction about how I can reduce the individual transaction times?

2
Why are you not using netty4 as the previous netty component is deprecated? You can let allowDefaultEncoding unless you need to encode and decode your data.Souciance Eqdam Rashti
The setup is not working when I don't specify defaultCodec=false. I also tried using netty4 but could not get it working. Will try it again and post the updates.bnsk
@SoucianceEqdamRashti I tried the same thing with netty4 but getting an exception. Below is the stack trace: io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1 at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:115) at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:53) at io.netty.channel.ChannelOutboundBuffer.fail(ChannelOutboundBuffer.java:252)bnsk
How does your route look after changing to netty4? Can you update the question?Souciance Eqdam Rashti
@SoucianceEqdamRashti Edited the question with whatever I tried using netty4 and mina. Not sure if it is something to do with Encoders/Decoders. An issue with Encoders/Decoders means not even one request will be successful right?bnsk

2 Answers

0
votes

For netty4 component there is no parameter called defaultCodec. It is called allowDefaultCodec. http://camel.apache.org/netty4.html Also, try something like this first.

from("netty4:tcp:\\this-ip:9445?textline=true&sync=true").to("netty4:tcp:\\backend1:9445?textline=true&sync=true")

The above means the data being sent is normal text. If you are sending byte or something else you will need to provide decoding/encoding for netty to handle the data.

And a side note. Before running the Camel route, test manually to send test messages via a standard tcp tool like sockettest to verify that everything works. Then implement the same via Camel. You can find sockettest here http://sockettest.sourceforge.net/ .

0
votes

I finally solved the issue with the same route settings as above. The issue was with the Request and Response Delimiter not configured properly due to which it was either closing the connection too early leading to unexpected buffer sizes or it was waiting too long even after the entire buffer was received leading to high response times.