同一Tomcat实例部署两个WAR包分端口响应问题咨询
这个问题90%的概率不是WAR包本身的通用兼容问题,也不是Tomcat全局HTTPS配置问题,是单应用维度的配置/链路特殊规则导致的,按下面的点逐一排查就行:
应用本地残留的硬编码端口/协议规则
最常见的踩坑场景:第二个应用之前在这台服务器上单独配过8090 HTTP的访问规则,相关配置存在war包之外的外置配置路径(比如Spring Boot会优先加载jar/war包外config目录下的配置、Tomcat共享lib目录下的配置、应用工作目录下的自定义配置文件),你重新部署war包的时候这些外置配置不会被覆盖,里面硬写了server.port=8090、请求scheme必须为HTTP、非8090端口请求直接拦截/重定向到8090的规则。把同一个war包丢到其他服务器部署时,没有这些残留的旧配置,自然能正常支持443 HTTPS。
排查动作:清空webapps/path2的解压目录、Tomcat临时目录、work目录下和path2相关的缓存,再检查WEB-INF下的web.xml有没有配置security-constraint的传输规则,全局搜所有配置文件里有没有8090的硬编码值。Tomcat单应用级别的端口绑定配置
检查conf/server.xml配置,很多人会给单个应用配置独立的Context甚至独立的虚拟Host,如果path2对应的Context被挂载到了仅关联8090 HTTP连接器的虚拟Host下,而没有关联443的HTTPS连接器,就会出现只有8090端口能访问这个应用的情况。而path1挂载在默认的、同时关联了所有连接器的Host下,所以HTTP、HTTPS端口都能通。
排查动作:核对443端口对应的HTTPS连接器配置,看关联的虚拟Host列表里是否包含path2的部署路径,检查有没有给path2单独配置专属的连接器绑定规则。前置链路针对path2的特殊转发/拦截规则
如果Tomcat前面挂了Nginx、Apache反向代理,或者用了云负载均衡、服务器防火墙规则,很可能配置了路径维度的转发策略:/path1的请求正常转发到Tomcat 443 HTTPS端口,/path2的请求被强制转发到8090 HTTP端口,甚至直接配置了443端口下/path2路径的访问拦截。
排查动作:直接在服务器本地执行curl -k https://127.0.0.1:443/path2绕开所有外部链路测试,如果本地访问正常,问题100%出在前置代理、防火墙、安全组的路径规则上。单应用级别的访问控制阀门限制
Tomcat支持给单个应用配置独立的访问控制阀门,如果你在conf/Catalina/localhost/目录下存在和path2同名的独立配置文件,里面可能配置了端口维度的访问限制,比如只允许8090端口的请求通过,443端口的请求直接被阀门拦截返回403/404,看起来就像应用不响应443请求。
快速定位顺序
- 本地绕开代理直连Tomcat 443端口测path2,先区分是Tomcat内部问题还是外部链路问题
- 彻底清空path2相关的部署缓存、外置配置文件,重新用和其他服务器一致的干净war包部署,排除残留配置干扰
- 对比两个应用的Context配置、web.xml配置、框架配置的差异,重点找端口、协议、访问控制相关的规则
- 逐行核对server.xml里连接器、虚拟主机、应用路径的绑定关系,确认没有给path2加特殊限制
内容的提问来源于stack exchange,提问作者harrys

