目录
- 核心概念:Linux + Java Web 是如何工作的?
- 环境准备:在 Linux 上安装 JDK 和构建工具。
- Web 应用开发:使用 Spring Boot 快速创建项目。
- Web 服务器/应用服务器:Tomcat vs. Spring Boot 内嵌服务器。
- 部署流程:如何将应用打包并部署到 Linux 服务器。
- 生产环境运维:进程管理、日志、监控。
- 高级主题:容器化、反向代理、性能调优。
- 总结与最佳实践。
核心概念
在 Linux 上运行 Java Web 应用,通常涉及以下几个核心组件:

- Linux 操作系统:提供稳定、高性能的运行环境。
- JDK (Java Development Kit):提供 Java 运行时环境和开发工具,是运行 Java 程序的基础。
- Web 服务器 / 应用服务器:
- Web 服务器 (如 Nginx, Apache):主要负责处理静态资源(HTML, CSS, JS, 图片)和反向代理,它像一个“门卫”,接收所有 HTTP 请求,然后将动态请求(如
.jsp,.do)转发给应用服务器。 - 应用服务器 (如 Tomcat, Jetty):负责执行 Java 代码,处理业务逻辑,并生成动态内容,它是 Java Web 应用的“引擎”。
- Web 服务器 (如 Nginx, Apache):主要负责处理静态资源(HTML, CSS, JS, 图片)和反向代理,它像一个“门卫”,接收所有 HTTP 请求,然后将动态请求(如
- Java Web 应用:你的业务代码,通常被打包成 WAR (Web Application Archive) 文件或 JAR (Java Archive) 文件(Spring Boot 方式)。
- 数据库 (如 MySQL, PostgreSQL):存储应用数据。
一个典型的请求流程:
用户浏览器 -> [Nginx (Web服务器)] -> [Tomcat (应用服务器)] -> [MySQL (数据库)]
| (静态资源) | (动态请求)
V V
直接返回 处理并返回动态HTML
环境准备
在 Linux 服务器上,首先需要安装 JDK 和构建工具(如 Maven)。
1 安装 JDK
推荐使用 OpenJDK,它是 Oracle JDK 的开源实现,完全免费且广泛使用。
以 Ubuntu/Debian 为例:
# 更新软件包列表 sudo apt update # 安装 OpenJDK 17 (LTS版本,推荐) sudo apt install openjdk-17-jdk # 验证安装 java -version javac -version
以 CentOS/RHEL 为例:
# 安装 EPEL 仓库 (如果还没有) sudo yum install -y epel-release # 安装 OpenJDK 17 sudo yum install -y java-17-openjdk-devel # 验证安装 java -version javac -version
配置环境变量 (可选但推荐)
系统通常会自动配置好 JAVA_HOME,但手动配置可以避免一些问题。
编辑 ~/.bashrc 或 /etc/profile 文件:
# 查找 JDK 安装路径,通常是 /usr/lib/jvm/java-17-openjdk-amd64 # 设置 JAVA_HOME export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 export PATH=$JAVA_HOME/bin:$PATH # 保存后,使配置生效 source ~/.bashrc # 或者对于系统用户 source /etc/profile
2 安装 Maven
Maven 是一个项目管理和构建自动化工具,用于管理项目依赖、编译代码、打包等。
以 Ubuntu/Debian 为例:
sudo apt install maven
以 CentOS/RHEL 为例:
sudo yum install maven
验证安装:
mvn -version
Web 应用开发 (以 Spring Boot 为例)
现代 Java Web 开发,Spring Boot 是绝对的主流,它极大地简化了配置,并内置了应用服务器(如 Tomcat)。
1 创建 Spring Boot 项目
最简单的方式是使用 Spring Initializr 网站。
- 访问 start.spring.io。
- 选择:
- Project:
Maven Project - Language:
Java - Spring Boot: 选择一个稳定版本 (如 3.x.x)
- Project Metadata: 填写 Group, Artifact, Name 等。
- Dependencies: 添加
Spring Web(用于创建 Web 应用) 和Spring Data JPA(用于数据库操作)。
- Project:
- 点击 "GENERATE" 下载项目压缩包。
2 编写一个简单的 Controller
将下载的项目解压到你的 Linux 工作目录中(~/my-web-app)。
打开 src/main/java/com/example/demo/DemoApplication.java,或者创建一个新的 Controller 类:
// src/main/java/com/example/demo/HelloController.java
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, Linux Java Web World!";
}
}
3 本地运行测试
在项目根目录 (~/my-web-app) 下,执行 Maven 命令:
# 编译并运行项目 mvn spring-boot:run
你会看到 Tomcat 服务器启动的日志,在浏览器或使用 curl 访问:
curl http://localhost:8080/hello
你应该会看到输出:Hello, Linux Java Web World!
Web 服务器 vs. 应用服务器
在部署到生产环境时,需要理解它们的区别和协作方式。
| 特性 | Tomcat (应用服务器) | Nginx (Web 服务器) |
|---|---|---|
| 主要职责 | 运行 Java Servlet/JSP,处理动态业务逻辑 | 处理 HTTP/HTTPS 请求,服务静态文件,反向代理 |
| 静态文件 | 效率较低,也能处理 | 效率极高,专为静态文件优化 |
| 并发连接 | 性能不错,但不如 Nginx | 非常擅长处理高并发、长连接 |
| 配置 | Java 配置 (web.xml) 或注解 |
配置文件 (nginx.conf) |
| Java 支持 | 原生支持,直接运行 WAR/JAR | 不支持,必须通过反向代理转发给 Tomcat |
最佳实践组合:Nginx + Tomcat
- Nginx 作为前端,监听 80/443 端口。
- Tomcat 作为后端,监听一个内部端口(如 8080)。
- Nginx 接收到所有请求。
- 如果请求是静态资源(如
/css/style.css),Nginx 直接返回。 - 如果请求是动态的(如
/api/user),Nginx 将请求反向代理到 Tomcat 的 8080 端口。
- 如果请求是静态资源(如
- Tomcat 处理完请求后,将响应返回给 Nginx,再由 Nginx 返回给用户。
这样做可以:
- 提高性能:让 Nginx 处理它擅长的事情。
- 增强安全性:隐藏 Tomcat 的真实端口和细节。
- 负载均衡:可以轻松配置 Nginx 将请求分发到多个 Tomcat 实例。
部署流程
假设我们采用 Nginx + Tomcat 的架构。
1 打包应用
对于 Spring Boot 项目,默认打包成可执行的 JAR 文件。
# 在项目根目录执行 mvn clean package
打包成功后,你会在 target/ 目录下找到一个名为 demo-0.0.1-SNAPSHOT.jar 的文件。
2 上传到服务器
使用 scp (secure copy) 或 rsync 将 JAR 文件上传到 Linux 服务器。
# 示例:从本地上传到服务器的 /opt/apps 目录 scp target/demo-0.0.1-SNAPSHOT.jar user@your-server-ip:/opt/apps/
3 创建 Tomcat 服务 (可选,但推荐)
虽然 Spring Boot 可以独立运行,但在生产环境中,我们通常将其作为系统服务来管理,使用 systemd。
-
创建服务文件
sudo vim /etc/systemd/system/my-web-app.service
-
写入以下内容
[Unit] Description=My Spring Boot Web Application After=syslog.target network.target [Service] # Java 运行参数,根据服务器内存调整 -Xms 和 -Xmx JAVA_OPTS="-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom" # 运行用户,建议使用普通用户而不是 root USER=myappuser # JAR 文件路径 JAR_PATH=/opt/apps/demo-0.0.1-SNAPSHOT.jar # 启动命令 ExecStart=/usr/bin/java $JAVA_OPTS -jar $JAR_PATH # 重启策略 Restart=on-failure # 重启间隔 RestartSec=10 [Install] WantedBy=multi-user.target
-
管理服务
# 重载 systemd 配置 sudo systemctl daemon-reload # 启动服务 sudo systemctl start my-web-app # 设置开机自启 sudo systemctl enable my-web-app # 查看服务状态 sudo systemctl status my-web-app # 查看实时日志 sudo journalctl -u my-web-app -f
你的应用已经作为后台服务运行了,默认情况下,它监听 8080 端口。
4 配置 Nginx 反向代理
-
安装 Nginx
# Ubuntu/Debian sudo apt install nginx # CentOS/RHEL sudo yum install nginx
-
创建站点配置文件
sudo vim /etc/nginx/sites-available/my-web-app
-
写入以下内容
server { listen 80; server_name your-domain.com; # 替换成你的域名或服务器IP access_log /var/log/nginx/my-web-app.access.log; error_log /var/log/nginx/my-web-app.error.log; location / { # 将所有请求代理到 Tomcat proxy_pass http://127.0.0.1:8080; # 设置一些代理头 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; } } -
启用站点并测试 Nginx 配置
# 创建软链接启用站点 sudo ln -s /etc/nginx/sites-available/my-web-app /etc/nginx/sites-enabled/ # 测试配置文件语法 sudo nginx -t # 如果测试通过,重载 Nginx 配置 sudo systemctl reload nginx
访问 http://your-domain.com,Nginx 会将请求转发到你的 Spring Boot 应用。
生产环境运维
1 日志管理
日志是排查问题的关键。
- 应用日志:Spring Boot 默认输出到控制台,可以被
systemd的journalctl捕获,最佳实践是配置日志框架(如 Logback)将日志写入文件,并进行按天分割。 - Nginx 日志:Nginx 会自动记录访问日志和错误日志,配置在
/etc/nginx/sites-available/中。 - 集中化日志:对于大型应用,使用 ELK Stack (Elasticsearch, Logstash, Kibana) 或 EFK (Elasticsearch, Fluentd, Kibana) 将所有服务器日志收集到一处,方便搜索和分析。
2 监控
- JMX (Java Management Extensions):Tomcat 和 Spring Boot 都支持 JMX,可以通过 JMX 工具(如
jconsole,VisualVM)远程监控应用的内存使用、线程状态、GC 情况等。 - Prometheus + Grafana:这是目前最主流的监控方案,通过
micrometer库将应用指标暴露给 Prometheus,然后在 Grafana 中进行可视化展示。 - 服务器监控:使用
top,htop,free,df -h等命令监控 CPU、内存、磁盘使用情况。
3 进程管理
我们已经使用了 systemd 来管理应用进程,这是最推荐的方式,它可以实现开机自启、自动重启、状态查看等功能。
高级主题
1 容器化
使用 Docker 和 Docker Compose 是现代部署的标准。
- Dockerfile:为你的 Spring Boot 应用创建一个 Dockerfile,将 JAR 包打包成一个镜像。
- Docker Compose:编写一个
docker-compose.yml文件,一键启动你的应用、数据库、Nginx 等所有服务,并管理它们之间的网络和依赖关系。
示例 Dockerfile
# 使用一个轻量的 OpenJDK 镜像作为基础 FROM openjdk:17-jre-slim # 设置工作目录 WORKDIR /app # 复制 JAR 文件到容器中 COPY target/demo-0.0.1-SNAPSHOT.jar app.jar # 暴露端口 EXPOSE 8080 # 设置 JVM 参数并启动应用 ENTRYPOINT ["java", "-jar", "/app/app.jar"]
2 性能调优
- JVM 参数调优:根据服务器内存,调整
-Xms(初始堆大小) 和-Xmx(最大堆大小),通常设置为服务器内存的 50%-70%。 - GC 调优:选择合适的垃圾回收器(如 G1GC 是目前的主流选择)。
- 连接池调优:配置数据库连接池(如 HikariCP)的最大连接数、超时时间等。
- Nginx 调优:调整
worker_processes和worker_connections以提高并发处理能力。
总结与最佳实践
- 环境隔离:为不同环境(开发、测试、生产)使用不同的配置文件。
- 版本控制:所有代码、配置文件都应使用 Git 进行管理。
- 自动化部署:使用 Jenkins, GitLab CI, GitHub Actions 等工具实现代码提交后自动构建、测试和部署。
- 安全第一:不要用 root 用户运行应用,使用 HTTPS,定期更新依赖库,修复安全漏洞。
- 日志即代码:像管理代码一样管理日志,确保日志格式统一、信息完整。
- 拥抱容器化:Docker 提供了环境一致性和部署便捷性,是现代运维的基石。
- 监控先行:在应用设计之初就考虑好如何监控,而不是出了问题再手忙脚乱。
在 Linux 上进行 Java Web 开发和部署,是一个系统性的工程,涵盖了从开发、构建、打包到运维的整个生命周期,掌握这些技能,对于成为一名优秀的后端工程师至关重要。
