【问题记录】JAVA进程启动大概率卡住6分钟左右,应用日志没有任何WARN ERROR,系统日志也没有发现和进程相关日志,最后定位TOMCAT SHA1PRNG耗时太长

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://xxlcube.blog.csdn.net/article/details/85111264

无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。

系统是基于springboot开发的系统,java -jar启动过程中发现经常会卡住6分钟左右,才能启动完成,全程没有发现任何WANR和ERROR级别的日志(其实早看看DEBUG和INFO日志,可能问题早就解决了,惯性思维害人啊),再去查看/var/log/message系统日志,也没发现任何和该进程相关的系统日志;

无奈,初步怀疑服务器虚拟机有问题,让运维排查下,也没发现任何异常;

将同样的jar包程序放到其它虚拟机上跑,也有卡顿,但是10秒,20秒的样子就结束了,虽然快了,但是也有卡顿,同样的排查还是没发现问题;

最后反复启停,反复查看,也是巧合在日志里有了发现,

[18-12-19 21:01:13:222][INFO ][org.apache.catalina.util.SessionIdGeneratorBase][localhost-startStop-1]Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [99,677] milliseconds.

 

发现了意外,这里耗时简直了

最后的解决方案就是在JVM启动参数里加上如下一串:

-Djava.security.egd=file:/dev/./urandom

在tomcat的wiki上也有解释 https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source

Tomcat 7+ heavily relies on SecureRandom class to provide random values for its session ids and in other places. Depending on your JRE it can cause delays during startup if entropy source that is used to initialize SecureRandom is short of entropy. You will see warning in the logs when this happens.

 

There is a way to configure JRE to use a non-blocking entropy source by setting the following system property: -Djava.security.egd=file:/dev/./urandom

 

在读取时,/dev/random设备会返回小于熵池噪声总数的随机字节。
/dev/random可生成高随机性的公钥或一次性密码本。
若熵池空了,对/dev/random的读操作将会被阻塞,直到收集到了足够的环境噪声为止

/dev/urandom则是一个非阻塞的发生器:

dev/random的一个副本是/dev/urandom (”unlocked”,非阻塞的随机数发生器),它会重复使用熵池中的数据以产生伪随机数据。
这表示对/dev/urandom的读取操作不会产生阻塞,但其输出的熵可能小于/dev/random的。
它可以作为生成较低强度密码的伪随机数生成器,不建议用于生成高强度长期密码。

https://bugs.openjdk.java.net/browse/JDK-6202721

另外wiki里也提到了为什么linux内核里的随机数生成器采用SHA1散列算法而非加密算法,是为了避开法律风险(密码出口限制)。

 

 

还有一篇文章专门解释/dev/urandom

https://www.2uo.de/myths-about-urandom/

 

最后总结下:

其实还是虚拟机的CPU差了点,跟其它环境的虚拟机10秒,20秒的差了几十倍,可见CPU差了很多啊。

 

 

 

展开阅读全文

存储过程调用不成功,没有记录任何的日志

11-29

