Netty 工作线程资源死锁问题分析

Posted 毕小宝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty 工作线程资源死锁问题分析相关的知识,希望对你有一定的参考价值。

背景

最近一个产品的开发工作告一段落,本文记录开发过程中遇到的几个印象深刻的问题。

数据库查询排序字段问题

问题一: 排序字段数据重复问题,有一个列表,按时间排序,但是有大量时间相同,导致不同页数据有重叠。

解决办法:分页查询处理按时间外,再加一个按主键排序的第二排序字段。

问题二: 排序字段有空值时,导致结果不稳定。
解决办法:避开空值,例如设置一个默认值,或者排序多加一列。

MyBatis 缓存问题

多模块开发中,有一个模块 A 只读数据库,它依赖另一个模块 B 对某张表进行修改。模块 A 启动时会读取数据库数据,同时用一个定时器查询最新值。

MyBatis 默认配置了缓存,导致模块 A 怎么都查不到最新数据。

解决办法:对于只读的模块,禁用缓存。配置为:

mybatis-plus:
  mapper-locations: classpath*:/mapper/*.xml
  configuration:
    # 开启驼峰命名规则自动转换
    map-underscore-to-camel-case: true
    # 本模块依赖其他模块操作数据库的数据,所以查询禁止缓存
    cache-enabled: false

RestTemplate 超时时间配置

多模块间服务调用时,需要考虑到目标服务器的处理时间,RestTemplate 读取超时时间应该远大于服务器处理的超时时间,保证服务端处理先超时,再返回。

Netty 工作线程资源死锁

有一个多模块通信流程如下:


A 下发数据给 NettyServer,它的 NIO 处理线程跟接收 B 响应的 NIO 线程是同一个,所以是顺次执行的。

而实际上前者依赖后者更新下发结果,A 下发线程得不到响应结果后超时返回,规则响应线程此时才能继续更新缓存中 B 的结果,但是已经晚了,形成了一种资源等待死锁现象。

解决办法:调整 A 发送的流程,调用 serviceB 下发和等待响应的逻辑放入新线程中处理,释放 NIO 工作线程资源。

事务嵌套子事务未提交问题


有一个嵌套事务,前提是不希望 serviceB 的数据随着 serviceA 的异常回滚,所以在 serviceB 上添加了Spring 的事务注解,开启新事务。

但是 serviceA 的步骤2依赖插入的数据,而查询操作不会触发 serviceB 上事务的提交,导数数据不一致问题。

这就引发了嵌套事务的提交问题,解决办法,去掉 serviceB 的事务,或者在 serviceB 中用 TransactionTemplate 显式执行事务,可以保证其写入操作及时提交。

以上是关于Netty 工作线程资源死锁问题分析的主要内容,如果未能解决你的问题,请参考以下文章

Netty classloader死锁问题及解决方案分享

多线程之死锁分析

怎么处理JAVA多线程死锁问题?

一个死锁问题的分析

Java多线程:并发死锁问题分析资源限制的挑战

多线程死锁阻塞问题分析