nginx

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > nginx > Nginx+Tomcat负载均衡集群

Nginx+Tomcat负载均衡集群详解

作者:YUNYINGXIA

这篇文章主要介绍了Nginx+Tomcat负载均衡集群,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、Tomcat 基础与单节点部署

(一)Tomcat 概述

名称由来:由 Sun 公司詹姆斯・邓肯・戴维森开发,后贡献给 Apache 软件基金会。因希望项目以能自我照顾的动物命名,最终定名为 “Tomcat”(公猫),其 Logo 也设计为公猫形象。早期项目名为 “Catalina”,故安装后可见许多相关目录和文件。

应用场景:免费开源的轻量级 Web 应用服务器,适用于中小型系统及并发用户不多的场合,是开发调试 JSP 程序的首选。虽具备处理 HTML 页面功能,但处理静态 HTML 能力不及 Apache 或 Nginx,通常作为 Servlet 和 JSP 容器运行于后端,与前端 Web 服务器(如 Apache、Nginx)及数据库配合工作。

(二)单节点部署案例

1. 案例环境

2. 实施准备

# 关闭防火墙
systemctl stop firewalld
setenforce 0

3. 安装 JDK

JDK(Java Development Kit)是 Java 语言的软件开发工具包,包含 JVM(Java 虚拟机),用于解释 Java 字节码,实现跨平台性。

JDK 版本需与 Tomcat 兼容,下载对应版本的 JDK 安装包并安装。

4. 查看 JDK 安装情况

java -version

若输出 Java 版本信息(如 “java version "1.8.0_171"”),则说明 JDK 已安装。

5. 安装配置 Tomcat

# 解压Tomcat安装包
tar xf apache-tomcat-9.0.8.tar.gz
# 移动并重命名文件夹
mv apache-tomcat-9.0.8 /usr/local/tomcat9

6. 启动 Tomcat

/usr/local/tomcat9/bin/startup.sh

启动后,默认监听 8080 端口,可通过以下命令查看端口监听情况:

netstat -anpt | grep 8080

7. 访问测试

在浏览器中输入 “http://192.168.10.101:8080/”,若出现 Tomcat 欢迎界面,则表示启动成功。

8. 关闭 Tomcat

/usr/local/tomcat9/bin/shutdown.sh

(三)Tomcat 目录与配置文件说明

主要目录

主配置文件 server.xml:

结构组成:由<Server>、<Service>、<Connector/>、<Engine>、<Host>、<Context>等元素构成。

关键配置:

(四)建立 Java Web 站点

创建站点目录

mkdir -pv /web/webapp1

创建测试页面 index.jsp

vim /web/webapp1/index.jsp

内容如下:

<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test1 page</title>
</head>
<body>
<%out.println("动态页面1,http://www.test1.com");%>
<div>静态页面的图片1</div><br><img src="logo.jpg">
</body>
</html>

修改 server.xml 配置

在<Host>元素中添加<Context>配置,将站点路径指向 /web/webapp1:

<Context docBase="/web/webapp1" path="" reloadable="true"/>

重启 Tomcat

/usr/local/tomcat9/bin/shutdown.sh
/usr/local/tomcat9/bin/startup.sh

访问测试

在浏览器中输入 “http://192.168.10.101:8080/”,应显示自定义的 JSP 页面内容。

二、Nginx+Tomcat 负载均衡与动静分离群集搭建

(一)案例分析

需求背景:单台 Tomcat 存在单点故障风险,且处理静态资源效率低。Nginx 具有高性能、低资源消耗的特点,可作为反向代理和负载均衡器,与 Tomcat 结合实现动静分离,提升站点性能和可靠性。

拓扑架构:Nginx 作为前端负载均衡器,负责处理静态资源请求和分发动态请求到后端 Tomcat 服务器(Tomcat1 和 Tomcat2)。

(二)案例环境

主机IP 地址操作系统应用
Tomcat1 服务器192.168.10.101OpenEuler24apache-tomcat-9.0.8
Tomcat2 服务器192.168.10.102OpenEuler24apache-tomcat-9.0.8
Nginx 服务器192.168.10.103OpenEuler24nginx-1.26.3

(三)Tomcat2 服务器配置

关闭防火墙(同 Tomcat1)

systemctl stop firewalld
setenforce 0

安装 JDK 和 Tomcat(版本与 Tomcat1 一致)

