杰瑞科技汇

Linux下Java Web如何部署运行?

目录

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

核心概念

在 Linux 上运行 Java Web 应用,通常涉及以下几个核心组件:

Linux下Java Web如何部署运行?-图1
(图片来源网络,侵删)
  • Linux 操作系统:提供稳定、高性能的运行环境。
  • JDK (Java Development Kit):提供 Java 运行时环境和开发工具,是运行 Java 程序的基础。
  • Web 服务器 / 应用服务器
    • Web 服务器 (如 Nginx, Apache):主要负责处理静态资源(HTML, CSS, JS, 图片)和反向代理,它像一个“门卫”,接收所有 HTTP 请求,然后将动态请求(如 .jsp, .do)转发给应用服务器。
    • 应用服务器 (如 Tomcat, Jetty):负责执行 Java 代码,处理业务逻辑,并生成动态内容,它是 Java Web 应用的“引擎”。
  • 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 网站。

  1. 访问 start.spring.io
  2. 选择:
    • Project: Maven Project
    • Language: Java
    • Spring Boot: 选择一个稳定版本 (如 3.x.x)
    • Project Metadata: 填写 Group, Artifact, Name 等。
    • Dependencies: 添加 Spring Web (用于创建 Web 应用) 和 Spring Data JPA (用于数据库操作)。
  3. 点击 "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

  1. Nginx 作为前端,监听 80/443 端口。
  2. Tomcat 作为后端,监听一个内部端口(如 8080)。
  3. Nginx 接收到所有请求。
    • 如果请求是静态资源(如 /css/style.css),Nginx 直接返回。
    • 如果请求是动态的(如 /api/user),Nginx 将请求反向代理到 Tomcat 的 8080 端口。
  4. 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

  1. 创建服务文件

    sudo vim /etc/systemd/system/my-web-app.service
  2. 写入以下内容

    [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
  3. 管理服务

    # 重载 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 反向代理

  1. 安装 Nginx

    # Ubuntu/Debian
    sudo apt install nginx
    # CentOS/RHEL
    sudo yum install nginx
  2. 创建站点配置文件

    sudo vim /etc/nginx/sites-available/my-web-app
  3. 写入以下内容

    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;
        }
    }
  4. 启用站点并测试 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 默认输出到控制台,可以被 systemdjournalctl 捕获,最佳实践是配置日志框架(如 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_processesworker_connections 以提高并发处理能力。

总结与最佳实践

  1. 环境隔离:为不同环境(开发、测试、生产)使用不同的配置文件。
  2. 版本控制:所有代码、配置文件都应使用 Git 进行管理。
  3. 自动化部署:使用 Jenkins, GitLab CI, GitHub Actions 等工具实现代码提交后自动构建、测试和部署。
  4. 安全第一:不要用 root 用户运行应用,使用 HTTPS,定期更新依赖库,修复安全漏洞。
  5. 日志即代码:像管理代码一样管理日志,确保日志格式统一、信息完整。
  6. 拥抱容器化:Docker 提供了环境一致性和部署便捷性,是现代运维的基石。
  7. 监控先行:在应用设计之初就考虑好如何监控,而不是出了问题再手忙脚乱。

在 Linux 上进行 Java Web 开发和部署,是一个系统性的工程,涵盖了从开发、构建、打包到运维的整个生命周期,掌握这些技能,对于成为一名优秀的后端工程师至关重要。

分享:
扫描分享到社交APP
上一篇
下一篇