温馨提示×

Debian系统Tomcat如何实现负载均衡

小樊
38
2025-12-08 00:10:39
栏目: 云计算

在 Debian 上实现 Tomcat 负载均衡

方案一 Nginx 作为反向代理与负载均衡器

  • 安装组件
    • 执行:sudo apt update && sudo apt install nginx tomcat9 tomcat9-admin
  • 配置负载均衡
    • 编辑 /etc/nginx/sites-available/default/etc/nginx/nginx.conf 的 http 段,添加 upstream 与反向代理:
      upstream tomcat_servers {
          server 127.0.0.1:8080;
          server 127.0.0.1:8081;
          server 127.0.0.1:8082;
      }
      
      server {
          listen 80;
          server_name your_domain_or_ip;
      
          location / {
              proxy_pass http://tomcat_servers;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
          }
      }
      
  • 校验与生效
    • 执行:sudo nginx -t && sudo systemctl restart nginx
  • 说明
    • 多实例请确保各实例 HTTP 端口不同(如 8080/8081/8082),应用在各实例保持 一致版本与内容

方案二 Apache HTTP Server 作为负载均衡器

  • 安装组件
    • 执行:sudo apt update && sudo apt install apache2
  • 方式 A mod_proxy 与 HTTP
    • 启用模块:sudo a2enmod proxy proxy_http
    • 配置虚拟主机 /etc/apache2/sites-available/your-site.conf
      <VirtualHost *:80>
          ServerName your_domain.com
      
          ProxyPass / balancer://mycluster/
          ProxyPassReverse / balancer://mycluster/
      
          <Proxy balancer://mycluster>
              BalancerMember http://127.0.0.1:8080
              BalancerMember http://127.0.0.1:8081
          </Proxy>
      </VirtualHost>
      
  • 方式 B mod_proxy_ajp(基于 AJP)
    • 启用模块:sudo a2enmod proxy proxy_ajp
    • 配置示例:
      <VirtualHost *:80>
          ServerName your_domain.com
          ProxyPass / ajp://127.0.0.1:8009/
          ProxyPassReverse / ajp://127.0.0.1:8009/
      </VirtualHost>
      
  • 方式 C mod_jk
    • 安装模块:sudo apt install libapache2-mod-jk
    • 创建 /etc/apache2/workers.properties
      worker.list=tomcat1,tomcat2
      worker.tomcat1.type=ajp13
      worker.tomcat1.host=localhost
      worker.tomcat1.port=8009
      
      worker.tomcat2.type=ajp13
      worker.tomcat2.host=localhost
      worker.tomcat2.port=8109
      
    • 虚拟主机中挂载:JkMount /* tomcat1 或按需分发。
  • 生效
    • 启用站点:sudo a2ensite your-site.conf
    • 重启服务:sudo systemctl restart apache2

Tomcat 多实例与端口规划

  • 同一台机器运行多个实例时,修改 server.xml 中的关键端口避免冲突:
    • Server port(关闭端口):如 8005 / 8105
    • Connector port(HTTP):如 8080 / 8180
    • AJP Connector(如使用 AJP):如 8009 / 8109
    • redirectPort(重定向端口):如 8443 / 8543
  • 示例(第二个实例片段):
    <Server port="8105" shutdown="SHUTDOWN">
      <Service name="Catalina">
        <Connector port="8180" protocol="HTTP/1.1"
                   connectionTimeout="20000" redirectPort="8543" />
        <Connector port="8109" protocol="AJP/1.3" redirectPort="8543" />
      </Service>
    </Server>
    
  • 各实例的 webapps 保持相同应用与版本,便于会话一致性与灰度发布。

会话保持与集群复制

  • 为无状态或允许丢失会话的场景
    • 在 Nginx upstream 中为关键实例增加权重或被动健康检查(max_fails/fail_timeout),实现故障转移:
      upstream tomcat_servers {
          server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
          server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
      }
      
  • 为有状态会话的场景(Tomcat 内置集群)
    • 在每个实例的 server.xmlEngine 内加入 ,示例:
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
               channelSendOptions="8">
        <Manager className="org.apache.catalina.ha.session.DeltaManager"
                 expireSessionsOnShutdown="false"
                 notifyListenersOnReplication="true"/>
        <Channel className="org.apache.catalina.tribes.group.GroupChannel">
          <Membership className="org.apache.catalina.tribes.membership.McastService"
                       address="228.0.0.4" port="45564"
                       frequency="500" dropTime="3000"/>
          <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                    address="auto" port="4001"
                    selectorTimeout="5000" maxThreads="6" timeout="60000"/>
          <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
            <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
          </Sender>
          <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"
                        timeout="5000"/>
          <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filterValveClassName="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
          <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Channel>
      </Cluster>
      
    • 将应用配置为可分布式(如将 distributable 加入 web.xml),并确保各实例 应用内容一致

验证与运维建议

  • 验证分发与故障转移
    • 多次访问应用,结合日志或返回页脚(若输出实例标识)确认请求被分发到不同实例;停用某实例验证自动切换。
    • 使用 curl -I http://your_domain_or_ip 观察响应头与后端命中情况。
  • 日志与排错
    • Nginx:/var/log/nginx/access.log/var/log/nginx/error.log
    • Tomcat:/var/log/tomcat9/catalina.outlocalhost_access_log.*.txt
  • 安全与优化
    • 对外启用 HTTPS/TLS(在 Nginx/Apache 终止),对内可保持 HTTP 或启用 AJP;为集群开放必要端口(如 45564/4001 等),并限制来源网段。
    • 为静态资源设置缓存、开启压缩;根据并发调整 worker 进程/连接、Tomcat 线程池JVM 参数

0