Topics running simultaneously in a Netty UDP server

The code I'm analyzing creates a UDP server with Netty NioDatagramChannelFactory. It creates a thread pool with:

ExecutorService threadPool = Executors.newCachedThreadPool(); 

Then the datagram channel, pipeFactory and bootstrap:

 int workerCount = 10; DatagramChannelFactory datagramChannelFactory = new NioDatagramChannelFactory(threadPool, workerCount); ChannelPipelineFactory pipelineFactory = new SNMPTrapsPipeLineFactory(); ConnectionlessBootstrap bootStrap = new ConnectionlessBootstrap(datagramChannelFactory); bootStrap.setPipelineFactory(pipelineFactory); bootStrap.bind(new InetSocketAddress(host, port)); 

In the pipeline program, getPipeline () adds custom handlers.

Same as stated in: Multithreaded UDP Message Processing

There is only one thread that processes received messages. In the logs, the flow names are displayed as I / O working day I / O worker No. 1 , for example:

2012-04-20 09: 20: 51,853 New working I / O datagram # 1 '-' 1 INFO [cemrshSNMPTrapsRequestHandler: 42] messageReceived | Processing: V1TRAP [reqestID = 0, ...]

I read the documentation and this entry: Many UDP requests lost on a UDP server with Netty

And then I changed the code a bit according to these entries. Now the thread pool is created using:

 int corePoolSize = 5; ExecutorService threadPool = new OrderedMemoryAwareThreadPoolExecutor(corePoolSize, 1048576, 1048576); 

And pipeFactory with and ExecutionHandler:

 ExecutionHandler executionHandler = new ExecutionHandler(threadPool); ChannelPipelineFactory pipelineFactory = new SNMPTrapsPipeLineFactory(executionHandler); 

And getPipeline () adds a handler as described:

 public class SNMPTrapsPipeLineFactory implements ChannelPipelineFactory { private ExecutionHandler executionHandler = null; public SNMPTrapsPipeLineFactory(ExecutionHandler executionHandler) { this.executionHandler = executionHandler; } @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline pipeline = Channels.pipeline(); pipeline.addFirst("ExecutorHandler", executionHandler); // Here the custom handlers are added pipeline.addLast( ... ) } 

Now I get 4 different stream names in the logs. They look like pool-2-thread-1 , pool-2-thread-2 , etc.

For instance:

2012-05-09 09: 12: 19,589 pool-2-thread-1 INFO [cemrshSNMPTrapsRequestHandler: 46] messageReceived | Processing: V1TRAP [reqestID = 0, ...]

But they are not processed at the same time. Processing in messageReceived () should end in one thread for the next process of processing the next message. I sent an email from different clients to the server, and the logs I receive are not interlaced. I also tried to execute Thread.sleep () inside messageReceived () and confirmed the previous one.

Am I missing something? Is there a way to achieve a REAL multithreaded UDP server with Netty? How can I get different threads to execute messageReceived () at the same time?

+4
source share
2 answers

One thing that popped up on me is that you sent the handler first. I believe that the goal is that the entire pipeline to the "application" handler should be executed by I / O threads performing IO and decoding.

Therefore, I would say that you would like to add all the SNMPTrap decoding handlers first, and then when you have a real SNMPTrap, it is passed to the execution handler, which in turn passes the trap to the actual trap consumers to do something useful.

 @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline pipeline = Channels.pipeline( new SomethingSomethingDecoder(), new SNMPTrapDecoder(), executionHandler. snmpTrapConsumerHandler ); } 

At least as shown in the ExecutionHandler javadoc, and this is my interpretation.

0
source

Based on my experience and my understanding of Netty with UDP, it is normal that there is only one thread that processes UDP messages for decoding. Since UDP does not have a session, only one stream can receive data on one UDP port and decode it.

After you have decrypted your data and wrapped it in a buffer or a specific java object, you can put this object in a thread pool that will process it (execution handler -> your handler). Then new upcoming data on the UDP port can be decoded after you have released the previous decoded data into the execution handler.

The pool stream that you can specify when creating the NioDatagramChannelFactory is used only when listening to data on multiple ports. Only one thread per port makes sense. Even if you specify 100 workers in this constructor, only one will be used if you configured one UDP port.

0
source

Source: https://habr.com/ru/post/910366/


All Articles