前言
将SpringMVC项目从开发环境迁移到Linux生产环境是一个复杂的过程,涉及环境配置、应用部署、性能调优等多个环节。本文将详细介绍在Linux系统上部署SpringMVC项目的完整流程,并提供具体的代码示例和配置方案。通过本文的指导,您将能够独立完成SpringMVC项目的生产环境部署,并掌握常见问题的排查方法。
一、环境准备与基础配置
1. 系统选择与初始化
推荐使用CentOS 7或Ubuntu 18.04 LTS,执行系统初始化:
# CentOS系统初始化
yum update -y
yum install -y vim wget git net-tools ntp
systemctl enable ntpd
systemctl start ntpd
# Ubuntu系统初始化
apt update -y
apt upgrade -y
apt install -y vim wget git net-tools ntp
systemctl enable ntp
systemctl start ntp
# 关闭SELinux(CentOS)
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
# 配置系统时区
timedatectl set-timezone Asia/Shanghai
2. JDK安装与配置
# 下载并安装OpenJDK 11
yum install -y java-11-openjdk-devel # CentOS
apt install -y openjdk-11-jdk # Ubuntu
# 配置环境变量
echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64' >> /etc/profile
echo 'export PATH=$PATH:$JAVA_HOME/bin' >> /etc/profile
echo 'export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib' >> /etc/profile
source /etc/profile
# 验证安装
java -version
3. 创建专用用户
# 创建tomcat用户和组
groupadd tomcat
useradd -s /bin/nologin -g tomcat -d /opt/tomcat tomcat
# 设置目录权限
chown -R tomcat:tomcat /opt/tomcat
4. Tomcat安装与配置
# 下载并解压Tomcat 9
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.78/bin/apache-tomcat-9.0.78.tar.gz
tar -zxvf apache-tomcat-9.0.78.tar.gz -C /opt/
ln -s /opt/apache-tomcat-9.0.78 /opt/tomcat
# 修改端口(可选)
vim /opt/tomcat/conf/server.xml
# 将Connector端口改为8081(避免与80端口冲突)
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
# 优化Tomcat配置
vim /opt/tomcat/conf/context.xml
# 添加以下配置,防止内存泄漏
<Context antiResourceLocking="false" privileged="true">
<CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor"
sameSiteCookies="strict" />
</Context>
二、SpringMVC项目打包与部署
1. 项目配置调整
确保pom.xml
中配置为WAR打包:
<packaging>war</packaging>
<dependencies>
<!-- 移除嵌入式Tomcat依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- 添加servlet-api依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 添加Maven插件配置 -->
<build>
<finalName>your-project</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
2. 构建WAR包
# 在项目根目录执行Maven打包
mvn clean package -Dmaven.test.skip=true
# 生成的WAR包位于target目录下
ls target/*.war
3. 部署到Tomcat
# 停止Tomcat
/opt/tomcat/bin/shutdown.sh
# 备份原有应用(如有)
mv /opt/tomcat/webapps/your-project /opt/tomcat/webapps/your-project_backup_$(date +%Y%m%d%H%M)
# 复制WAR包到Tomcat的webapps目录
cp target/your-project.war /opt/tomcat/webapps/
# 调整权限
chown tomcat:tomcat /opt/tomcat/webapps/your-project.war
# 启动Tomcat
/opt/tomcat/bin/startup.sh
# 查看应用日志
tail -f /opt/tomcat/logs/catalina.out
三、生产环境配置优化
1. 数据库连接配置
创建独立的application-prod.properties
:
# 数据库连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/yourdb?useSSL=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=prod_user
spring.datasource.password=prod_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 连接池配置
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
# 日志配置
logging.level.root=INFO
logging.level.com.yourcompany=DEBUG
logging.file.name=/var/log/your-project/application.log
2. JVM参数优化
编辑/opt/tomcat/bin/catalina.sh
,添加JVM参数:
JAVA_OPTS="-server -Xms1024m -Xmx1024m -Xss512k -XX:MetaspaceSize=128m \
-XX:MaxMetaspaceSize=256m -XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/opt/tomcat/logs/heapdump.hprof \
-XX:+UseG1GC -XX:G1HeapRegionSize=4m -XX:MaxGCPauseMillis=50 \
-XX:+DisableExplicitGC -XX:+ParallelRefProcEnabled \
-Djava.security.egd=file:/dev/./urandom \
-Dspring.profiles.active=prod"
3. Tomcat性能优化
编辑/opt/tomcat/conf/server.xml
:
<Connector port="8081" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
maxThreads="500" minSpareThreads="50"
maxConnections="8192" acceptCount="100"
connectionTimeout="20000" redirectPort="8443"
compression="on" compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json" />
<!-- 配置线程池 -->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="500" minSpareThreads="50"
maxIdleTime="60000" prestartminSpareThreads="true"
maxQueueSize="100" threadPriority="5" />
四、Nginx反向代理配置
1. 安装Nginx
# CentOS
yum install -y epel-release
yum install -y nginx
systemctl enable nginx
systemctl start nginx
# Ubuntu
apt install -y nginx
systemctl enable nginx
systemctl start nginx
2. 配置反向代理
编辑/etc/nginx/conf.d/your-project.conf
:
upstream tomcat_backend {
server 127.0.0.1:8081 weight=1 max_fails=3 fail_timeout=30s;
keepalive 32;
}
server {
listen 80;
server_name example.com; # 替换为你的域名或IP
# 字符集设置
charset utf-8;
# 访问日志配置
access_log /var/log/nginx/your-project.access.log main;
error_log /var/log/nginx/your-project.error.log warn;
# 禁用不必要的HTTP头
server_tokens off;
# 安全相关配置
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
add_header Content-Security-Policy "default-src 'self'";
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 7d;
log_not_found off;
access_log off;
add_header Cache-Control "public, no-transform";
}
# 反向代理配置
location / {
proxy_pass http://tomcat_backend/your-project/;
proxy_http_version 1.1;
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;
proxy_set_header Connection ""; # 启用HTTP/1.1的keepalive
# 超时设置
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲区设置
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
# 大文件上传支持
client_max_body_size 100m;
}
}
3. 配置HTTPS(可选)
# 申请SSL证书(使用Certbot)
yum install -y certbot python3-certbot-nginx # CentOS
apt install -y certbot python3-certbot-nginx # Ubuntu
certbot --nginx -d example.com
# 修改Nginx配置,启用HTTPS
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# HSTS配置
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# 其他配置保持不变
...
}
# 重定向HTTP到HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
4. 重载Nginx配置
nginx -t # 检查配置文件语法
systemctl reload nginx
五、系统监控与日志管理
1. 应用监控配置
添加Spring Boot Actuator依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置application-prod.properties
:
# Actuator配置
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
# 自定义健康检查
management.health.db.enabled=true
management.health.redis.enabled=true
management.health.diskspace.enabled=true
# 指标配置
management.metrics.tags.application=your-project
management.metrics.export.prometheus.enabled=true
2. 日志管理配置
配置logback-spring.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATH" value="/var/log/your-project" />
<property name="APP_NAME" value="your-project" />
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 应用日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${APP_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APP_NAME}.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 错误日志文件 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${APP_NAME}_error.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APP_NAME}_error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 异步日志 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
<appender-ref ref="ERROR_FILE" />
<queueSize>5000</queueSize>
<discardingThreshold>0</discardingThreshold>
</appender>
<!-- 根日志配置 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC" />
</root>
<!-- 特定包日志级别 -->
<logger name="com.yourcompany" level="DEBUG" />
<logger name="org.springframework" level="INFO" />
<logger name="org.hibernate" level="INFO" />
</configuration>
3. 集成ELK日志系统(可选)
# 安装Logstash客户端
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
apt update && apt install logstash
# 配置Logstash
vim /etc/logstash/conf.d/your-project.conf
input {
file {
path => "/var/log/your-project/*.log"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
if [path] =~ "error" {
mutate { add_tag => ["error"] }
}
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} \[%{DATA:thread}\] %{LOGLEVEL:level} %{DATA:logger} - %{GREEDYDATA:message}" }
}
date {
match => ["timestamp", "yyyy-MM-dd HH:mm:ss"]
target => "@timestamp"
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "your-project-%{+YYYY.MM.dd}"
}
}
六、服务化与自动化部署
1. 创建Systemd服务
创建/etc/systemd/system/tomcat.service
:
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment=CATALINA_OPTS="-Xms1024m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m"
Environment=JAVA_OPTS="-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
User=tomcat
Group=tomcat
UMask=0007
# 自动重启配置
RestartSec=10
Restart=always
# 资源限制
LimitNOFILE=65536
LimitNPROC=65536
[Install]
WantedBy=multi-user.target
2. 服务管理命令
# 重载systemd配置
systemctl daemon-reload
# 启动服务
systemctl start tomcat
# 设置开机自启
systemctl enable tomcat
# 查看服务状态
systemctl status tomcat
# 查看服务日志
journalctl -u tomcat -f
3. 自动化部署脚本示例
#!/bin/bash
# 部署脚本:deploy.sh
APP_NAME="your-project"
TOMCAT_HOME="/opt/tomcat"
WAR_FILE="/path/to/your-project.war"
BACKUP_DIR="/opt/backup/${APP_NAME}"
# 创建备份目录
mkdir -p ${BACKUP_DIR}/$(date +%Y%m%d)
# 停止Tomcat
echo "Stopping Tomcat..."
systemctl stop tomcat
# 备份现有应用
echo "Backing up existing application..."
if [ -d "${TOMCAT_HOME}/webapps/${APP_NAME}" ]; then
tar -zcvf ${BACKUP_DIR}/$(date +%Y%m%d)/${APP_NAME}_$(date +%H%M%S).tar.gz ${TOMCAT_HOME}/webapps/${APP_NAME}
fi
# 删除旧的WAR文件和应用目录
echo "Removing old application..."
rm -rf ${TOMCAT_HOME}/webapps/${APP_NAME}*
# 部署新的WAR文件
echo "Deploying new application..."
cp ${WAR_FILE} ${TOMCAT_HOME}/webapps/${APP_NAME}.war
chown tomcat:tomcat ${TOMCAT_HOME}/webapps/${APP_NAME}.war
# 启动Tomcat
echo "Starting Tomcat..."
systemctl start tomcat
# 检查部署状态
echo "Checking deployment status..."
sleep 10
tail -n 50 ${TOMCAT_HOME}/logs/catalina.out
echo "Deployment completed!"
七、安全加固与故障排查
1. 防火墙配置
# CentOS使用firewalld
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-port=8081/tcp # 仅内部访问
firewall-cmd --reload
# Ubuntu使用ufw
ufw allow 80
ufw allow 443
ufw allow from 192.168.1.0/24 to any port 8081 # 限制内部访问
ufw enable
2. SSH安全配置
# 修改SSH端口
vim /etc/ssh/sshd_config
Port 2222 # 修改为非标准端口
PermitRootLogin no # 禁止root直接登录
PasswordAuthentication no # 禁用密码认证,使用密钥
AllowUsers deploy user1 # 限制允许登录的用户
# 重启SSH服务
systemctl restart sshd
3. 常见故障排查
# 查看Tomcat日志
tail -f /opt/tomcat/logs/catalina.out
# 查看系统资源使用情况
top
htop # 需先安装
# 检查端口占用
netstat -tulpn | grep 8081
lsof -i :8081
# 检查应用进程
ps -ef | grep tomcat
# 检查Nginx配置
nginx -t
# 检查系统日志
journalctl -xe
# 内存分析
jstat -gc <pid> 1000 # 每1秒显示一次GC情况
jmap -heap <pid> # 查看堆内存使用情况
jmap -dump:format=b,file=heapdump.hprof <pid> # 生成堆转储文件
# 线程分析
jstack <pid> > threaddump.txt # 生成线程转储文件
八、高可用架构设计
1. 负载均衡配置
upstream tomcat_cluster {
ip_hash; # 会话保持
server tomcat1.example.com:8081 weight=1 max_fails=3 fail_timeout=30s;
server tomcat2.example.com:8081 weight=1 max_fails=3 fail_timeout=30s;
server tomcat3.example.com:8081 weight=1 max_fails=3 fail_timeout=30s backup;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://tomcat_cluster/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 其他代理配置...
}
}
2. 会话管理方案
// 使用Spring Session集成Redis
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
// 配置application.properties
spring.session.store-type=redis
spring.redis.host=redis.example.com
spring.redis.port=6379
总结
Linux部署SpringMVC项目需要系统性的规划和实践,本文详细介绍了从环境准备到生产优化的完整流程,包括:
- 基础环境配置(JDK、Tomcat、Nginx)
- 项目打包与部署策略
- 生产环境参数优化
- Nginx反向代理与HTTPS配置
- 监控与日志管理方案
- 服务化与自动化部署
- 安全加固与故障排查方法
- 高可用架构设计
遵循这些步骤和最佳实践,能够构建出高性能、高可用的SpringMVC生产环境。关键是要根据实际业务需求调整配置参数,并建立完善的监控和应急响应机制。通过持续优化和自动化部署,可以大幅提高开发效率和系统稳定性。