今天工作收到一个问题是伊利的Resin服务器启动慢的问题。主要体现在启动服务的时间不稳定,但是起步是在30s起,最高的是可以达到59s.
- 以下就来分析是如何导致服务启动慢的。
步骤1:由于是第一次接触伊利的服务器,所以第一反应还是先去看伊利的resin.conf配置文件。里面给堆配置了8G的内存。这明显是够的,所以内存这方面的原因可以排除了。
步骤二:亲自尝试启动resin服务二到三次,看看是否符合问题的反馈描述。结果是的确是至少是三十秒起步才能启动服务。
步骤三:启动慢,没有其他原因,第一反应还是得抓启动线程啊。
那么是如何抓线程呢?
1. 使用jvm提供的Jstack命令打印线程栈信息。
2. 在resin启动的瞬间马上执行Jstack指令打印线程信息到某文件,而且需要多执行几次。这是手动不断的执行Jstack指令打印线程信息。
3. 分析线程日志信息,一般启动过程中都有一个main线程,在线程信息文件中,搜索关键字main.
4. 每个文件搜一下,大致就可以判断,main线程执行了多长时间,然后看main线程里面的信息,看里面是否有固定内容一直在执行
5. 如果没有发现什么异常,建议再次循环一下步骤,因为一次的数据可能是漏抓了。
自动抓取线程信息。
写一个脚本自动监听Resin服务的启动,输出线程信息
我采用的是自动脚本抓线程信息
是一秒抓一次的。
我们可以打开一个文件,搜索里面的main线程,果然找到了一个main线程,里面的信息如下:
main" prio=10 tid=0x0000000041a52800 nid=0x61d runnable [0x00007f50a69e2000] java.lang.Thread.State: RUNNABLE at oracle.jdbc.driver.NumberCommonAccessor.getBigDecimal(NumberCommonAccessor.java:2404) at oracle.jdbc.driver.NumberCommonAccessor.getObject(NumberCommonAccessor.java:6347) at oracle.jdbc.driver.T4CNumberAccessor.getObject(T4CNumberAccessor.java:288) at oracle.jdbc.driver.OracleResultSetImpl.getObject(OracleResultSetImpl.java:915) - locked <0x000000064187aa98> (a oracle.jdbc.driver.OracleResultSetImpl) at weaver.conn.RecordSet.parseResultSet(RecordSet.java:1500) at weaver.conn.RecordSet.executeSql(RecordSet.java:793) at weaver.conn.RecordSet.executeSql(RecordSet.java:341) at weaver.hrm.resource.ResourceComInfo.setResourceInfo(ResourceComInfo.java:314) at weaver.hrm.resource.ResourceComInfo.getResourceInfo(ResourceComInfo.java:106) at weaver.hrm.resource.ResourceComInfo.<init>(ResourceComInfo.java:82) - locked <0x000000064180b190> (a java.lang.Object) at weaver.workrelate.util.SendTaskEmail.<clinit>(SendTaskEmail.java:22) at weaver.workrelate.util.SendEmailInit.init(SendEmailInit.java:35) at com.caucho.server.dispatch.ServletConfigImpl.createServletImpl(ServletConfigImpl.java:830) at com.caucho.server.dispatch.ServletConfigImpl.createServlet(ServletConfigImpl.java:732) - locked <0x000000061a7fb0d8> (a com.caucho.server.dispatch.ServletConfigImpl) at com.caucho.server.dispatch.ServletManager.init(ServletManager.java:159) at com.caucho.server.webapp.WebApp.start(WebApp.java:1874) at com.caucho.server.deploy.DeployController.startImpl(DeployController.java:667) at com.caucho.server.deploy.StartAutoRedeployAutoStrategy.startOnInit(StartAutoRedeployAutoStrategy.java:72) at com.caucho.server.deploy.DeployController.startOnInit(DeployController.java:549) at com.caucho.server.deploy.DeployContainer.start(DeployContainer.java:160) at com.caucho.server.webapp.WebAppContainer.start(WebAppContainer.java:659) at com.caucho.server.host.Host.start(Host.java:450) at com.caucho.server.deploy.DeployController.startImpl(DeployController.java:667) at com.caucho.server.deploy.StartAutoRedeployAutoStrategy.startOnInit(StartAutoRedeployAutoStrategy.java:72) at com.caucho.server.deploy.DeployController.startOnInit(DeployController.java:549) at com.caucho.server.deploy.DeployContainer.start(DeployContainer.java:160) at com.caucho.server.host.HostContainer.start(HostContainer.java:484) at com.caucho.server.cluster.Server.start(Server.java:1319) at com.caucho.server.cluster.Cluster.startServer(Cluster.java:710) - locked <0x000000060eb35b38> (a com.caucho.server.cluster.Cluster) at com.caucho.server.cluster.ClusterServer.startServer(ClusterServer.java:542) at com.caucho.server.resin.Resin.start(Resin.java:703) at com.caucho.server.resin.Resin.initMain(Resin.java:1162) at com.caucho.server.resin.Resin.main(Resin.java:1365)
其中:
at weaver.conn.RecordSet.parseResultSet(RecordSet.java:1500) at weaver.conn.RecordSet.executeSql(RecordSet.java:793) at weaver.conn.RecordSet.executeSql(RecordSet.java:341) at weaver.hrm.resource.ResourceComInfo.setResourceInfo(ResourceComInfo.java:314) at weaver.hrm.resource.ResourceComInfo.getResourceInfo(ResourceComInfo.java:106) at weaver.hrm.resource.ResourceComInfo.<init>(ResourceComInfo.java:82) - locked <0x000000064180b190> (a java.lang.Object) at weaver.workrelate.util.SendTaskEmail.<clinit>(SendTaskEmail.java:22) at weaver.workrelate.util.SendEmailInit.init(SendEmailInit.java:35) at com.caucho.server.dispatch.ServletConfigImpl.createServletImpl(ServletConfigImpl.java:830) at com.caucho.server.dispatch.ServletConfigImpl.createServlet(ServletConfigImpl.java:732)
- 基本上每一段的main线程里面都有这么一段
- dispatch.ServletConfigImpl.createServletImpl 说明在创建一个servlet
- at weaver.workrelate.util.SendEmailInit.init(SendEmailInit.java:35) 说明SendEmailInit可能就是一个servlet,正在执行servlet的Init()方法
- 在该servlet的初始化过程中里面new了一个SendTaskEmail对象。
- 之后又在SendTasckEmail类的初始化过程中有new了一个ResourceComInfo,ResourceComInfo类的初始化过程中还行了该类的两个方法,说明ResourceComInfo可能是个全局变量。问题就是在这,容器启动过程中可以把这个类的初始化放置在哪里需要就在哪里new。