# 安装JDK(若未安装)
# 解压Tomcat安装包
tar xf apache-tomcat-9.0.8.tar.gz
# 移动并重命名
mv apache-tomcat-9.0.8 /usr/local/tomcat9

创建站点目录并配置

mkdir -pv /web/webapp1

修改 server.xml 中的<Context>配置,指向 /web/webapp1:

<Context docBase="/web/webapp1" path="" reloadable="true"/>

创建测试页面 index.jsp

vim /web/webapp1/index.jsp

内容如下:

<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test2 page</title>
</head>
<body>
<%out.println("动态页面2,http://www.test2.com");%>
<div>动态页面的图片2</div><br><img src="logo.jpg">
</body>
</html>

启动 Tomcat2 并测试

/usr/local/tomcat9/bin/startup.sh

在浏览器中输入 “http://192.168.10.102:8080/”,查看页面是否正确显示。

(四)Nginx 服务器配置

关闭防火墙

systemctl stop firewalld
setenforce 0

安装依赖软件包

dnf install -y gcc make pcre-devel zlib-devel openssl-devel perl-ExtUtils-MakeMaker

创建 Nginx 用户

useradd -M -s /sbin/nologin nginx

解压并安装 Nginx

tar zxf nginx-1.26.3.tar.gz
cd nginx-1.26.3
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-pcre
make && make install

配置 nginx.conf

vim /usr/local/nginx/conf/nginx.conf

在 http {} 块中添加负载均衡服务器列表:

upstream tomcat_server {
    server 192.168.10.101:8080 weight=1;
    server 192.168.10.102:8080 weight=1;
}

在 server {} 块中配置动静分离规则:

location ~ \.jsp$ {
    proxy_set_header HOST $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Client-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://tomcat_server;
}

location ~* \.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
    root /usr/local/nginx/html/img;
    expires 30d;
}

location / {
    root html;
    index index.html index.htm;
}

准备静态图片

mkdir /usr/local/nginx/html/img
cp /root/logo.jpg /usr/local/nginx/html/img

测试配置文件

/usr/local/nginx/sbin/nginx -t

启动 Nginx 服务

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

查看服务进程和端口

ps aux | grep nginx
netstat -anpt | grep nginx

(五)测试效果

  1. 静态页面测试:在浏览器中输入 “http://192.168.10.103/”,应显示 Nginx 默认的静态页面。
  2. 负载均衡测试:在浏览器中输入 “http://192.168.10.103/index.jsp”,不断刷新页面,应交替显示 Tomcat1 和 Tomcat2 的测试页面,表明负载均衡生效。

三、心得

通过 Nginx 与 Tomcat 的结合,实现了动静分离和负载均衡,提升了 Web 站点的性能、可扩展性和稳定性。Nginx 高效处理静态资源,减轻了 Tomcat 的压力,使其专注于动态请求处理。这种架构是现代 Web 应用优化的重要实践,适用于中小型网站及高并发场景的初步搭建。在实际生产环境中,还可进一步结合缓存机制、安全策略等,进一步提升系统的可靠性和用户体验。

四、Tomcat 核心组件解析

(一)Server 与 Service

Server

<Server port="8005" shutdown="SHUTDOWN">
  <!-- 包含多个Service -->
</Server>

Service

<Service name="Catalina">
  <Connector port="8080" protocol="HTTP/1.1" />
  <Engine name="Catalina" defaultHost="localhost">
    <!-- 虚拟主机配置 -->
  </Engine>
</Service>

(二)Connector:请求入口

功能与类型

典型 Co4nnector

关键配置参6数

(三)Eng1ine 与 Host:请求处理与虚拟主机

Engine

<Engine name="Catalina" defaultHost="localhost">
  <Host name="localhost" appBase="webapps">
    <!-- 具体Host配置 -->
  </Host>
</Engine>

Host(虚拟主机)

示例配置

<Host name="www.test.com" appBase="/data/webapps" unpackWARs="true" autoDeploy="true">
  <Context path="/app1" docBase="/data/webapps/app1" />
</Host>

(四)Context:Web 应用容器

功能

关键配置

(五)组件协作流程

请求链路

客户端请求 → Connector(接收) → Engine(路由) → Host(匹配虚拟主机) → Context(处理Web应用) → 返回响应

示例场景

用户访问http://www.test.com/app1/index.jsp

五、Nginx 负载均衡策略与优化

(一)负载均衡策略配置

