服务重启一会就自动宕机?

现场突发问题排查与解决

问题描述

现象:服务重启后,5分钟就宕机,全部接口访问不通

排查过程

第一阶段:初步排查

问题发现

  1. 观察日志:发现查询数据库的地方一直不返回
  2. 日志问题:由于日志太多,不好观察,先增加日志

异常现象

  • 查询数据库需要一个小时才返回
  • 但是将 SQL 放到 Navicat 里面,立马返回
  • 目前不太好定位是什么原因

第二阶段:解决方案尝试

方案1:本地缓存(失败 ❌)

思路

  • 服务启动后先将数据缓存到本地缓存中
  • 查询走缓存,避免频繁查询数据库

为什么不用 Redis?

  • 因为目前服务没有 Redis
  • 引入 Redis 还需要加配置,太麻烦
  • 目前需要尽快恢复服务使用

结果

  • 改造完成,上线以为万无一失
  • 结果还是 5分钟宕机

方案2:去除锁和事务(失败 ❌)

分析:可能是因为服务中的锁导致

操作

  • 去除 synchronized
  • 去除事务注解 @Transactional
  • 去除读写锁

结果

  • 全都去掉后
  • 结果还是宕机

第三阶段:深度排查

使用 jstack 分析线程堆栈

命令

jstack pid > jstack.log

分析结果

image.png

  • 通过 jstack.log 发现问题
  • random 的问题

根本原因

问题代码

private static Random random;

static {
    try {
        random = SecureRandom.getInstanceStrong();
    } catch (NoSuchAlgorithmException e) {
        LOGGER.error("Exception:NoSuchAlgorithmException!");
    }
}

问题分析

SecureRandom.getInstanceStrong() 存在严重的阻塞问题

  1. 阻塞式随机数生成

    • 在 Linux 系统上使用 /dev/random
    • 这是一个阻塞式的随机数生成器
    • 当系统熵池不足时,会阻塞等待
  2. 高并发场景下的问题

    • 多个线程同时调用会导致严重的性能问题
    • 线程挂起数秒甚至数分钟
    • 最终导致服务宕机

最终解决方案 ✅

修改后的代码

private static Random random;

static {
    try {
        random = SecureRandom.getInstance("SHA1PRNG");
    } catch (NoSuchAlgorithmException e) {
        random = new SecureRandom();
        LOGGER.error("SHA1PRNG not available, using default SecureRandom");
    }
}

方案说明

使用 SHA1PRNG 算法

  • 使用非阻塞式的随机数生成算法
  • 避免依赖系统熵池
  • 性能更好,不会阻塞线程

降级策略

  • 如果 SHA1PRNG 不可用,使用默认的 SecureRandom
  • 记录错误日志,便于监控

结果

上线后,完美解决

  • 服务稳定运行,不再宕机
  • 所有接口正常访问
  • 数据库查询正常返回

经验总结

排查思路

  1. 观察日志:关注异常和慢查询
  2. 对比测试:服务查询慢,但直接查询快 → 排除数据库问题
  3. 逐步排查:先排查缓存、锁、事务等常见问题
  4. 深度分析:使用 jstack 分析线程堆栈

关键工具

工具 用途 命令
jstack 分析线程堆栈 jstack pid > jstack.log
日志 观察异常和慢查询 增加关键位置的日志
Navicat 验证 SQL 性能 直接执行 SQL

技术要点

SecureRandom 使用建议

场景 推荐方案 说明
高并发生成随机数 SecureRandom.getInstance("SHA1PRNG") 非阻塞,性能好
普通随机数 ThreadLocalRandom.current() 最快,线程安全
加密场景 new SecureRandom() 安全性最高
❌ 不推荐 SecureRandom.getInstanceStrong() 会阻塞,容易宕机

注意事项

⚠️ 避免使用 SecureRandom.getInstanceStrong()

  • 在生产环境中极易导致服务阻塞
  • 特别是在高并发场景下
  • Linux 系统上问题更严重

推荐做法

  • 使用 SHA1PRNG 或 ThreadLocalRandom
  • 增加日志记录,便于问题排查
  • 定期使用 jstack 监控线程状态

解决状态:✅ 已完美解决

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 现象 最近新增了一批服务器,运维反馈说,部署的tomcat启动很慢,但是没有报任何异常,启动后应用也能正常运行。正...
    leoss_H阅读 2,050评论 0 2
  • 现象 今天, 生产上的springboot 应用cpu 达到200%, 即占用了2核, 线上应用奔溃, 应用无法访...
    朱万宇阅读 3,193评论 2 2
  • 1、问题现象 tomcat启动时候,日志显示如下,生成sessionid耗费了72S,整个tomcat部署完成耗费...
    Lavanda_yang阅读 405评论 0 0
  • 本文档是身边一些朋友、技术大佬之前分享的一些笔记,记录了 Tomcat 优化方法,笔记较多而且比较杂乱,经过整理、...
    zwb_jianshu阅读 786评论 0 1
  • 本文主要介绍java里的一些随机函数实现与用法,也会附带介绍一些随机数知识。目前计算机实现的随机函数过程中,都是伪...
    疯狂的冰块阅读 3,060评论 0 1

友情链接更多精彩内容