Netty高并发下数据丢失问题与性能优化配置

一、Netty高并发下数据丢失问题分析处理

1、现象

客户端与服务端采用长连接通讯, 传输数据量不大情况下不会出现数据丢失,在大数据量高并发场景下,会出现极少数的数据丢失,存在偶发性。 仔细分析代码处理逻辑,并无问题,查看netty的配置以及编解码处理, 也没有问题。

2、定位

数据丢失可能在传输任何环节都会出现, 需要定位缩小排查范围。 在服务端整个流转环节上都加上日志: 解码器->数据接收->业务逻辑处理->数据发送->编码器,发现数据接收的数量与客户端发送的数量一致, 业务逻辑处理数与数据发送都一致,但编码器的编码数量不一致, 存在缺失。

3、分析

问题范围已经明确,需要知道什么原因导致发送与编码的数量不一致, 增加发送回调处理,监听失败异常:
请添加图片描述

发现报出堆外内存超出限制的异常:
在这里插入图片描述

这里堆外内存的大小和JVM设置的Xmx大小一致, 都为16G。说明发送数据量过大, 产生严重的堆积阻塞。检查代码,因为是查询hbase的历史数据,返回发送的数据量确实会很大,那么该如何处理? 很直接的方法,是直接增加内存, 但数据量如果再增长, 这种方式就很被动。 结合业务场景来看, 并不需要很强的实时性,那么可以在发送前做个检查判断, 如果水位线过高, 阻塞等待, 直到水位降低,再进行发送, 这样就不会导致积压过多消息, 由于内存不足而产生数据丢失的问题。 这种方式会降低性能吗? 如果网络没有瓶颈且接收端处理速度足够快,是不会产生影响。

4、解决

改造之前需要先了解Netty的高低水控制作用,ChannelOutboundBuffer 提供了高低水位线的配置,当buffer缓冲区大小超过高水位时,该Channel的isWritable状态为false变成不可发送; 当buffer缓冲区低于低水位线时,isWritable又会变回true,可以重新发送数据。 那么高低水位线该如何配置? 在Netty服务端初始化的时候进行配置:
在这里插入图片描述

接下来改造发送代码, 增加阻塞等待:
在这里插入图片描述

这样改造貌似没有问题, 但其实隐藏一个很大的坑, 如果客户端异常断开, 那么该channel会一直处于不可写的状态,占用服务端的处理线程,如果大量客户端中断,整个服务就会不可用,甚至造成崩溃的风险, 进一步改造:

在这里插入图片描述

增加channel的有效性判断,同时设定最大等待上限, 每次阻塞100毫秒, 总计30秒的等待时间,实际根据业务场景进行设定, 对于我们业务来讲,时间是足够。至此,服务端发送数据丢失的问题, 就已经成功解决。

二、Netty服务端性能优化配置

1、场景

适用大数据量,请求交互频繁的场景, 采用自定义的二进制数据结构进行传输。

2、服务端配置

1) 基础配置
在这里插入图片描述

bossGroup与workGroup如果没有特殊需要, 可以按默认配置。 TCP/IP 第三次握手的请求队列最大长度, 如果在TCP连接上没有丢包与阻塞, 不需要设置过大。

2) 高低水位与缓冲区设置

在这里插入图片描述
此配置可以支撑5~10M/S的数据处理, 如有更大数据量,可以适当调高些,但不能设置过大。

3)编解码等其他配置

在这里插入图片描述
为防止粘包/拆包问题,采用LengthFieldBasedFrameDecoder解码器, 偏移量根据自定义二进制数据结构进行设置。

3、编码与解码配置

1)编码配置

通过MessageToByteEncoder进行编码,为减少内存空间占用, 及时释放回收,可以将相关引用都设为null。
在这里插入图片描述

2) 解码配置

通过ByteToMessageDecoder进行解码, 最后调用discardReadBytes()方法,及时释放空间,减少内存占用。
在这里插入图片描述

4、业务处理异步化

Netty虽然有较高的性能, 但业务逻辑如果单线程处理, 仍可能出现阻塞,这时候开启采用线程池做业务逻辑处理, 保障性能最大化。

1)线程池定义:
在这里插入图片描述

2)线程池拒绝handler处理

这里是直接拒绝, 如果不想返回失败, 也阻塞, 等待重新加入线程池处理。
在这里插入图片描述

3) 在handle进行调用处理
在这里插入图片描述
业务逻辑异步处理完成之后,再通过DataHander中传入的ctxl通道上下文进行数据发送。

  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: Spring Boot是一种用于构建独立的、生产级的Spring应用程序的框架,而Netty是一个基于Java的异步事件驱动的网络应用框架。Spring Boot和Netty可以结合使用来实现高并发的网络应用。 首先,Spring Boot提供了一种简化和自动化配置的方式来快速构建应用程序。它可以帮助开发人员快速搭建基于Spring框架的应用程序,并提供了很多开箱即用的功能,如自动配置、自动化部署等。 而Netty是一个异步事件驱动的网络应用框架,它能够高效地处理多个并发连接,并实现高性能、高可靠性的网络应用。Netty提供了一种基于事件驱动的编程模型,充分利用了现代操作系统的异步IO机制,使得应用程序能够高效地处理大量的并发请求,同时保持低延迟和高吞吐量。 在使用Spring Boot和Netty构建高并发应用程序时,可以充分利用Netty的异步IO和事件驱动的特性,通过合理地设计和优化应用程序的架构和算法,来实现对大量并发连接的高效处理。同时,Spring Boot提供了一些方便的功能和工具,如集成Spring框架的依赖注入、AOP等,使得开发、测试和部署变得更加简单和高效。 总的来说,Spring Boot和Netty的结合可以帮助开发人员快速搭建高并发的网络应用程序。在设计和实现上,可以充分利用Netty的异步IO和事件驱动的特性,结合合理的架构和算法,来实现对大量并发连接的高效处理。而Spring Boot的自动化配置和便利性可以大大加快开发、测试和部署的速度,提高开发人员的生产力。 ### 回答2: Spring Boot是一个开源的Java框架,它简化了基于Spring的应用程序的搭建和部署过程。Netty是一个异步的事件驱动的网络应用程序框架,它能够快速开发高性能、高可靠性的网络服务器和客户端。 Spring Boot和Netty都是为了处理高并发场景而设计的。Spring Boot提供了一种简单的方式来开发并部署应用程序,并提供了一些特性,如自动配置、监视和管理,提高了开发效率。而Netty则专注于提供高性能的网络通信能力,通过使用事件驱动模型和异步非阻塞的I/O方式,可以支持海量的并发连接。 在Spring Boot中使用Netty可以实现高并发的需求。通过使用Netty的异步非阻塞I/O模型,可以同时处理大量并发请求,而不会因为一个请求的阻塞而影响其他请求的处理。此外,Netty提供了多种事件处理器和线程模型,可以根据实际需求进行灵活的配置和优化,提高系统的吞吐量和并发能力。 在实际应用中,可以将Spring Boot作为应用程序的框架,通过调用Netty提供的API来处理网络通信。通过合理的配置和优化,可以在高并发场景下实现系统的快速响应和稳定性。 总之,Spring Boot和Netty的结合可以实现高并发应用程序的开发和部署。通过利用Netty的高性能网络通信能力,并结合Spring Boot的自动配置和管理特性,可以提高系统的并发能力和稳定性,满足高并发场景下的需求。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦神-mirson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值