轮询(默认)

upstream tomcat_server {
  server 192.168.10.101:8080;
  server 192.168.10.102:8080;
}

权重轮询(weight)

upstream tomcat_server {
  server 192.168.10.101:8080 weight=2;  # 处理2倍请求
  server 192.168.10.102:8080 weight=1;
}

IP 哈希(ip_hash)

upstream tomcat_server {
  ip_hash;
  server 192.168.10.101:8080;
  server 192.168.10.102:8080;
}

(二)健康检查机制

被动检查(默认)

upstream tomcat_server {
  server 192.168.10.101:8080 max_fails=2 fail_timeout=30s;
}

主动检查(第三方模块)

upstream tomcat_server {
  server 192.168.10.101:8080;
  check interval=5000 rise=2 fall=3 timeout=3000 type=http;
  check_http_send "GET /health HTTP/1.0\r\n\r\n";
  check_http_expect_1xx any;
}

(三)动静分离优化实践

静态资源缓存配置

location ~* \.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
  root /usr/local/nginx/html/img;
  expires 30d;  # 缓存30天
  add_header Cache-Control "public";
}

压缩优化

http {
  gzip on;
  gzip_types text/plain text/css application/json application/javascript text/html;
  gzip_comp_level 6;  # 压缩级别(1-9,默认6)
}

防盗链配置

location ~* \.(gif|jpg|jpeg|png)$ {
  valid_referers none blocked www.test.com test.com;
  if ($invalid_referer) {
    return 403;
  }
}

六、生产环境部署注意事项

(一)安全加固

端口与防火墙

用户权限

chown -R nginx:nginx /usr/local/nginx
chown -R tomcat:tomcat /usr/local/tomcat9

HTTPS 配置

server {
  listen 443 ssl;
  server_name www.test.com;
  ssl_certificate /path/to/cert.pem;
  ssl_certificate_key /path/to/key.pem;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384;
}

(二)性能调优

Nginx worker 进程优化

worker_processes 4;  # 假设4核CPU
events {
  worker_connections 10240;
}

Tomcat 线程池调整

<Connector port="8080" protocol="HTTP/1.1">
  <Executor name="tomcatExecutor" namePrefix="catalina-exec-"
            maxThreads="200" minSpareThreads="20" maxSpareThreads="50"
            maxQueueSize="100" />
</Connector>

连接超时优化

# Nginx配置
proxy_connect_timeout 5s;
proxy_read_timeout 10s;
proxy_send_timeout 10s;
# Tomcat配置(server.xml)
<Connector port="8080" connectionTimeout="20000" />

(三)监控与日志

Nginx 日志配置

开启访问日志和错误日志,记录详细请求信息以便排查问题:

http {
  access_log logs/access.log main;
  error_log logs/error.log error;
  log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                   '$status $body_bytes_sent "$http_referer" '
                   '"$http_user_agent" "$http_x_forwarded_for"';
}

Tomcat 日志分析

主要日志文件:

配置日志切割9,避免单文件过大:

