1. Linux环境下Java项目部署概述
在Linux服务器上部署Java项目是后端开发工程师的必备技能之一。与Windows环境不同,Linux环境下部署Java项目需要考虑更多系统层面的因素,比如权限管理、环境变量配置、服务化运行等。本文将详细介绍从零开始在Linux系统上部署带有JAR包的Java项目的完整流程,包括Java环境配置、项目目录规划、启动脚本编写以及常见问题排查等关键环节。
对于刚接触Linux系统管理的Java开发者来说,最大的挑战往往不是代码本身,而是如何让项目在生产环境中稳定运行。Linux的无图形界面操作方式、严格的权限体系以及不同的文件系统结构,都需要开发者调整在Windows环境下的开发习惯。本文将采用"原理说明+实操演示"的方式,确保即使是Linux新手也能顺利完成部署。
提示:本文基于CentOS 7系统进行演示,但所述方法同样适用于Ubuntu、Debian等主流Linux发行版,只需注意包管理命令的差异(yum/apt-get)。
2. 环境准备与基础配置
2.1 Java运行环境安装与验证
Java环境是运行JAR包的基础前提。在Linux上安装JDK通常有以下几种方式:
- 使用系统包管理器安装(推荐新手):
bash复制# CentOS/RHEL
sudo yum install java-11-openjdk-devel
# Ubuntu/Debian
sudo apt-get install openjdk-11-jdk
- 手动下载安装Oracle JDK(需要官网下载):
bash复制tar -xzf jdk-11.0.15_linux-x64_bin.tar.gz
sudo mv jdk-11.0.15 /usr/local/
安装完成后,需要验证Java环境是否配置正确:
bash复制java -version
javac -version
如果系统提示"command not found",可能是环境变量未正确设置。需要将JAVA_HOME添加到系统环境:
bash复制echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
2.2 项目目录结构规划
合理的目录结构能极大提升项目管理效率。建议采用以下标准化目录布局:
code复制/opt
└── myapp
├── bin # 存放启动脚本
├── config # 配置文件
├── lib # 依赖JAR包
├── logs # 日志文件
└── app.jar # 主应用JAR
创建目录并设置适当权限:
bash复制sudo mkdir -p /opt/myapp/{bin,config,lib,logs}
sudo chown -R $USER:$USER /opt/myapp # 将所有权赋给当前用户
3. 项目部署与配置
3.1 传输JAR包到服务器
将本地开发的JAR包上传到服务器有多种方式:
- 使用scp命令(最常用):
bash复制scp target/myapp-1.0.0.jar user@server_ip:/opt/myapp/app.jar
- 通过SFTP客户端(如FileZilla):
- 连接服务器后,直接拖拽文件到目标目录
- 使用Git仓库(适合持续集成):
bash复制git clone https://github.com/yourrepo/myapp.git
cd myapp && mvn package
cp target/*.jar /opt/myapp/app.jar
3.2 处理项目依赖
对于需要外部JAR依赖的项目,有两种处理方式:
- 打包为fat JAR(推荐):
使用Maven或Gradle构建工具将所有依赖打包到一个JAR中:
xml复制<!-- Maven的pom.xml配置 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
- 单独管理依赖JAR:
将依赖JAR放入lib目录,启动时通过-classpath指定:
bash复制java -cp app.jar:lib/* com.example.Main
4. 启动脚本与服务化
4.1 编写启动脚本
创建/opt/myapp/bin/start.sh:
bash复制#!/bin/bash
APP_HOME=/opt/myapp
JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
LOG_FILE=$APP_HOME/logs/app_$(date +%Y%m%d).log
cd $APP_HOME
nohup java $JAVA_OPTS -jar app.jar > $LOG_FILE 2>&1 &
echo $! > $APP_HOME/bin/pid.file
给脚本添加执行权限:
bash复制chmod +x /opt/myapp/bin/start.sh
4.2 系统服务化(Systemd)
将Java应用注册为系统服务,实现开机自启:
创建/etc/systemd/system/myapp.service:
ini复制[Unit]
Description=My Java Application
After=syslog.target network.target
[Service]
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/start.sh
SuccessExitStatus=143
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
启用并启动服务:
bash复制sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
5. 运维与监控
5.1 日志管理
配置日志轮转防止磁盘爆满:
创建/etc/logrotate.d/myapp:
code复制/opt/myapp/logs/*.log {
daily
rotate 30
compress
missingok
notifempty
copytruncate
}
5.2 进程监控
使用jps查看Java进程:
bash复制jps -l
使用jstat监控GC情况:
bash复制jstat -gcutil <pid> 1000 5
5.3 常见问题排查
- 端口冲突:
bash复制netstat -tulnp | grep 8080
- 内存不足:
调整JVM参数:
bash复制JAVA_OPTS="-Xms1g -Xmx2g -XX:+HeapDumpOnOutOfMemoryError"
- 类加载问题:
bash复制java -verbose:class -jar app.jar | grep "类名"
6. 高级部署方案
6.1 使用Docker容器化
创建Dockerfile:
dockerfile复制FROM openjdk:11-jre
WORKDIR /app
COPY target/app.jar .
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
构建并运行:
bash复制docker build -t myapp .
docker run -d -p 8080:8080 --name myapp myapp
6.2 负载均衡配置
使用Nginx作为反向代理:
nginx复制upstream myapp {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
server {
listen 80;
location / {
proxy_pass http://myapp;
}
}
6.3 持续集成部署
Jenkins pipeline示例:
groovy复制pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Deploy') {
steps {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: 'prod-server',
transfers: [
sshTransfer(
sourceFiles: 'target/*.jar',
remoteDirectory: '/opt/myapp',
execCommand: 'systemctl restart myapp'
)
]
)
]
)
}
}
}
}
7. 安全加固建议
- 使用非root用户运行:
bash复制sudo useradd -r -s /bin/false appuser
sudo chown -R appuser:appuser /opt/myapp
- 防火墙配置:
bash复制sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
- 敏感信息加密:
使用Jasypt等工具加密配置文件中的密码:
properties复制db.password=ENC(加密后的字符串)
- 定期更新JDK:
bash复制sudo yum update java-11-openjdk