Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Netty UDP服务器中未并发执行的线程_Multithreading_Concurrency_Udp_Netty - Fatal编程技术网

Multithreading Netty UDP服务器中未并发执行的线程

Multithreading Netty UDP服务器中未并发执行的线程,multithreading,concurrency,udp,netty,Multithreading,Concurrency,Udp,Netty,我正在分析的代码使用Netty NioDatagramChannelFactory创建UDP服务器。 它创建一个线程池,其中包含: ExecutorService threadPool = Executors.newCachedThreadPool(); 然后是数据报通道、pipelineFactory和引导: int workerCount = 10; DatagramChannelFactory datagramChannelFactory = new NioDatagramChannel

我正在分析的代码使用Netty NioDatagramChannelFactory创建UDP服务器。 它创建一个线程池,其中包含:

ExecutorService threadPool = Executors.newCachedThreadPool();
然后是数据报通道、pipelineFactory和引导:

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));
在pipelineFactory中,getPipeline()添加自定义处理程序

正如书中所说:

只有一个线程处理收到的消息。在日志中,线程名称显示为新I/O数据报工作线程1类似:

2012-04-20 09:20:51853新I/O数据报工作程序#1'-'1信息[c.e.m.r.s.h.SNMPTrapsRequestHandler:42]消息已接收|处理:V1TRAP[Requestid=0,…]

我阅读了文档和此条目:

然后我根据这些条目对代码做了一些修改。 现在,线程池是通过以下方式创建的:

int corePoolSize = 5;
ExecutorService threadPool = new OrderedMemoryAwareThreadPoolExecutor(corePoolSize, 1048576, 1048576);
以及具有和ExecutionHandler的pipelineFactory:

ExecutionHandler executionHandler = new ExecutionHandler(threadPool);
ChannelPipelineFactory pipelineFactory = new SNMPTrapsPipeLineFactory(executionHandler);
getPipeline()添加如下所述的处理程序:

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( ... )
    }
现在,我在日志中得到了4个不同的线程名称。它们显示为池-2-thread-1池-2-thread-2

例如:

2012-05-09 09:12:19589 pool-2-thread-1信息[c.e.m.r.s.h.SNMPTrapsRequestHandler:46]消息已接收|处理:V1TRAP[Requestid=0,…]

但它们不是同时处理的。 messageReceived()下的处理必须在一个线程上完成,下一个线程才能处理下一条消息。 我从不同的客户机向服务器发送了大量消息,并且我得到的日志不是交错的。我还尝试在messageReceived()中执行Thread.sleep(),并确认了前面的操作

我错过什么了吗? 有没有办法用Netty实现真正的多线程UDP服务器?
如何让不同的线程同时执行messageReceived()?

我突然想到的一件事是,您首先将执行处理程序放入管道中。我相信其目的是,到“应用程序”处理程序的整个管道应该由执行IO和解码的IO线程执行

因此,我认为您应该首先添加所有的SNMPTrap解码处理程序,然后,当您有一个实际的SNMPTrap时,它会被传递给执行处理程序,执行处理程序又会将陷阱传递给陷阱的实际使用者,以便对其做一些有用的事情

@Override
public ChannelPipeline getPipeline() throws Exception {

    ChannelPipeline pipeline = Channels.pipeline(
         new SomethingSomethingDecoder(),
         new SNMPTrapDecoder(),
         executionHandler.
         snmpTrapConsumerHandler
    );
}

至少,javadoc中是这样显示的,以上是我对它的解释。

根据我的经验和我对Netty with UDP的理解,只有一个线程处理UDP消息进行解码是正常的。由于UDP是无会话的,因此只有一个线程可以在一个UDP端口上接收数据并对其进行解码

一旦解码了数据并将其包装到缓冲区或特定java对象中,就可以将该对象放入将处理它的线程池(执行处理程序->业务处理程序)。然后,一旦您将先前解码的数据释放到执行处理程序中,就可以对UDP端口上即将出现的新数据进行解码


创建NioDatagramChannelFactory时可以指定的池线程仅在侦听多个端口上的数据时使用。每个端口只有一个线程有意义。即使在该构造函数中指定了100个工作线程,如果配置了一个UDP端口,也只会使用一个工作线程。

如果我没有弄错,则OrderedMemoryAwareThreadPoolExecutor在同一线程中执行来自同一客户端的请求。是。我尝试过这种方法,文档中描述过的方法,但不起作用。然后,我尝试使用addFirst()添加executionHandler,就像问题的答案中所描述的那样:在使用Netty的UDP服务器中丢失了大量UDP请求。但它们都不起作用。看来你是对的,每个端口只有一个线程。但对我来说,这毫无意义。。。看来这正是内蒂的设计风格。我必须添加我的“线程代码”来实现这样的行为,当我使用一个框架来处理具有数万亿选项的线程池时。。。我真不敢相信…你愿意把你的密码贴出来作为答案吗?我同意你的观点,即使只有一个接收端口,也可能有许多源,因此多线程不仅有意义,而且似乎对服务大量客户机是必要的。