# CentOS 7 Java 项目部署说明 ## 1. 环境概览 服务器环境: ```text 系统:CentOS 7.x 架构:x86_64 服务器 IP:192.168.1.144 ``` ```text todesk地址: 435628202 93qafjm1 通过此台计算机远程局域网内服务器 ssh admin@192.168.1.144 hngd5618 数据库mysql mysql端口23306 版本8.0 登录方式 mysql -h127.0.0.1 -P23306 -uroot -p 账号root 密码为项目内配置密码yuyue520 redis密码为yuyue520 redis端口26379 ``` 当前部署组件: | 组件 | 版本/说明 | 端口 | |---|---|---:| | JDK | Temurin OpenJDK 17.0.20.1 | - | | Redis | 7.2.16 | 26379 | | MySQL | 8.0.46 | 23306 | | Nginx | 1.30.4 | 80 | | Java 应用 | Spring Boot Jar | 项目实际端口 | | 前端 | admin-mgr | 由 Nginx 80 端口托管 | --- # 2. 目录规划 ```text /usr/local/java/ └── jdk17 # JDK 17 软链接 /usr/local/redis/ ├── bin/ # Redis 程序 ├── conf/redis.conf # Redis 配置 ├── data/ # Redis 数据 └── logs/redis.log # Redis 日志 /usr/local/mysql/ ├── mysql-8.0.46/ # MySQL 实际程序目录 └── current -> mysql-8.0.46 # MySQL 软链接 /usr/local/nginx/ ├── sbin/nginx # Nginx 程序 ├── conf/nginx.conf # Nginx 配置 └── logs/ # Nginx 日志 /data/mysql/ ├── data/ # MySQL 数据 ├── logs/ # MySQL 日志 ├── tmp/ # MySQL 临时目录 └── mysql.pid # MySQL PID /data/java/myapp/ ├── app.jar # Java 应用 ├── logs/ # Java 日志(如项目自行输出) └── backup/ # Jar 备份目录 /data/web/admin-mgr/ ├── index.html └── assets/ # 前端静态资源 ``` --- # 3. JDK 17 ## 3.1 安装文件 原始安装包: ```text /home/admin/OpenJDK17U-jdk_x64_linux_hotspot_17.0.20.1_1.tar.gz ``` 安装目录: ```text /usr/local/java/jdk-17.0.20.1+1 ``` 统一软链接: ```text /usr/local/java/jdk17 ``` 环境变量: ```text /etc/profile.d/java.sh ``` 内容: ```bash export JAVA_HOME=/usr/local/java/jdk17 export PATH=$JAVA_HOME/bin:$PATH ``` 生效: ```bash source /etc/profile.d/java.sh ``` 验证: ```bash java -version javac -version echo $JAVA_HOME ``` ## 3.2 JDK 升级 解压新版本到: ```text /usr/local/java/jdk-17.x.x ``` 然后切换软链接: ```bash sudo rm -f /usr/local/java/jdk17 sudo ln -s /usr/local/java/jdk-17.x.x /usr/local/java/jdk17 ``` 最后重启 Java: ```bash sudo systemctl restart myapp ``` --- # 4. Redis 7.2.16 安装目录: ```text /usr/local/redis ``` 配置文件: ```text /usr/local/redis/conf/redis.conf ``` 数据: ```text /usr/local/redis/data ``` 日志: ```text /usr/local/redis/logs/redis.log ``` 端口: ```text 26379 ``` Redis 配置应包含: ```conf port 26379 daemonize yes dir /usr/local/redis/data logfile "/usr/local/redis/logs/redis.log" appendonly yes ``` 如果 Java 和 Redis 在同一台服务器,建议: ```conf bind 127.0.0.1 ``` 如果还需要局域网访问: ```conf bind 127.0.0.1 192.168.1.144 ``` 建议配置密码: ```conf requirepass 你的Redis密码 ``` ## 4.1 Redis 用户与权限 Redis 建议使用独立用户: ```bash sudo useradd -r -s /sbin/nologin redis ``` 目录权限: ```bash sudo chown -R redis:redis /usr/local/redis/data sudo chown -R redis:redis /usr/local/redis/logs ``` ## 4.2 systemd 服务 文件: ```text /etc/systemd/system/redis.service ``` 示例: ```ini [Unit] Description=Redis Server After=network.target [Service] Type=forking User=redis Group=redis ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf Restart=always RestartSec=3 [Install] WantedBy=multi-user.target ``` 重新加载: ```bash sudo systemctl daemon-reload sudo systemctl enable redis ``` 启动: ```bash sudo systemctl start redis ``` 停止: ```bash sudo systemctl stop redis ``` 重启: ```bash sudo systemctl restart redis ``` 状态: ```bash sudo systemctl status redis ``` 测试: ```bash /usr/local/redis/bin/redis-cli -p 26379 ``` 有密码: ```bash /usr/local/redis/bin/redis-cli -p 26379 -a 'Redis密码' ping ``` 正常返回: ```text PONG ``` 端口检查: ```bash sudo ss -lntp | grep 26379 ``` --- # 5. MySQL 8.0.46 MySQL 使用: ```text mysql-8.0.46-linux-glibc2.17-x86_64 ``` CentOS 7 必须使用 glibc 2.17 兼容版本,不要使用 glibc 2.28 版本。 实际目录: ```text /usr/local/mysql/mysql-8.0.46 ``` 软链接: ```text /usr/local/mysql/current ``` 配置: ```text /etc/my.cnf ``` 数据: ```text /data/mysql/data ``` 日志: ```text /data/mysql/logs/mysql-error.log ``` 慢 SQL: ```text /data/mysql/logs/mysql-slow.log ``` 端口: ```text 23306 ``` ## 5.1 MySQL 基础配置 ```ini [client] port=23306 socket=/tmp/mysql.sock default-character-set=utf8mb4 [mysqld] user=mysql port=23306 basedir=/usr/local/mysql/current datadir=/data/mysql/data socket=/tmp/mysql.sock pid-file=/data/mysql/mysql.pid tmpdir=/data/mysql/tmp character-set-server=utf8mb4 collation-server=utf8mb4_general_ci lower_case_table_names=1 max_connections=500 innodb_buffer_pool_size=512M log-error=/data/mysql/logs/mysql-error.log slow_query_log=1 slow_query_log_file=/data/mysql/logs/mysql-slow.log long_query_time=2 skip-name-resolve [mysql] default-character-set=utf8mb4 ``` 注意: `/etc/my.cnf` 中不要同时保留旧 MariaDB 配置,例如: ```ini log-error=/var/log/mariadb/mariadb.log ``` 检查: ```bash sudo grep -Rni "log-error" /etc/my.cnf /etc/my.cnf.d 2>/dev/null ``` ## 5.2 /data 权限 由于 MySQL 使用 `/data/mysql`,必须保证 mysql 用户能穿过 `/data`。 当前推荐: ```bash sudo chmod 711 /data sudo chown -R mysql:mysql /data/mysql sudo chmod 750 /data/mysql sudo chmod 750 /data/mysql/data sudo chmod 750 /data/mysql/logs sudo chmod 750 /data/mysql/tmp ``` 测试 mysql 用户写权限: ```bash sudo -u mysql touch /data/mysql/data/test.txt sudo rm -f /data/mysql/data/test.txt ``` ## 5.3 SELinux 检查: ```bash getenforce ``` 如果为: ```text Enforcing ``` 可临时排障: ```bash sudo setenforce 0 ``` 正式环境建议配置正确的 SELinux context,而不是永久关闭: ```bash sudo yum install -y policycoreutils-python sudo semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?" sudo restorecon -Rv /data/mysql sudo setenforce 1 ``` ## 5.4 MySQL 初始化 只允许在全新空数据目录时执行: ```bash cd /usr/local/mysql/current sudo bin/mysqld \ --initialize \ --user=mysql \ --basedir=/usr/local/mysql/current \ --datadir=/data/mysql/data ``` 临时 root 密码: ```bash sudo grep "temporary password" /data/mysql/logs/mysql-error.log ``` ## 5.5 MySQL 服务 服务脚本: ```text /etc/init.d/mysqld ``` 启动: ```bash sudo service mysqld start ``` 停止: ```bash sudo service mysqld stop ``` 重启: ```bash sudo service mysqld restart ``` 状态: ```bash sudo service mysqld status ``` 开机启动: ```bash sudo chkconfig mysqld on ``` 端口: ```bash sudo ss -lntp | grep 23306 ``` 日志: ```bash sudo tail -100 /data/mysql/logs/mysql-error.log ``` 实时日志: ```bash sudo tail -f /data/mysql/logs/mysql-error.log ``` ## 5.6 MySQL 登录 Socket 登录: ```bash mysql -uroot -p ``` TCP 登录: ```bash mysql -h127.0.0.1 -P23306 -uroot -p ``` 两者不是一回事。 `mysql -uroot -p` 通常通过: ```text /tmp/mysql.sock ``` 而 Java JDBC: ```text jdbc:mysql://127.0.0.1:23306/... ``` 走的是 TCP。 --- # 6. Java 连接 MySQL 的 Host 授权问题 如果 Java 报错: ```text Host '127.0.0.1' is not allowed to connect to this MySQL server ``` 说明 MySQL 当前用户只允许: ```text 'user'@'localhost' ``` 但 Java 是: ```text 'user'@'127.0.0.1' ``` 如果 Java 配置不能修改,则必须让 MySQL 适配 Java。 先查看: ```sql SELECT user, host, plugin FROM mysql.user; ``` 假设 Java 使用 root,并且 Java 中用户名、密码、地址不能修改: ```sql CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY 'Java配置中的原密码'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION; FLUSH PRIVILEGES; ``` 然后测试: ```bash mysql -h127.0.0.1 -P23306 -uroot -p ``` 只要这条 TCP 登录成功,Java JDBC 才具备正常连接条件。 生产环境更建议给 Java 独立数据库账号,但如果现有 Java 配置不可修改,则按现有用户名和密码补齐对应的 `127.0.0.1` Host 授权。 --- # 7. MySQL SQL 脚本导入 登录后: ```sql USE 数据库名; source /home/admin/init.sql; ``` 或者 Linux 直接执行: ```bash mysql -h127.0.0.1 -P23306 -uroot -p 数据库名 < /home/admin/init.sql ``` --- # 8. MySQL 备份 单数据库: ```bash mysqldump \ -h127.0.0.1 \ -P23306 \ -uroot \ -p \ --single-transaction \ --routines \ --triggers \ --events \ 数据库名 > /home/admin/数据库名.sql ``` 全部数据库: ```bash mysqldump \ -h127.0.0.1 \ -P23306 \ -uroot \ -p \ --all-databases \ --single-transaction \ --routines \ --triggers \ --events \ > /home/admin/all.sql ``` --- # 9. Nginx 1.30.4 安装目录: ```text /usr/local/nginx ``` 程序: ```text /usr/local/nginx/sbin/nginx ``` 配置: ```text /usr/local/nginx/conf/nginx.conf ``` 日志: ```text /usr/local/nginx/logs/access.log /usr/local/nginx/logs/error.log ``` systemd: ```text /etc/systemd/system/nginx.service ``` ## 9.1 Nginx systemd ```ini [Unit] Description=Nginx HTTP Server After=network.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit PrivateTmp=true [Install] WantedBy=multi-user.target ``` 加载: ```bash sudo systemctl daemon-reload sudo systemctl enable nginx ``` 启动: ```bash sudo systemctl start nginx ``` 停止: ```bash sudo systemctl stop nginx ``` 重启: ```bash sudo systemctl restart nginx ``` 重载配置: ```bash sudo systemctl reload nginx ``` 状态: ```bash sudo systemctl status nginx ``` 修改配置后必须先: ```bash sudo /usr/local/nginx/sbin/nginx -t ``` 确认: ```text syntax is ok test is successful ``` 再: ```bash sudo systemctl reload nginx ``` ## 9.2 80 端口冲突 检查: ```bash sudo ss -lntp | grep ':80' ``` 如果手动启动过 nginx,可能与 systemd 冲突。 检查: ```bash ps -ef | grep '[n]ginx' ``` 优雅结束 master: ```bash sudo kill -QUIT ``` 之后统一使用 systemd 管理,不再直接执行: ```bash /usr/local/nginx/sbin/nginx ``` --- # 10. 前端 admin-mgr 上传压缩包: ```text /home/admin/admin-mgr.zip ``` 正式目录: ```text /data/web/admin-mgr ``` 当前结构: ```text /data/web/admin-mgr/ ├── index.html └── assets/ ``` Nginx 只负责静态前端,不反向代理 Java 后端。 配置: ```nginx server { listen 80; server_name _; charset utf-8; root /data/web/admin-mgr; index index.html; location / { try_files $uri $uri/ /index.html; } } ``` 访问: ```text http://192.168.1.144/ ``` --- # 11. 前端更新发布 新的包仍上传为: ```text /home/admin/admin-mgr.zip ``` 建议先备份: ```bash cd /data/web mv admin-mgr admin-mgr-bak-$(date +%Y%m%d%H%M%S) ``` 解压: ```bash unzip /home/admin/admin-mgr.zip -d /data/web/ ``` 确认: ```bash ls -lh /data/web/admin-mgr ``` 应直接存在: ```text index.html assets/ ``` 权限: ```bash sudo chmod -R 755 /data/web/admin-mgr ``` 如果只替换前端静态文件,Nginx 配置没有变化: ```text 不需要 restart 不需要 reload ``` 浏览器刷新即可。 如果 nginx.conf 有修改: ```bash sudo /usr/local/nginx/sbin/nginx -t sudo systemctl reload nginx ``` --- # 12. Java 应用 正式部署目录: ```text /data/java/myapp ``` Jar: ```text /data/java/myapp/app.jar ``` 原上传目录通常: ```text /home/admin/app.jar ``` systemd: ```text /etc/systemd/system/myapp.service ``` 示例: ```ini [Unit] Description=Java MyApp Service After=network.target [Service] Type=simple User=admin Group=admin WorkingDirectory=/data/java/myapp Environment="JAVA_HOME=/usr/local/java/jdk17" Environment="PATH=/usr/local/java/jdk17/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin" ExecStart=/usr/local/java/jdk17/bin/java \ -Xms512m \ -Xmx1024m \ -XX:+UseG1GC \ -jar /data/java/myapp/app.jar \ --spring.profiles.active=prod Restart=always RestartSec=5 SuccessExitStatus=143 [Install] WantedBy=multi-user.target ``` 加载: ```bash sudo systemctl daemon-reload sudo systemctl enable myapp ``` 启动: ```bash sudo systemctl start myapp ``` 停止: ```bash sudo systemctl stop myapp ``` 重启: ```bash sudo systemctl restart myapp ``` 状态: ```bash sudo systemctl status myapp ``` 实时日志: ```bash journalctl -u myapp -f ``` 最近 200 行: ```bash journalctl -u myapp -n 200 --no-pager ``` Java 进程: ```bash ps -ef | grep '[j]ava' ``` --- # 13. Java Jar 更新 假设新 Jar: ```text /home/admin/app.jar ``` 停止: ```bash sudo systemctl stop myapp ``` 备份: ```bash mkdir -p /data/java/myapp/backup cp /data/java/myapp/app.jar \ /data/java/myapp/backup/app-$(date +%Y%m%d%H%M%S).jar ``` 替换: ```bash cp /home/admin/app.jar /data/java/myapp/app.jar sudo chown admin:admin /data/java/myapp/app.jar ``` 启动: ```bash sudo systemctl start myapp ``` 检查: ```bash sudo systemctl status myapp journalctl -u myapp -f ``` --- # 14. Java 一键发布脚本 文件: ```text /data/java/myapp/deploy.sh ``` 内容: ```bash #!/bin/bash set -e APP_DIR=/data/java/myapp UPLOAD_JAR=/home/admin/app.jar TARGET_JAR=$APP_DIR/app.jar BACKUP_DIR=$APP_DIR/backup mkdir -p "$BACKUP_DIR" echo "停止 Java 服务..." sudo systemctl stop myapp if [ -f "$TARGET_JAR" ]; then echo "备份旧版本..." cp "$TARGET_JAR" \ "$BACKUP_DIR/app-$(date +%Y%m%d%H%M%S).jar" fi echo "替换新版本..." cp "$UPLOAD_JAR" "$TARGET_JAR" chown admin:admin "$TARGET_JAR" echo "启动 Java 服务..." sudo systemctl start myapp echo "服务状态:" sudo systemctl status myapp --no-pager ``` 授权: ```bash chmod +x /data/java/myapp/deploy.sh ``` 发布: ```bash /data/java/myapp/deploy.sh ``` --- # 15. 当前端口 | 服务 | IP | 端口 | 用途 | |---|---|---:|---| | Nginx | 0.0.0.0 | 80 | 前端访问 | | MySQL | 127.0.0.1/实际 bind | 23306 | 数据库 | | Redis | 127.0.0.1/实际 bind | 26379 | Redis | | Java | 127.0.0.1/实际 bind | 项目端口 | 后端服务 | 如果 Java、Redis、MySQL 都部署在同一台服务器,建议优先使用: ```text 127.0.0.1 ``` 连接。 Java → MySQL: ```text 127.0.0.1:23306 ``` Java → Redis: ```text 127.0.0.1:26379 ``` --- # 16. 防火墙建议 前端需要: ```bash sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --reload ``` 如果以后使用 HTTPS: ```bash sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload ``` Redis 26379 和 MySQL 23306 如果仅本机 Java 使用,不建议对外开放。 --- # 17. 常用状态检查 ## 全部端口 ```bash sudo ss -lntp ``` 关键端口: ```bash sudo ss -lntp | grep -E ':80|:23306|:26379' ``` ## Nginx ```bash systemctl status nginx ps -ef | grep '[n]ginx' ``` ## Redis ```bash systemctl status redis ps -ef | grep '[r]edis' ``` ## MySQL ```bash service mysqld status ps -ef | grep '[m]ysql' ``` ## Java ```bash systemctl status myapp ps -ef | grep '[j]ava' ``` --- # 18. 服务器重启后的检查 服务器重启后: ```bash systemctl status nginx systemctl status redis service mysqld status systemctl status myapp ``` 端口: ```bash sudo ss -lntp | grep -E ':80|:23306|:26379' ``` Java 日志: ```bash journalctl -u myapp -n 200 --no-pager ``` --- # 19. 更新方式汇总 | 模块 | 更新方式 | 是否需要重启 | |---|---|---| | 前端 admin-mgr | 替换 `/data/web/admin-mgr` | 一般不需要 | | Java Jar | 替换 `/data/java/myapp/app.jar` | 需要重启 myapp | | Nginx 配置 | 修改 `nginx.conf` | `reload` | | Redis 配置 | 修改 `redis.conf` | 重启 Redis | | MySQL 配置 | 修改 `/etc/my.cnf` | 重启 MySQL | | JDK | 更新软链接 `/usr/local/java/jdk17` | 重启 Java | | MySQL 数据 | 不直接替换目录 | 使用 SQL/备份恢复 | | Redis 数据 | 不直接随意替换 | 停服后按备份策略操作 | --- # 20. 整体架构 ```text 浏览器 | | HTTP :80 v Nginx 1.30.4 | +--> /data/web/admin-mgr index.html assets/ Java 17 Application | +--> MySQL 8.0.46 | 127.0.0.1:23306 | +--> Redis 7.2.16 127.0.0.1:26379 ``` --- # 21. 重要注意事项 1. CentOS 7 已停止官方维护,当前 yum 使用归档镜像源。 2. MySQL 8 在 CentOS 7 上使用 glibc 2.17 兼容包。 3. `/data` 权限必须允许 MySQL 用户穿过,否则会出现 `OS errno: 13 - Permission denied`。 4. SELinux 如果启用,需要为 `/data/mysql` 配置正确上下文。 5. `mysql -uroot -p` 成功,不代表 `127.0.0.1:23306` TCP 登录一定成功。 6. Java JDBC 使用 `127.0.0.1` 时,MySQL 必须存在对应的 `'用户'@'127.0.0.1'` 授权。 7. Nginx 后续统一使用 systemd 管理,不建议手动直接执行 nginx 主程序启动。 8. Redis 26379、MySQL 23306 如果仅本机使用,不建议暴露到公网。 9. 前端静态文件替换通常不需要重启 Nginx。 10. Java Jar 更新后需要重启 `myapp` 服务,并立即检查日志。