0
点赞
收藏
分享

微信扫一扫

【问题】【实用】java服务假死【CLOSE_WAIT】【线程WAITING】

问题排查步骤

检查是否服务异常(OOM)或GC异常

  1. 查看线程是否存活。

    ps -aux|grep xxx.jar
    
  2. 查看日志,并没有抛出异常,是否发生OOM。

    tail -1000f log.log
    

    JVM添加OOM时导出dump文件参数,可以采用jvisualvm等工具进行分析。

    -XX:+HeapDumpOnOutOfMemoryError//开启导出
    -XX:HeapDumpPath=./  //导出路径
    

    导出dump文件参数(直接复制版)

    -XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=./  
    
  3. 使用arthas查看是否死锁

    thread -b
    
  4. 使用arthas查看是否重复GC

    dashboard
    

    在JVM启动项中添加GC日志参数

    Xloggc:./gc‐%t.log //GC文件命名
    ‐XX:+PrintGCDetails  //展示GC细节
    ‐XX:+PrintGCDateStamps  //展示日期时间
    ‐XX:+PrintGCTimeStamps //展示小时时间
    ‐XX:+PrintGCCause //展示GC原因
    ‐XX:+UseGCLogFileRotation //开启GC文件输出
    ‐XX:NumberOfGCLogFiles=10 //GC文件最大总数量
    ‐XX:GCLogFileSize=100M //GC最大大小
    

    添加GC日志参数(直接复制版)

    Xloggc:./gc‐%t.log ‐XX:+PrintGCDetails ‐XX:+PrintGCDateStamps ‐XX:+PrintGCTimeStamps ‐XX:+PrintGCCause  ‐XX:+UseGCLogFileRotation ‐XX:NumberOfGCLogFiles=10 ‐XX:GCLogFileSize=100M
    

    GC日志可以用GC分析工具进行分析,如GCViewer【提取码:qqwb】,也可以使用GCEasy进行分析。

    个人调整链接

检查是否是JVM线程阻塞

  1. 查看与之关联的网络请求状态

    netstat -nat|grep 端口
    
  2. 查看是否为微服务内部阻塞,使用Jstack进行导出微服务线程执行以及状态

    jstack [PID] > jstack.log
    

    分析jstack.log,查询线程名称包含http的线程(包含http的线程名为外部访问的HTTP请求的线程,当然也可以自定义线程名字)

    "http-nio-9084-exec-1059" #18281 daemon prio=5 os_prio=0 tid=0x00007f951cc17000 nid=0x75de waiting on condition [0x00007f947d1cf000]
       java.lang.Thread.State: WAITING (parking)  //线程状态
        at sun.misc.Unsafe.park(Native Method) //阻塞方法,后面都为调用了链路
        - parking to wait for  <0x00000000802d02f7> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at org.apache.commons.pool2.impl.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:590)
        at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:425)
        at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:346)
        at redis.clients.util.Pool.getResource(Pool.java:49)
        at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
        at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnectionFromSlot(JedisSlotBasedConnectionHandler.java:70)
        at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:113)
        at redis.clients.jedis.JedisClusterCommand.runBinary(JedisClusterCommand.java:58)
        at redis.clients.jedis.BinaryJedisCluster.hget(BinaryJedisCluster.java:373)
        at org.springframework.data.redis.connection.jedis.JedisClusterHashCommands.hGet(JedisClusterHashCommands.java:95)
    

    解决阻塞问题即可。

网络上存在的其他情况或临时解决方法。

  • httpClientUtils工具类中未调用close方法,未指定超时等问题。
  • 针对暂未排除查出问题的,设置ipv4的超时,如果多个应用部署在同一个服务器,可能存在使用ipv6协议。
    修改/etc/sysctl.conf 文件
    # 禁用整个系统所有接口的IPv6
    net.ipv6.conf.all.disable_ipv6 = 1
    # 禁用某一个指定接口的IPv6(例如:eth0, lo)
    net.ipv6.conf.lo.disable_ipv6 = 1
    net.ipv6.conf.eth0.disable_ipv6 = 1
    # 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间
    net.ipv4.tcp_fin_timeout = 3 
    # 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟
    net.ipv4.tcp_keepalive_time = 1200 
    # 表示开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
    net.ipv4.tcp_syncookies = 1  
    # 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
    net.ipv4.tcp_tw_reuse = 1 
    # 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
    net.ipv4.tcp_tw_recycle = 1  
    # 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
    net.ipv4.ip_local_port_range = 1024    65000 
    # 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
    net.ipv4.tcp_max_syn_backlog = 8192 
    # 表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为5000。
    net.ipv4.tcp_max_tw_buckets = 5000  
    
    可以临时使用,不建议长时间使用,只是降低了发生概率而已,并没有彻底解决问题。

网络阻塞异常

  • 直接测试网络ip

    ping [ip]
    
  • 测试网络端口

    telnet ip port
    
  • 使用postman直接测试端口

举报

相关推荐

0 条评论