abandon_mysql_使用Druid报错abandon connection, open stackTrace

在使用 Druid 数据源配合 Quartz 定时任务为会员增加积分时,遇到异常 'abandon connection, open stackTrace',该异常在执行积分日志保存时发生,经过30分钟后抛出。检查表结构、代码逻辑和 Druid 配置,发现异常可能是由于连接超时(removeAbandonedTimeout 配置为30分钟)导致。检查数据库服务器和应用服务器配置,2核16GB的服务器与4核8GB MySQL 实例应能支撑任务运行。排查方向包括代码是否持有连接过久、数据库连接池配置是否合理等。" 78370245,5246201,信息熵与相关概念详解:条件熵、互信息、相对熵、交叉熵,"['信息论', '熵', '交叉熵', '相对熵', '互信息']
摘要由CSDN通过智能技术生成

问题原由

最近使用

quartz

写了一个定时任务,这个定时任务主要是给会员增加类似积分的东西,并且要保存积分增加记录,每天凌晨4点钟执行,但是会有些时候会出现很多会员的积分并没有增加,查了一下日志,发现

Druid

抛出了

abandon connection, open stackTrace

,查看了一下报错的代码行,是在保存积分增加记录的时候抛出的异常,而且是等了30分钟才抛出的,也就是说,4点开始执行,然后4点半就抛异常了,导致用户的积分没有增加。

表结构

-- 用户会员信息表

create table client_vip_user_info

(

id                           varchar(36)      not null comment '主键'primary key,

user_id                      varchar(36)      null comment '用户编号',

had_stays                    int    default 0 not null comment '积分',

create_time                  datetime         null comment '创建时间(成为会员的时间)',

update_time                  datetime         null comment '更新时间',

deadline                     datetime         null comment '本期截止时间',

min_vip_level                varchar(36)      null comment '会员最低等级',

source                       varchar(20)      null comment '注册途径'

)comment '用户会员信息表';

-- 会员积分记录表

create table client_vip_stays_log

(

id          varchar(36) not null comment '主键' primary key,

userid      varchar(36) null comment '用户编号',

type        varchar(36) null comment '类型',

oldvalue    int         null comment '老数据',

incomevalue int         null comment '新添加的数据',

value       int         null comment '当前数据',

createtime  timestamp   null comment '创建时间'

)comment '会员积分操作日志';

相关代码

//定时器

public void execute(JobExecutionContext context) throws JobExecutionException {

//加载bean

LiveUserService liveUserService = (LiveUserService) AppContext.getSpringBean("liveUserService");

UserService clientUserService = (UserService) AppContext.getSpringBean("clientUserService");

VIPLevelService vipLevelService = (VIPLevelService) AppContext.getSpringBean("vipLevelService");

VipUserInfoService vipUserInfoService = (VipUserInfoService) AppContext.getSpringBean("vipUserInfoService");

VIPStaysLogService vipStaysLogService = (VIPStaysLogService) AppContext.getSpringBean("vipStaysLogService");

OrderService orderService = (OrderService) AppContext.getSpringBean("orderService");

try {

//获取前一天的日期

String yesterday = DateUtil.getYesterdayDate();

//获取当前日期前一天的入住人

List<Map<String, Object>> list = liveUserService.getLiveUsers(yesterday);

User user = null;

Order order = null;

for (Map<String, Object> map : list) {

user = clientUserService.findByPhone(map.get("PHONE").toString(), map.get("phoneareacode").toString());

if (null != user) {

VIPLevel vipLevel = vipLevelService.getByUserId(user.getUserID());

//是会员才会进行操作

if (null != vipLevel) {

//用户会员信息

VipUserInfo vipUserInfo = vipUserInfoService.getByUserId(user.getUserID());

int oldStays = vipUserInfo.getHadStays();

int newStays = oldStays + 1;

//间夜数变更日志

VipStaysLog vipStaysLog = new VipStaysLog();

vipStaysLog.setCreateTime(new Date());

vipStaysLog.setId(UuidUtil.get32UUID());

vipStaysLog.setOldValue(oldStays);

vipStaysLog.setIncomeValue(1);

vipStaysLog.setValue(newStays);

vipStaysLog.setUserId(user.getUserID());

vipStaysLog.setType("入住新增");

vipStaysLogService.save(vipStaysLog); //就是这一行抛出的异常

//省略代码

vipUserInfoService.update(vipUserInfo);

}

}

}

} catch (Exception e) {

LOGGER.error("-------------------error");

e.printStackTrace();

}

}

//mybatis

<!--表名 -->

<sql id="tableName">

`client_vip_stays_log`

</sql>

<!-- 字段 -->

<sql id="Field">

`id` ,

`userid` ,

`type` ,

`oldvalue` ,

`incomevalue` ,

`value` ,

`createtime`

</sql>

<!-- 字段值 -->

<sql id="FieldValue">

#{id} ,

#{userId} ,

#{type} ,

#{oldValue} ,

#{incomeValue} ,

#{value} ,

#{createTime}

</sql>

<insert id="save" parameterType="VipStaysLog">

INSERT INTO

<include refid="tableName"></include>

(

<include refid="Field"></include>

) VALUES (

<include refid="FieldValue"></include>

)

</insert>

相关配置

// 数据源配置

url:jdbc:mysql://localhost:3306/leyizhu?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8

driverClassName:com.mysql.jdbc.Driver

username:root

password:123456

filters:stat

maxActive:20

initialSize:1

maxWait:60000

minIdle:10

maxIdle:15

timeBetweenEvictionRunsMillis:60000

minEvictableIdleTimeMillis:300000

validationQuery:SELECT 'x'

testWhileIdle:true

testOnBorrow:false

testOnReturn:false

maxOpenPreparedStatements:20

removeAbandoned:true

removeAbandonedTimeout:1800

logAbandoned:true

环境配置

应用服务器

CPU: 2核

内存: 16 GB

实例类型: I/O优化

操作系统: Aliyun Linux 17.1 64位

独立数据库服务器

规格族:通用型    数据库类型:MySQL 5.6    CPU:4 核

数据库内存:8192MB    最大IOPS:5000    最大连接数:2000

可维护时间段:02:00-06:00     实例规格:rds.mysql.s3.large

错误日志

7f08df0faac2490583375f863486701b.png

目前我检查了代码很多遍,都没有发现代码哪里有问题,同事也没有看出来,目前已知的是为什么30分钟后才抛异常,是因为

removeAbandonedTimeout

设置的就是30分钟。如果主动获取连接,30分钟没有主动释放掉,druid就会自动释放掉,也就是说,代码停止了30分钟。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值