宝塔部署tomcat项目,nginx负载均衡代理访问报错404问题

一、问题背景

  • 最近服务器到期,新买了服务器,尝试改变部署方式,从传统的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配置
bash 复制代码
 # 设置服务器组
    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配置
bash 复制代码
<?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 &quot;%r&quot; %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设置如下
bash 复制代码
 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;
         }
      }
解决方案
  1. 增加使用的域名到java项目-域名管理

  2. 添加域名后,会出现新的Host,修改path=""

    bash 复制代码
    <Host autoDeploy="true" name="sunXXX.vip" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false">
            <Context crossContext="true" docBase="/www/wwwroot/项目名称" path="" reloadable="true" />
          </Host>
  3. nginx添加请求头: proxy_set_header Host $host

    bash 复制代码
     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作用,尝试探索出来了的,希望对你有帮助。

相关推荐
ictI CABL2 小时前
Linux环境下Tomcat的安装与配置详细指南
linux·运维·tomcat
鱼鳞_2 小时前
Java学习笔记_Day37(网络编程)
java·网络·笔记·学习
Metaphor6922 小时前
使用 Python 合并 PDF 文件
java·python·pdf
我是无敌小恐龙2 小时前
Java SE 零基础入门Day03 数组核心详解(定义+内存+遍历+算法+实战案例)
java·开发语言·数据结构·人工智能·算法·aigc·动态规划
甘露寺2 小时前
深入理解并发模型:从 Python 的 async/await 到 Java 的虚拟线程与线程池机制
java·开发语言·网络
HAWK eoni2 小时前
java进阶1——JVM
java·开发语言·jvm
HUGu RGIN2 小时前
Django视图与URLs路由详解
java
京师20万禁军教头2 小时前
29面向对象(中级)-继承
java