You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何定位Java/Karaf应用收到的SIGALRM信号来源?

问题背景

我们有一个基于Karaf容器的Java应用,每5-6天会异常退出。经排查:

  • 未出现JVM OOM,GC日志显示内存正常且可正常回收
  • 未发生Linux系统OOM kill,dmesg及/var/log/messages中无相关日志
  • JVM未损坏,未生成hs_err或core文件

通过以下strace命令追踪应用:

nohup strace -tt -e trace=signal -p 7428 -o /tmp/app.strace >/dev/null 2>&1 &

得到的strace日志显示:

[root@admin ~]# cat /tmp/app.strace 
14:33:53.561413 +++ killed by SIGALRM +++

由于使用strace的-f选项会导致应用响应极慢、服务不可用,故未使用。现在需要确定:向该应用发送SIGALRM信号的程序是什么?

排查方法

1. 使用auditd追踪信号发送

auditd是系统级审计工具,对应用性能影响极小,适合生产环境:

  • 安装并启动auditd服务(根据系统发行版调整命令):
    # CentOS/RHEL
    yum install auditd -y
    systemctl start auditd
    systemctl enable auditd
    
  • 添加审计规则,仅追踪目标进程的SIGALRM信号:
    auditctl -a exit,always -F arch=b64 -S kill -F pid=7428 -F sig=14
    
    注:sig=14对应SIGALRM,32位系统替换arch=b32
  • 应用再次异常退出后,查看审计日志:
    ausearch -i -m kill -ts recent
    
    日志会明确显示发送信号的进程PID、PPID及进程名,直接定位发送者。

2. 用sysdig轻量实时监控

sysdig是低开销的系统追踪工具,可实时捕获信号发送行为:

  • 安装sysdig后,运行以下命令监控目标进程的SIGALRM:
    sysdig -p "%proc.name %proc.pid %evt.arg.signame" evt.type=kill and evt.arg.sig=14 and proc.pid=7428
    
    当有SIGALRM发送到目标进程时,会实时输出发送信号的进程名和PID。

3. 优化strace参数降低性能影响

若必须使用strace,可通过缩小追踪范围减少性能损耗:

  • 仅追踪SIGALRM相关信号操作,而非全信号:
    nohup strace -tt -e trace=signal -e signal=SIGALRM -p 7428 -o /tmp/app_sigalrm.strace >/dev/null 2>&1 &
    
    若应用子进程不多,可尝试-ff替代-f,将每个进程日志分开写入,避免单日志过大,同时尽量缩短追踪时长。

4. 排查应用内部触发可能

SIGALRM也可能是应用自身或依赖库触发的:

  • 检查Karaf及应用的定时任务配置,是否存在异常定时逻辑
  • 定期用jstack导出线程栈,分析是否有与定时、信号相关的线程异常(比如Java Timer/ScheduledExecutorService的异常,或JNI调用的原生代码发送信号)

内容的提问来源于stack exchange,提问作者Joey Sun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 22:00:13