宝塔部署tomcat项目,nginx负载均衡代理访问报错404问题
摘要: 服务器迁移后采用宝塔面板部署Tomcat项目时,遇到负载均衡代理访问404错误的问题。经排查发现,宝塔的Java项目域名管理会生成多个独立Host配置,每个Host对应不同的访问入口(IP/域名),但会话和上下文相互隔离。问题根源在于Nginx负载均衡配置未正确传递Host头,导致请求无法匹配Tomcat中的Host配置。解决方案:1)在宝塔中添加负载均衡使用的域名,生成对应Host配置;
一、问题背景
- 最近服务器到期,新买了服务器,尝试改变部署方式,从传统的tomcat自主部署转向宝塔可视化部署
- 宝塔部署了tomcat项目,IP访问可以,直接使用代理访问也可以,但使用负载均衡代理无法访问一直报错404
二、解决方案
宝塔Java项目的域名管理

- 可以设置IP和域名,不能重复
- 设置的IP和域名只能由它访问,我这里设置三个,开始的时候设置了一个IP,这时候tomcat配置文件会出现三个Host

-
配置中包含 3 个 <Host> 标签,每个 <Host> 标签内都配置了 1 个 <Context> 元素。在 Tomcat 架构中,<Context> 作为表示 Web 应用程序的核心单元。基于此配置,Tomcat 运行时将初始化 3 个独立的应用程序上下文。
-
3 个 <Context> 配置的 docBase 均指向 /www/wwwroot/你的应用 目录
-
该 Web 应用目录被同时挂载在三个不同域名(或 IP)下。具体表现为:无论用户访问 43.xx.xx.32、sunXXXvip 还是 suXXX.vip,展示的网站内容完全一致。尽管底层代码相同,但这三个应用在 JVM 中各自独立运行:会话(Session)默认互不共享(例如用户在 A 域名登录后,访问 B 域名仍需重新登录),且拥有独立的类加载器空间。当前部署状态:3 个独立应用实例(对应 3 个 Context),1 个物理代码目录,实现"一码多域名"的部署架构。
我的当时nginx配置
# 设置服务器组
upstream abackend {
server 172.XX.0.14:8084 max_fails=3 fail_timeout=30s;
server 43.XXX.XXX.35:8086 max_fails=3 fail_timeout=30s;
server 43.XXX.XX.32:8232 max_fails=3 fail_timeout=30s;
server 172.XXX.XXX.14:8086 max_fails=3 fail_timeout=30s;
least_conn;
keepalive 32;
keepalive_timeout 60s;
keepalive_requests 100;
}
server {
listen 443 ssl;
server_name sunXXX.vip;
client_max_body_size 100M;
ssl_certificate cert/sunXXX.vip.pem;
ssl_certificate_key cert/sunXXX.vip.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://abackend;
proxy_connect_timeout 2000s;
proxy_send_timeout 2000s;
proxy_read_timeout 2000s;
}
}
当时我的宝塔tomcat配置
<?xml version='1.0' encoding='utf-8'?>
<Server port="8098" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector connectionTimeout="20000" port="8232" protocol="HTTP/1.1" redirectPort="8490" />
<Engine defaultHost="localhost" name="Catalina">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" />
</Realm>
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt" />
</Host>
<Host autoDeploy="true" name="43.136.19.32" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false">
<Context crossContext="true" docBase="/www/wwwroot/sunshine1" path="" reloadable="true" />
</Host>
</Engine>
</Service>
</Server>
404问题
- 通过域名访问接口和页面都是404
- 通过IP访问,是正常的,并且通过非负载均衡也可以访问
- 非负载均衡Nginx设置如下
-
server { listen 443 ssl; server_name sunXXX.vip; client_max_body_size 100M; ssl_certificate cert/sunshine.zhonghuibao.vip.pem; ssl_certificate_key cert/sunshine.zhonghuibao.vip.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location / { proxy_pass http://43.XX.XX.13:8232; proxy_connect_timeout 2000s; proxy_send_timeout 2000s; proxy_read_timeout 2000s; } }
解决方案
- 增加使用的域名到java项目-域名管理

- 添加域名后,会出现新的Host,修改path=""
<Host autoDeploy="true" name="sunXXX.vip" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false"> <Context crossContext="true" docBase="/www/wwwroot/项目名称" path="" reloadable="true" /> </Host> - nginx添加请求头: proxy_set_header Host $host
location / { proxy_pass http://abackend; proxy_set_header Host $host; proxy_connect_timeout 2000s; proxy_send_timeout 2000s; proxy_read_timeout 2000s; }
三、总结
宝塔部署tomcat项目,至少会绑定一个域名,一开始我设置的IP,使用IP正常访问,并且非负载正常访问,误导解决了方向,使用各类AI工具解决都没有解决,最后通过理解每个Host作用,尝试探索出来了的,希望对你有帮助。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)