说明
最近部署一个项目到centOS上时,项目启动运行,中间会卡住一段时间,将近2,3分钟。看日志没有报错。同样的包,在另外一台机子部署后启动又是正常的。
排查
百度了一圈。网上大部份都说random的原因, 我都照着改了,但是,依然很慢。
于是去问我们部门大大牛;大牛说你用jstack看一下日志了吗???我:…
没用过jstack调试工具;于是,又开始漫长的度娘了。
jstack调试
- 在程序启动之后,立即执行:
ps -aux|grep 程序名称
得到进程pid;
- 然后执行jstack命令,监控jvm状态:
jstack -l 进程id
jstack的日志大致如下:
卡住的时候关键log是一下这一段:
"main" #1 prio=5 os_prio=0 tid=0x00007f399000c800 nid=0x276a6 runnable [0x00007f39961e1000]
java.lang.Thread.State: RUNNABLE
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:929)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1324)
at java.net.InetAddress.getLocalHost(InetAddress.java:1501)
- locked <0x00000000fd466af8> (a java.lang.Object)
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:54)
at org.springframework.boot.system.ApplicationPid.<init>(ApplicationPid.java:45)
at org.springframework.boot.logging.LoggingSystemProperties.apply(LoggingSystemProperties.java:123)
at org.springframework.boot.logging.AbstractLoggingSystem.applySystemProperties(AbstractLoggingSystem.java:177)
at org.springframework.boot.logging.Slf4JLoggingSystem.loadConfiguration(Slf4JLoggingSystem.java:61)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:151)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:80)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:118)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:313)
at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:288)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at ctsi.riverchief.eureka.EurekaApplication.main(EurekaApplication.java:12)
Locked ownable synchronizers:
- None
"VM Thread" os_prio=0 tid=0x00007f3990256800 nid=0x276bb runnable
这个错误的原因是因为hosts和hostname不一致导致的;
解决方法
- 查看本机的hostname:
[zjsl@host-192-168-* etc]$ hostname
- 查看/etc/hosts文件内容:
[zjsl@host-192-168-* etc]$ cat /etc/hosts
这里就发现hosts文件真的没有配置本机的hostname映射;
- 往hosts里面添加一行到本机的hostname映射(需要root权限)
vi /etc/hosts
- 保存后,重启网络:
service network restart
重试项目启动,问题解决!!!
附:自动添加本机ip和hostname到hosts文件的脚本
#!/bin/bash
# 检查是否以root权限运行
if [ "$(id -u)" != "0" ]; then
echo "此脚本必须以 root 权限运行"
exit 1
fi
# 自动获取本地IP地址
IP_ADDRESS=$(ip addr show | grep 'inet ' | grep -v inet6 | awk '{print $2}' | cut -d "/" -f 1 | head -n 1)
# 获取当前主机名
HOSTNAME=$(hostname)
# 检查 hosts 文件中是否已有该条目
if grep -q "$IP_ADDRESS $HOSTNAME" /etc/hosts; then
echo "条目已存在,无需添加"
else
# 添加新的条目
echo "$IP_ADDRESS $HOSTNAME" >> /etc/hosts
echo "条目已添加至 /etc/hosts"
fi