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

Glassfish部署的Java Servlet应用频繁无日志报错冻结崩溃(Proxy Error)排查求助

Glassfish部署的Java Servlet应用频繁无日志报错冻结崩溃(Proxy Error)排查求助

看起来你遇到的这个无明确日志线索的崩溃问题确实挺棘手的——从最初每15天偶发到现在几乎每天傍晚出现,肯定给日常运维带来了不少困扰。结合你的环境配置和报错现象,我整理了几个实际排查过类似问题的方向,供你参考:

一、优先排查Apache反向代理的连接超时配置

浏览器抛出的Proxy Error本质是Apache作为反向代理,和后端Glassfish的连接出现了异常中断。大概率是默认的代理超时时间太短,当Glassfish处理请求卡住时,Apache等待超时就直接返回了错误,而此时Glassfish可能还没来得及把错误写入日志。

你可以修改Apache的代理配置(比如/etc/apache2/mods-available/proxy.conf或者对应虚拟主机的配置文件),添加或调整以下参数:

ProxyTimeout 300  # 把超时时间从默认60秒调到300秒
ProxyBadHeader Ignore  # 忽略后端返回的异常头部,避免因此中断连接

修改后重启Apache服务生效,观察傍晚的报错是否有所缓解。

二、检查Glassfish的JVM内存与GC问题

虽然你设置了-Xmx1536m且每日自动重启,但傍晚出现问题很可能是白天业务量累积导致的内存碎片、GC停顿过长,甚至隐性OOM(JVM卡死来不及写入日志)。

1. 开启GC日志排查

在Glassfish的启动参数中添加GC日志配置(可以在domain.xml里找到JVM参数部分):

-Xloggc:/var/log/glassfish/gc.log 
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps 
-XX:+UseGCLogFileRotation 
-XX:NumberOfGCLogFiles=5 
-XX:GCLogFileSize=10M

傍晚出问题后,查看GC日志是否存在频繁Full GC、停顿时间过长(比如超过10秒)的情况,这会直接导致请求超时。

2. 修正PermGen配置(针对Java 8+)

你当前设置的-XX:MaxPermSize=384m在Java 8及以上版本是无效的——PermGen已经被Metaspace取代,建议替换为:

-XX:MaxMetaspaceSize=384m

如果元空间不足,会导致类加载失败,进而引发线程阻塞甚至JVM崩溃,且可能不会在常规日志中留下明确痕迹。

三、排查C3P0连接池与MySQL的配置冲突

你的Hibernate连接池配置存在几个可能导致阻塞的点:

  • 连接池大小超过MySQL限制:C3P0设置maxPoolSize=200,但MySQL默认的max_connections通常是151(可以通过show variables like 'max_connections';查看)。当C3P0申请的连接数超过MySQL允许的上限时,线程会卡在等待连接的状态,最终拖垮Glassfish。建议把maxPoolSize调整为不超过MySQLmax_connections的80%(比如120),留足管理员连接的余量。
  • 空闲超时与连接年龄的矛盾配置:maxIdleTime=1500(秒)和maxConnectionAge=1200(秒)的设置逻辑冲突——连接还没到空闲超时时间就被强制回收,会导致频繁创建销毁连接,增加数据库和应用的开销。建议保留其中一个参数,或者把maxConnectionAge调大到比maxIdleTime更长(比如1800秒)。
  • 连接重试后的异常处理:acquireRetryAttempts=7意味着连接失败后重试7次,若最终仍无法获取连接,会抛出异常。如果你的应用代码没有妥善处理这类异常,可能导致线程永久阻塞,进而耗尽线程池资源。

四、监控服务器资源瓶颈

傍晚通常是业务高峰,服务器的CPU、磁盘IO或网络带宽可能达到瓶颈:

  • 用htop实时监控CPU、内存使用率,看是否有进程占用过高资源;
  • 用iostat -x 1查看磁盘IO情况,若%util接近100%,说明磁盘IO已饱和;
  • 查看AWS CloudWatch的监控数据,确认傍晚时段的CPU使用率、磁盘IOPS、网络流量是否出现峰值;
  • 开启MySQL慢查询日志,排查是否有傍晚出现的慢SQL拖垮数据库,进而导致Glassfish请求超时。

五、检查Glassfish线程池配置

Glassfish默认的HTTP线程池大小可能无法应对傍晚的请求高峰,当线程池满了之后,新请求会进入等待队列,最终导致Apache那边超时。

你可以通过Glassfish管理控制台(默认4848端口)进入配置->线程池->http-thread-pool,查看当前线程数、等待队列长度。如果等待队列经常处于满载状态,建议调大max-thread-pool-size(一般设置为2*CPU核心数+1,你的服务器是2核,可先调到5试试,逐步增加到10-20)。

应急排查小技巧

当应用再次卡住时,不要立刻重启Glassfish,先执行以下命令获取关键快照:

  • jstack <glassfish_pid>:生成线程快照,查看是否存在死锁、阻塞的线程;
  • jmap -heap <glassfish_pid>:查看堆内存使用情况,确认是否存在内存溢出;
  • netstat -anp | grep <glassfish_pid>:查看Glassfish的网络连接状态,是否有大量TIME_WAIT或CLOSE_WAIT连接。

这些快照能帮你快速定位到具体是哪个环节出了问题,比盲目调整配置更有效。

备注:内容来源于stack exchange,提问作者EduOK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 09:34:53