zoukankan      html  css  js  c++  java
  • 解决centos下tomcat启动太慢 & JDBC连接oracle太慢的问题

    近期遇到一个非常奇怪的问题,也不知道改了什么,tomcat启动非常慢,以前几秒就启动好了,现在要30秒左右。

    而且,通过jdbc连接oracle数据库也非常慢,以前建立一个连接只要几十毫秒,现在也要10秒左右。

    折腾了好几天,终于解决了,记录下来,帮助大家少走弯路。

    遇到这个问题时,最初以为是random策略问题,以前遇到过,通过修改随机数策略可以解决,参照我的这篇文章:

    https://www.cnblogs.com/lavezhang/p/6106356.html

    但是,修改后发现问题没有解决,只能继续排查。

    怀疑是jdk自动寻找proxy的问题,于是设置ProxySelector.setDefault(null),还是没有解决。

    怀疑是tomcat版本问题,从tomat8到tomcat8.5,到tomcat9,都试了一遍,还是没解决。

    怀疑是jdk的问题,从openjdk换成了oraclejdk,还是没解决。

    最后,这种疑难问题,还是依赖Tomcat堆栈数据来分析。

    于是导出tomcat堆栈信息

    > pgrep java

    > 21257

    > jstack 21257 > thread_data1

    注意:默认通过yum安装的是openjdk,没有jstack这个工具,得安装特殊的包才有,办法去网上搜吧。

    最简单的办法是,直接换成oracle jdk,因为openjdk的jstack工具有坑!

    开始分析堆栈数据,发现tomcat启动,以及Oracle连接,都是卡在一个地方:

    "main" #1 prio=5 os_prio=0 tid=0x00007f812000a000 nid=0x5813 runnable [0x00007f8126dee000]
    java.lang.Thread.State: RUNNABLE
    at java.net.Inet4AddressImpl.getLocalHostName(Native Method)
    at java.net.InetAddress.getLocalHost(InetAddress.java:1474)
    at sun.management.VMManagementImpl.getVmId(VMManagementImpl.java:140)
    at sun.management.RuntimeImpl.getName(RuntimeImpl.java:59)
    at org.springframework.boot.system.ApplicationPid.getPid(ApplicationPid.java:55)
    at org.springframework.boot.system.ApplicationPid.<init>(ApplicationPid.java:46)

    ------------------------------------------------------------------------------------------

    "http-nio-8082-exec-4" #23 daemon prio=5 os_prio=0 tid=0x00007fa7fc77a800 nid=0x5438 runnable [0x00007fa7b97d1000]
    java.lang.Thread.State: RUNNABLE
    at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928)
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323)
    at java.net.InetAddress.getLocalHost(InetAddress.java:1500)
    - locked <0x0000000688fca748> (a java.lang.Object)
    at oracle.jdbc.driver.T4CTTIoauthenticate.setSessionFields(T4CTTIoauthenticate.java:1118)
    at oracle.jdbc.driver.T4CTTIoauthenticate.<init>(T4CTTIoauthenticate.java:265)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:579)
    at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:666)
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:566)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)

    查了一下,这行代码是检索/etc/hosts文件,获取当前机器名对应的IP地址,如果没有明确配置机器名和IP的映射关系,就会在这里卡10秒左右,其实就是在局域网内去ping了。

    打开/etc/hosts,果然没有配置,赶紧补上,如下:

    > vi /etc/hosts

    127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 prd_web1
    ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 prd_web1

    其中,prd_web1就是手工设置的机器名。

    至此,问题得以解决!

    总结,走了很大一段弯路,其实对于这种程序卡死的现象,最佳解决方案就是分析tomcat堆栈,其它办法都是靠猜测,不靠谱。

    另外,这个现象并不是在所有机器上都存在,在有些机器上,即使没有在hosts文件中配置自定义hostname的映射,程序也会正常运行,可能是jdk内部还依赖别的环境配置吧,这个等待其它小伙伴去探究。

  • 相关阅读:
    彻底理解Netty
    linux netstat 统计连接数查看
    log4j2 自动删除过期日志文件配置及实现原理解析
    Log4j2的Policy触发策略与Strategy滚动策略配置详解
    @Accessors
    Caffeine Cache实战
    ws协议与http协议的异同
    深入理解Java:注解(Annotation)自定义注解入门
    java日志框架
    springboot 集成J2Cache
  • 原文地址:https://www.cnblogs.com/lavezhang/p/11891855.html
Copyright © 2011-2022 走看看