crontab java -jar --------- java.sql.SQLRecoverableException: 无法从套接字读取更多的数据
2018-01-18 10:21
489 查看
前阵子自己尝试用maven和mybatis写了一个小程序,本来是对业务系统的定时任务做监控的。
如果定时任务正常,就继续监控;如果定时任务没有正常写库,就发一个短信给我。
多么简单的需求,就是一个简单的读库操作。crontab里面定时执行一个java -jar,直接执行jar包,jar包代码直接读库,正常则继续;不正常则发短信。
结果倒好,隔三差五的误报警,简直被玩死。瞅来瞅去自己都快对报警短信麻木了。
准备分析这个问题的,结果去看crontab的系统日志,发现自己账户没有权限。但是crontab的定时监控脚本是自己写好保存并启动的。然后分析下来,觉得是因为直接-jar执行,没有跑在容器里面(如果是tomcat执行的话,就相当于跑在tomcat容器里面。log在tomcat里面可以看到)
自己改了一下代码,将原来代码里面的e.printStackTrace();改成了
这样至少可以把crontab的应用层面的log保留下来并自己查看了。观察了几天,发现报错都是下面这一种问题
在网上查了一些帖子,有人说是因为mybatis超时导致的,于是在config.xml中新增了
<settings>
<setting name="defaultStatementTimeout" value="720"/>
</settings>
参数设置,然后发现没有效果。
又有人讲是需要在DataSource段中新增
<property name="poolPingQuery" value="SELECT SYSDATE FROM dual" />
<property name="poolPingEnabled" value="true" />
经人指点,应该在DB操作前后打印准确的时间戳,通过时间方便查找问题。于是进行了打印,果然可以看到问题
按照网上的样例,自己写了一个Mybatis读取数据库的代码。如下:
try {
inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();
Map<String, Object> param = new HashMap<String, Object>();
param.put("codeA", jobName);
param.put("codeD", date);
System.out.println("Before DB access " + String.valueOf(new SimpleDateFormat("yyyyMMdd HH:mm:ss:SSS").format(new Date())));
tab = sqlSession.selectOne("com.lcd.cf.dao.ConsumeJournalDetailTabMapper.queryReturnCodeOfBatch",
param);
System.out.println("After DB access " + String.valueOf(new SimpleDateFormat("yyyyMMdd HH:mm:ss:SSS").format(new Date())));
} catch (Exception e) {
System.out.println("After DB access " + String.valueOf(new SimpleDateFormat("yyyyMMdd HH:mm:ss:SSS").format(new Date())));
System.out.println(e.toString());
} finally {
if (sqlSession != null) {
sqlSession.close();
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
System.out.println(e.toString());
}
}
}
测试下来功能实现了,但是实际跑这段代码发现问题如下:
生产上会连续多次读取多条数据,就是多次调用上面这段逻辑。
观察后台log发现:
20180201 19:30:01:704
Before DB access 20180201 19:30:02:036
Input args: {codeA=放款通知, codeD=20180201}
After DB access 20180201 19:30:58:065
Before DB access 20180201 19:30:58:116
Input args: {codeA=还款提醒1, codeD=20180201}
After DB access 20180201 19:30:58:146
Before DB access 20180201 19:30:58:181
Input args: {codeA=还款提醒2, codeD=20180201}
After DB access 20180201 19:30:58:221
Before DB access 20180201 19:30:58:265
Input args: {codeA=还款提醒3, codeD=20180201}
After DB access 20180201 19:30:58:292
Before DB access 20180201 19:30:58:325
Input args: {codeA=还款提醒4, codeD=20180201}
After DB access 20180201 19:30:58:361
Before DB access 20180201 19:30:58:399
Input args: {codeA=逾期提醒, codeD=20180201}
After DB access 20180201 19:30:58:446
Before DB access 20180201 19:30:58:479
Input args: {codeA=逾期提醒2, codeD=20180201}
After DB access 20180201 19:30:58:563
看时间打印,第一次读取,花了56s,而后面的每次读取都是不到1s就可以搞定。
为什么第一次会这么慢,后面快起来又是为啥?都是同样的逻辑。每次读取数据库都会关闭session的。后续的读库操作,不应该和前面的操作一样的开销吗?
最省事的解决方案是把读取数据库的超时报错调整一下。过两天看效果
如果定时任务正常,就继续监控;如果定时任务没有正常写库,就发一个短信给我。
多么简单的需求,就是一个简单的读库操作。crontab里面定时执行一个java -jar,直接执行jar包,jar包代码直接读库,正常则继续;不正常则发短信。
结果倒好,隔三差五的误报警,简直被玩死。瞅来瞅去自己都快对报警短信麻木了。
准备分析这个问题的,结果去看crontab的系统日志,发现自己账户没有权限。但是crontab的定时监控脚本是自己写好保存并启动的。然后分析下来,觉得是因为直接-jar执行,没有跑在容器里面(如果是tomcat执行的话,就相当于跑在tomcat容器里面。log在tomcat里面可以看到)
自己改了一下代码,将原来代码里面的e.printStackTrace();改成了
这样至少可以把crontab的应用层面的log保留下来并自己查看了。观察了几天,发现报错都是下面这一种问题
在网上查了一些帖子,有人说是因为mybatis超时导致的,于是在config.xml中新增了
<settings>
<setting name="defaultStatementTimeout" value="720"/>
</settings>
参数设置,然后发现没有效果。
又有人讲是需要在DataSource段中新增
<property name="poolPingQuery" value="SELECT SYSDATE FROM dual" />
<property name="poolPingEnabled" value="true" />
经人指点,应该在DB操作前后打印准确的时间戳,通过时间方便查找问题。于是进行了打印,果然可以看到问题
按照网上的样例,自己写了一个Mybatis读取数据库的代码。如下:
try {
inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();
Map<String, Object> param = new HashMap<String, Object>();
param.put("codeA", jobName);
param.put("codeD", date);
System.out.println("Before DB access " + String.valueOf(new SimpleDateFormat("yyyyMMdd HH:mm:ss:SSS").format(new Date())));
tab = sqlSession.selectOne("com.lcd.cf.dao.ConsumeJournalDetailTabMapper.queryReturnCodeOfBatch",
param);
System.out.println("After DB access " + String.valueOf(new SimpleDateFormat("yyyyMMdd HH:mm:ss:SSS").format(new Date())));
} catch (Exception e) {
System.out.println("After DB access " + String.valueOf(new SimpleDateFormat("yyyyMMdd HH:mm:ss:SSS").format(new Date())));
System.out.println(e.toString());
} finally {
if (sqlSession != null) {
sqlSession.close();
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
System.out.println(e.toString());
}
}
}
测试下来功能实现了,但是实际跑这段代码发现问题如下:
生产上会连续多次读取多条数据,就是多次调用上面这段逻辑。
观察后台log发现:
20180201 19:30:01:704
Before DB access 20180201 19:30:02:036
Input args: {codeA=放款通知, codeD=20180201}
After DB access 20180201 19:30:58:065
Before DB access 20180201 19:30:58:116
Input args: {codeA=还款提醒1, codeD=20180201}
After DB access 20180201 19:30:58:146
Before DB access 20180201 19:30:58:181
Input args: {codeA=还款提醒2, codeD=20180201}
After DB access 20180201 19:30:58:221
Before DB access 20180201 19:30:58:265
Input args: {codeA=还款提醒3, codeD=20180201}
After DB access 20180201 19:30:58:292
Before DB access 20180201 19:30:58:325
Input args: {codeA=还款提醒4, codeD=20180201}
After DB access 20180201 19:30:58:361
Before DB access 20180201 19:30:58:399
Input args: {codeA=逾期提醒, codeD=20180201}
After DB access 20180201 19:30:58:446
Before DB access 20180201 19:30:58:479
Input args: {codeA=逾期提醒2, codeD=20180201}
After DB access 20180201 19:30:58:563
看时间打印,第一次读取,花了56s,而后面的每次读取都是不到1s就可以搞定。
为什么第一次会这么慢,后面快起来又是为啥?都是同样的逻辑。每次读取数据库都会关闭session的。后续的读库操作,不应该和前面的操作一样的开销吗?
最省事的解决方案是把读取数据库的超时报错调整一下。过两天看效果
相关文章推荐
- Oracle ORA-3137[12333] 关闭的连接 java.sql.SQLRecoverableException: 无法从套接字读取更多的数据 _optim_peek_user_binds
- java.sql.SQLException: 无法从套接字读取更多的数据出现的原因
- Error querying database. Cause: java.sql.SQLException: 无法从套接字读取更多的数据
- java.sql.SQLException: 无法从套接字读取更多的数据
- java.sql.SQLException: 无法从套接字读取更多的数据
- java.sql.SQLException: 无法从套接字读取更多的数据
- java.sql.SQLException: 无法从套接字读取更多的数据
- java.sql.SQLException: 无法从套接字读取更多的数据
- 异常 java.sql.SQLException: 无法从套接字读取更多的数据
- Oracle java.sql.SQLException: 无法从套接字读取更多的数据
- java.sql.SQLException: 无法从套接字读取更多的数据(mybatis 插入时)
- minus 时 sql无法从套接字读取更多数据 错误 分页
- org.hibernate.util.JDBCExceptionReporter# 关闭的连接(或者无法从套接字读取更多数据)
- 使用Oracle SQL Developer提示无法从套接字获取更多数据如何解决
- 无法从套接字读取更多的数据
- 页面500,tomcat报错 oall8 处于不一致状态 无法从套接字读取更多数据
- oracle 无法从套接字读取更多的数据
- java 异常:无法从套接字获取更多数据
- [转]使用Oracle SQL Developer 17410 提示无法从套接字获取更多数据如何解决
- java.sql.SQLException: 无法转换为内部表示