我的存储过程如下:rnrnCREATE OR REPLACE PROCEDURE SP_INFO_ARCHIVErn ASrnrn C_LIMIT PLS_INTEGER := 1000;rn C_MAXDELNUM PLS_INTEGER := 10000;rn C_JOBNAME_ VARCHAR2(50) := 'SP_INFO_ARCHIVE';rn V_STEPNO_ NUMBER;rn V_DEAL_ROWCOUNT_ NUMBER;rn V_AFFECT_NUM_ PLS_INTEGER;rnrn CURSOR task_cur ISrn select c.taskid, c.plyno, c.regnorn from a_t_task c, m_t_trad trn where c.plyno = t.plynorn and t.enddate < (sysdate - interval '15' day)rn and t.validstatus = '1'rn and c.finished = '0'rn and c.validstatus = '1';rnrn CURSOR info_cur ISrn select n.id from a_t_info n where n.expired = '1';rnrn TYPE TaskIdList IS TABLE OF a_t_task.taskid%TYPE;rn TYPE InfoIdList IS TABLE OF a_t_info.id%TYPE;rn TYPE PlyNoList IS TABLE OF a_t_task.plyno%TYPE;rn TYPE RegNoList IS TABLE OF a_t_task.regno%TYPE;rnrn taskIds TaskIdList;rn nodeIds InfoIdList;rn plyNos PlyNoList;rn regNos RegNoList;rnrnBEGINrn --第一步:把没有结束的任务置为无效,把对应的信息置为expired='1'rn V_DEAL_ROWCOUNT_ := 0;rn OPEN task_cur;rn V_STEPNO_ := 0;rn LOOPrn FETCH task_cur BULK COLLECTrn INTO taskIds, plyNos, regNos LIMIT C_LIMIT;rn EXIT WHEN taskIds.COUNT = 0;rnrn FORALL i IN 1 .. taskIds.COUNTrn update a_t_inforn set expired = '1'rn where plyno = plyNos(i)rn and regno = regNos(i);rnrn FORALL i IN 1 .. taskIds.COUNTrn update a_t_taskrn set validstatus = '0'rn WHERE taskid = taskIds(i);rnrn COMMIT;rn V_DEAL_ROWCOUNT_ := V_DEAL_ROWCOUNT_ + taskIds.COUNT;rn END LOOP;rn CLOSE task_cur;rn --打日志rn SP_LOG(V_JOBNAME => C_JOBNAME_,rn V_STEPNO => V_STEPNO_,rn V_INDATE => SYSDATE,rn V_DEALTYPE => C_JOBNAME_,rn V_DEAL_DESC => '信息归档',rn V_SQLCODE => SQLCODE,rn V_SOURCE_TABLE => 'a_t_info',rn V_TARGET_TABLE => 'a_t_infohistory',rn V_DEAL_ROWCOUNT => V_DEAL_ROWCOUNT_,rn V_COMID => '00000000');rnrn --第二步:归档expired='1'的节点rn V_DEAL_ROWCOUNT_ := 0;rn OPEN info_cur;rn V_STEPNO_ := 1;rn LOOPrn FETCH info_cur BULK COLLECTrn INTO nodeIds LIMIT C_LIMIT;rn EXIT WHEN nodeIds.COUNT = 0;rnrn FORALL i IN 1 .. nodeIds.COUNTrn insert into a_t_infohistoryrn select * from a_t_info n where n.id = nodeIds(i);rnrn FORALL i IN 1 .. nodeIds.COUNTrn delete from a_t_info where id = nodeIds(i);rnrn COMMIT;rn V_DEAL_ROWCOUNT_ := V_DEAL_ROWCOUNT_ + nodeIds.COUNT;rn END LOOP;rn CLOSE info_cur;rn --打日志rn SP_LOG(V_JOBNAME => C_JOBNAME_,rn V_STEPNO => V_STEPNO_,rn V_INDATE => SYSDATE,rn V_DEALTYPE => C_JOBNAME_,rn V_DEAL_DESC => '信息归档',rn V_SQLCODE => SQLCODE,rn V_SOURCE_TABLE => 'a_t_info',rn V_TARGET_TABLE => 'a_t_infohistory',rn V_DEAL_ROWCOUNT => V_DEAL_ROWCOUNT_,rn V_COMID => '00000000');rnrn --第三步:删除创建时间为13个月前的信息数据rn V_DEAL_ROWCOUNT_ := 0;rn V_STEPNO_ := 2;rn LOOPrn delete from a_t_infohistory nrn where n.createtime < (sysdate - interval '13' month)rn and rownum < C_MAXDELNUM;rn COMMIT;rn V_AFFECT_NUM_ := SQL%ROWCOUNT;rn V_DEAL_ROWCOUNT_ := V_DEAL_ROWCOUNT_ + V_AFFECT_NUM_;rn EXIT WHEN V_AFFECT_NUM_ < (C_MAXDELNUM - 1);rn END LOOP;rnrn --打日志rn SP_LOG(V_JOBNAME => C_JOBNAME_,rn V_STEPNO => V_STEPNO_,rn V_INDATE => SYSDATE,rn V_DEALTYPE => C_JOBNAME_,rn V_DEAL_DESC => '信息归档',rn V_SQLCODE => SQLCODE,rn V_SOURCE_TABLE => 'a_t_info',rn V_TARGET_TABLE => 'a_t_infohistory',rn V_DEAL_ROWCOUNT => V_DEAL_ROWCOUNT_,rn V_COMID => '00000000');rnrnEXCEPTIONrn WHEN OTHERS THENrn ROLLBACK;rn --打日志rn SP_LOG(V_JOBNAME => C_JOBNAME_,rn V_STEPNO => V_STEPNO_,rn V_INDATE => SYSDATE,rn V_DEALTYPE => C_JOBNAME_,rn V_DEAL_DESC => '信息归档',rn V_SQLCODE => SQLCODE,rn V_SOURCE_TABLE => 'a_t_info',rn V_TARGET_TABLE => 'a_t_infohistory',rn V_DEAL_ROWCOUNT => V_DEAL_ROWCOUNT_,rn V_COMID => '00000000');rnrn IF task_cur%ISOPEN THENrn CLOSE task_cur;rn END IF;rnrn IF info_cur%ISOPEN THENrn CLOSE info_cur;rn END IF;rnEND SP_INFO_ARCHIVE;rnrna_t_task这张表大约500万条记录,a_t_info这张表也是大约500万条记录。这个存储过程每天调用一次,但是一直都没有调用成功,也没有打任何日志。请教各位Oracle达人为啥会出现这种情况。 论坛

log4j与tomcat启动日志问题

10-22

