解决UDP多线程并发和丢包问题

项目使用了Netty UDP,代码中设置了BossGroup线程数如下

private void start() {
        group = new NioEventLoopGroup(10, r -> {
            return new Thread(r, "server-worker-" + WORKER_THREAD_INDEX.incrementAndGet());
        });
        try {
            Bootstrap b = new Bootstrap()
                    .group(group)
                    .channel(NioDatagramChannel.class)
                    .handler(new ChannelInitializer() {
                        @Override
                        protected void initChannel(Channel channel) {
                            ChannelPipeline ch = channel.pipeline();
                            ch.addLast(new ServerChannelHandler());

                        }
                    });
            b.bind(9876).sync().channel().closeFuture().await();
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        } finally {
            group.shutdownGracefully();
        }
    }

但是压测后发现只有一个线程在处理请求,并不是想象中的10个线程并发处理。
debug发现ChannelContext中的Channel始终是同一个对象不是多个,而一个Channel只会被一个线程处理,因此需要在接收到请求后再放入到业务线程池处理。

并发数上来后发现有消息丢失,通过watch -d 'netstat -su' 发现UDP的packet receive errorsreceive buffer errors 同步增长,怀疑是内核缓存区太小应用层处理不过来导致的。通过调整如下参数解决:

sudo sysctl -w net.core.rmem_max=26214400
sudo sysctl -w net.core.wmem_max=26214400
sudo sysctl -w net.core.netdev_max_backlog=2000

如果要永久生效,需要在/etc/sysctl.conf中配置。
参考:https://blog.csdn.net/u011001084/article/details/79093393

项目中top命令发现CPU占用不高但是系统负载很高,排查发现是磁盘IO性能太差导致的。
具体为什么CPU使用率低而Load高 参考 https://developpaper.com/the-reason-of-low-cpu-utilization-and-high-load-take-a-look-at-this-article/#:~:text=Low%20CPU%20and%20high%20load%20means%20that%20there%20are%20too,or%20idle%20at%20this%20time.

你可能感兴趣的:(解决UDP多线程并发和丢包问题)