# 使用logrotate工具
cat /etc/logrotate.d/tomcat
/usr/local/tomcat9/logs/*.log {
  daily
  rotate 7
  compress
  missingok
  notifempty
}

监控工具集成

使用 Prometheus+Grafana 监控 Nginx 和 Tomcat 的性能指标(如请求量、响应时间、服务器负载)。

Nginx 可通过ngx_http_stub_status_module暴露状态数据:

location /nginx_status {
  stub_status on;
  access_log off;
  allow 127.0.0.1;
  deny all;
}

七、常见问题与解决方案

(一)动态页面无法访问

排查步骤

查看日志

常见原因

(二)静态资11源加载失败

排查步骤

解决方案

修正rootalias路径,确保与实际文件路径一致(root为绝对路径,alias为自定义路径)。

赋予目录读权限:

chmod -R o+r /usr/local/nginx/html/img

(三)负载均衡未生效

排查步骤

常见原因

八、扩展与高可用架构

(一)增加 Tomcat 节点

步骤说明

新增 Tomcat 服务器(如 192.168.10.104),重复 “Tomcat2 服务器配置” 步骤,确保 JDK 和 Tomcat 版本一致,站点目录和测试页面配置正确。

修改 Nginx 的upstream配置,添加新节点:

upstream tomcat_server {
  server 192.168.10.101:8080 weight=1;
  server 192.168.10.102:8080 weight=1;
  server 192.168.10.104:8080 weight=1;  # 新增节点
}

Session 共享方案

问题背景:负载均衡场景下,若客户端请求被分发到不同 Tomcat 节点,未共享的 Session 会导致用户状态丢失。

解决方案

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
# 添加Maven依赖(Tomcat 9为例)
<dependency>
  <groupId>com.orangefunction</groupId>
  <artifactId>tomcat-redis-session-manager</artifactId>
  <version>2.0.3</version>
</dependency>

配置context.xml

<Context>
  <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve"/>
  <SessionHandler className="com.orangefunction.tomcat.redissessions.RedisSessionHandler"
                 host="192.168.10.105" port="6379" database="0" />
</Context>

(二)Nginx 高可用(主从 / 集群)

主从模式(Keepalived)

安装 Keepalived

dnf install -y keepalived

主节点配置(/etc/keepalived/keepalived.conf)

global_defs {
  router_id NGINX_MASTER
}
vrrp_instance VI_1 {
  state MASTER
  interface eth0  # 绑定网卡
  virtual_router_id 51  # 虚拟路由ID(主从一致)
  priority 100       # 主节点优先级(备用节点设为90)
  advert_int 1       # 心跳间隔(秒)
  authentication {
    auth_type PASS
    auth_pass 123456
  }
  virtual_ipaddress {
    192.168.10.200  # 虚拟IP
  }
}

备用节点配置:除state改为BACKUPpriority降低外,其余与主节点一致。

健康检查脚本:在 Keepalived 中配置脚本检测 Nginx 进程,若主节点 Nginx 停止,自动切换至备用节点:

script_check_nginx.sh:
#!/bin/bash
if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then
  systemctl stop keepalived
fi
vrrp_script check_nginx {
  script "/etc/keepalived/script_check_nginx.sh"
  interval 2
}

Nginx 集群(多节点负载均衡)

(三)日志集中管理

ELK Stack 方案

组件说明:

Nginx 日志输出到 Logstash

log_format json_log '{"time":"$time_iso8601",'
                    '"remote_addr":"$remote_addr",'
                    '"request":"$request",'
                    '"status":"$status",'
                    '"body_bytes_sent":"$body_bytes_sent",'
                    '"http_referer":"$http_referer",'
                    '"http_user_agent":"$http_user_agent"}';

access_log /usr/local/nginx/logs/access.json json_log;

Logstash 配置

input {
  file {
    path => "/usr/local/nginx/logs/access.json"
    type => "nginx"
    codec => json_lines
  }
}
output {
  elasticsearch {
    hosts => ["192.168.10.106:9200"]
    index => "nginx-%{+YYYY.MM.dd}"
  }
}

(四)自动化部署与监控

CI/CD 流程

使用 Jenkins 或 GitLab CI 实现代码自动构建、测试和部署:

Prometheus+Grafana 监控

采集指标

Prometheus 配置

scrape_configs:
  - job_name: "nginx"
    static_configs:
      - targets: ["192.168.10.103:80"]
  - job_name: "tomcat"
    static_configs:
      - targets: ["192.168.10.101:8009", "192.168.10.102:8009"]  # Tomcat JMX端口

九、成本优化与性能对比

(一)硬件资源规划

组件最低配置(开发环境)推荐配置(生产环境)
Nginx 服务器2 核 CPU,4GB 内存,50GB 磁盘4 核 CPU,8GB 内存,100GB SSD
Tomcat 服务器2 核 CPU,4GB 内存,100GB 磁盘4-8 核 CPU,16GB 内存,200GB SSD
数据库服务器4 核 CPU,8GB 内存,200GB 磁盘8 核 CPU,32GB 内存,500GB SSD

(二)性能对比(压测数据参考)

场景单 Tomcat 节点Nginx+Tomcat 集群(2 节点)
静态资源请求(RPS)5000+10000+
动态 JSP 请求(RPS)800-10001500-2000
内存占用800MB-1.2GB每 Tomcat 节点 800MB-1.2GB,Nginx 200MB

说明:

十、总结与最佳实践

(一)核心价值

(二)最佳实践清单

开发阶段

启用 Tomcat 的reloadable=true(仅开发环境),方便代码修改后自动重启。

使用 Nginx 的proxy_next_upstream配置,实现故障节点请求重试:

proxy_next_upstream error timeout http_500;

生产阶段

维护阶段

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文