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

Payara Micro在Kubernetes中随机未开放8080端口的排查求助

Payara Micro 6.2024.7-jdk21 随机未开放8080端口问题排查

环境与核心问题

  • 运行环境:DigitalOcean Kubernetes集群,使用镜像payara/micro:6.2024.7-jdk21
  • 核心问题:Pod内8080端口随机未开放,触发就绪探针失败导致容器重启;重启后恢复正常,无流量时也会随机出现该问题
  • 部署策略:蓝绿部署,HPA最小副本数设为2

已执行的测试与观察结果

  • 容器启动后立即执行netstat -tuln,无开放端口
  • Payara Micro启动后通常可见8080和6900端口,偶尔缺失8080
  • 日志中出现关键异常:
    1. 严重错误:
      SEVERE: Error adding HttpProbes. NetworkListener http-listeners GrizzlyProxy is NULL.
      
    2. 类加载相关细粒度错误:
      FINE: Failed to clear ResourceBundle references for web application [unknown]
      java.lang.NoSuchFieldException: loaderRef
          at java.base/java.lang.Class.getDeclaredField(Class.java:2782)
          at org.glassfish.web.loader.WebappClassLoader.clearReferencesResourceBundles(WebappClassLoader.java:2773)
          ...(省略重复栈轨迹)
      
      FINE: Method not found: clearProperties
      java.lang.NoSuchMethodException: jakarta.el.BeanELResolver.clearProperties(java.lang.ClassLoader)
          at java.base/java.lang.Class.getMethod(Class.java:2395)
          at org.glassfish.web.loader.CachingReflectionUtil.lambda$getMethodFromCache$1(CachingReflectionUtil.java:76)
          ...(省略重复栈轨迹)
      
  • 端口未开放时,应用仍显示部署成功:
    INFO: {
        "Instance Configuration": {
            "Host": "some-app-green-5768f94d4b-ct2n2",
            "Http Port(s)": "8080",
            "Https Port(s)": "",
            "Instance Name": "Poor-Flyingfish",
            "Instance Group": "MicroShoal",
            "Hazelcast Member UUID": "e4a1bcea-1da1-4952-92af-4d282b93dcb1",
            "Deployed": [
                {
                    "Name": "someapp",
                    "Type": "war",
                    "Context Root": "/app"
                }
            ]
        }
    }
    
  • Kubernetes环境检查:kubectl get networkpolicy -A无结果,事件日志仅记录就绪探针失败

相关配置信息

Dockerfile片段

FROM --platform=linux/amd64 payara/micro:6.2024.7-jdk21

COPY dist/ /opt/payara/deployments/
COPY conf/mysql-connector-j-8.2.0.jar /opt/payara/deployments/mysql-connector-j-8.2.0.jar
COPY conf/configure-datasource.sh /opt/payara/scripts/configure-datasource.sh

ENV JVM_ARGS="-XX:MaxHeapFreeRatio=50"

CMD ["--enableRequestTracing", "2", "--addjars", "/opt/payara/deployments/mysql-connector-j-8.2.0.jar", "--postbootcommandfile", "/opt/payara/scripts/configure-datasource.sh", "--deploy", "/opt/payara/deployments/someapp.war", "--contextroot", "/app", "--port", "8080", "--clustermode", "kubernetes:namespace-ns,backend-service"]

启动后脚本(configure-datasource.sh)片段

set configs.config.server-config.thread-pools.thread-pool.http-thread-pool.min-thread-pool-size=5 
set configs.config.server-config.thread-pools.thread-pool.http-thread-pool.max-thread-pool-size=350
set configs.config.server-config.thread-pools.thread-pool.thread-pool-1.min-thread-pool-size=3 
set configs.config.server-config.thread-pools.thread-pool.thread-pool-1.max-thread-pool-size=250

set configs.config.server-config.web-container.session-config.session-properties.timeout-in-seconds=432000

set-metrics-configuration --enabled=false

set configs.config.server-config.network-config.protocols.protocol.http-listener.http.cookie-same-site-enabled=true
set configs.config.server-config.network-config.protocols.protocol.http-listener.http.cookie-same-site-value=None
set configs.config.server-config.network-config.protocols.protocol.http-listener.http.compressable-mime-type=text/plain,text/html,text/xml,text/css,application/xml,application/xhtml+xml,application/rss+xml,application/javascript,image/svg+xml,application/json
set configs.config.server-config.network-config.protocols.protocol.http-listener.http.compression=on
set configs.config.server-config.network-config.protocols.protocol.http-listener.http.compression-level=6
set configs.config.server-config.network-config.protocols.protocol.http-listener.http.file-cache.enabled=true
set configs.config.server-config.network-config.protocols.protocol.http-listener.http.file-cache.max-age-seconds=3600
set configs.config.server-config.network-config.protocols.protocol.http-listener.http.file-cache.max-cache-size-bytes=52857600 
set configs.config.server-config.network-config.protocols.protocol.http-listener.http.file-cache.max-files-count=5000

可能的原因与解决方案

1. Grizzly网络监听器初始化竞态

日志中的NetworkListener http-listeners GrizzlyProxy is NULL是核心线索,说明Payara的Grizzly HTTP服务器初始化失败,导致8080端口未绑定。

  • 解决方案:
    • 升级Payara Micro版本:该版本可能存在初始化竞态bug,尝试升级到最新6.x稳定版,官方大概率已修复此类随机启动失败问题
    • 显式指定监听器绑定:在启动命令中添加--networkListener http-listener=0.0.0.0:8080,强制绑定端口,避免自动配置的不确定性
    • 调整启动顺序:将应用部署命令放在postboot脚本执行之后,或者在脚本中添加短暂延迟,避免配置修改与监听器初始化的冲突

2. JDK版本适配问题

日志中的类加载反射异常(NoSuchFieldException、NoSuchMethodException)表明JDK21与Payara内部类加载逻辑存在适配问题,间接影响监听器启动。

  • 解决方案:
    • 降级JDK版本:暂时切换到JDK17测试,确认是否是JDK21的兼容性问题
    • 禁用类加载器清理优化:通过JVM参数-Dorg.glassfish.web.loader.WebappClassLoader.clearReferences=false关闭类加载器清理逻辑,避免反射调用失败

3. Kubernetes资源竞争

K8s节点的CPU、内存波动可能导致Payara启动时初始化超时,监听器未完成绑定。

  • 解决方案:
    • 配置Pod资源请求与限制:为Pod设置合理的resources.requests.cpu、resources.requests.memory,避免启动时资源不足
    • 优化就绪探针:增加initialDelaySeconds(如设为60)和periodSeconds(如设为10),给Payara足够的启动时间,避免误判

4. 启动脚本配置冲突

postboot脚本中修改了多项HTTP监听器配置,可能与Payara Micro的默认初始化流程冲突。

  • 解决方案:
    • 简化启动脚本:逐步移除配置项,排查是否某一项配置导致监听器初始化失败(例如先移除文件缓存、压缩相关配置)
    • 使用静态配置文件:将配置项写入microprofile-config.properties或Payara的domain.xml片段,替代动态修改的postboot脚本,避免启动时的配置竞态

内容的提问来源于stack exchange,提问作者Pedro K-Lar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:12:03