没有用log4j之前,用控制台启动tomcat时会有详细的启动日志,可是当我配置log4j时,tomcat的启动日志变得很少了,如下:rnlog4j:WARN No appenders could be found for logger (org.apache.catalina.startup.Embedded).rnlog4j:WARN Please initialize the log4j system properly.rn15672 INFO [main]- Tiles definition factory loaded for module ''.rn15687 INFO [main]- Loading validation rules file from '/WEB-INF/validator-rules.xml'rn15703 INFO [main]- Loading validation rules file from '/WEB-INF/validation.xml'rnrn16547 INFO [main]- Starting Coyote HTTP/1.1 on http-8080rn16859 INFO [main]- JK2: ajp13 listening on /0.0.0.0:8009rn16875 INFO [main]- Jk running ID=0 time=0/94 config=D:\Tomcat 5.0\conf\jk2.propertiesrn16922 INFO [main]- Server startup in 14454 msrn其中最后四行我在原来完整的启动日志中也有看到.rn我的相关文件如下:rnlog4j.properties文件:rnlog4j.rootLogger=info,A1rnlog4j.logger.myLogger=infornlog4j.appender.A1=org.apache.log4j.ConsoleAppenderrnlog4j.appender.A1.layout=org.apache.log4j.PatternLayoutrnlog4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%nrnrnInitServlet.java文件:rnimport ...rnpublic class InitServlet extends HttpServletrnrn public void init() throws ServletExceptionrn rn String path = getServletContext().getRealPath("/");rn String propfile = path + getinitParameter("propfile");rn PropertyConfigurator.configure(propfile);rn rnrnweb.xml文件rnrnrn initializerrn InitServletrn rn propfilern /WEB-INF/log4j.propertiesrn rn 1rnrn不知道我怎样才能让tomcat启动时看到和原来一样的完整的启动日志(在级别不改成debug的前提下),按照他的提示我好象没有为某logger配置好appender,而且该logger是tomcat start时用到的,但我没有用到其他的log配置文件,也没有找到tomcat系统的日志配置文件.rn另外,我想问,再我们没有安装log4j时,原来tomcat启动时它是靠什么打印日志的,应该不是log4j吧,我查看过org.apache.catalina.startup.Embedded源文件,它好像是用org.apache.commons.logging.Log来输出日志,他的相关配置文件在哪里?rn还有上述启动日志最后四行,在没有用log4j时,应该是用org.apache.commons.logging.Log来输出的,可是用了log4j后,又是用org.apache.log4j.Logger输出的,这是怎么一回事? 论坛

关于进程tomcat相关问题

06-22

单位一台服务器,用tomcat发布的BS系统,软件做了负荷分担,也就是同时开了2个tomcat窗口,系统进程可见2个"java.exe",form也是2个"Tomcat",现在问题是由于使用人数还在增加,现在已有1500多终端了,大约7-10天,tomcat会出错,重启form后正常,小弟想做一定时重启托盘小工具,将2个form每隔一定时间自动重启rnrn关闭java.exe过程如下:rn'杀指定进程rnPublic Function Kill_Process(ByVal strProcess As String) As BooleanrnOn Error GoTo err1rn Dim strComputer As String '本机系统rn Dim objWMIService As Object '系统运行进程对象rn Dim colProcessList '进程对象集rn Dim objProcess As Object '循环中单进程对象rn Dim lngProcess As Long '单进程对象的句柄rnrn strComputer = "."rn Set objWMIService = GetObject("winmgmts:" & "impersonationLevel=impersonate!\\" & strComputer & "\root\cimv2")rnSet colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where Name = '" & strProcess & "'")rnrnFor Each objProcess In colProcessListrn lngProcess = OpenProcess(PROCESS_TERMINATE, 0&, objProcess.ProcessId) rn Call TerminateProcess(lngProcess, 1&) rnNextrnrnKill_Process = Truern Exit Functionrnrnerr1:rn Err.Clearrn Kill_Process = FalsernEnd Functionrn这没有问题,rnrn'启动应用程序rnPublic Function begin_Pro(ByVal PRO_NAME As String) As BooleanrnOn Error GoTo err1rn Shell PRO_NAMErn begin_Pro = Truern Exit Functionrn rnerr1:rn Err.Clearrn begin_Pro = FalsernEnd Functionrnrn物理地址传参如下:rnE:\webserv\bin\tomcat1\startup.bat和E:\webserv\bin\tomcat3\startup.batrnrn这一步总是起不来,不知是什么原因?调其它.exe文件均正常rn不知是否是只杀java.exe进程,从而没完全结束tomcat相关进程造成startup.bat进不来,还是rn Shell "E:\webserv\bin\tomcat1\startup.bat"这个本身就有问题,或是kill java.exe运行这个过程时就有问题?rnrn后又试调同目录下的shutdown.bat下也没成功,小弟不是专业开发的,对tomcat也不是很明白,大家多多帮忙啊!先谢过 论坛

没有更多推荐了,返回首页