【博客系统】博客系统第十一弹:从零开始在 Linux 系统上搭建 Java 部署环境并部署 Web 项目

发布于:2025-05-30 ⋅ 阅读:(15) ⋅ 点赞:(0)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


搭建 Java 部署环境


JDK


1. 更新软件包


apt 命令详细介绍

sudo apt-get update

2. 安装 OpenJDK


查找 JDK 包

apt list | grep "jdk"

安装 JDK

sudo apt install openjdk-17-jdk

注意:

  • 使用 java -version 验证是否安装成功。
  • 如果提示 “java 命令找不到” 则说明安装失败。

image-20250529160653334


3. 卸载 OpenJDK


  1. 检查安装的是哪个 OpenJDK

    dpkg --list | grep -i jdk
    
  2. 移除 OpenJDK 包

    apt-get purge openjdk*
    
  3. 卸载 OpenJDK 相关包

    apt-get purge icedtea-* openjdk-*
    
  4. 检查所有 OpenJDK 包是否都已卸载完毕

    dpkg --list | grep -i jdk
    

MySQL


使用 apt 安装 MySQL


  1. 查找安装包

    apt list | grep "mysql-server"
    
  2. 安装 MySQL

    sudo apt install mysql-server
    

查看 MySQL 状态


sudo systemctl status mysql

image-20250529161153518


MySQL 安装安全设置


默认的 MySQL 设置是不安全的,MySQL 安装提供了一个安全脚本,用于解决不太安全的默认选项。


运行以下命令:

sudo mysql_secure_installation #安装安全设置

执行过程:

  1. 是否设置验证密码组件:

    Press y|Y for Yes, any other key for No: Y #是否设置验证密码组件
    
  2. 密码强度设置:

    Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2 #设置密码强度
    
  3. 删除匿名用户:

    Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y 
    
    #默认情况下,MySQL安装有一个匿名用户, 允许任何人登录MySQL. 是否删除匿名用户?
    
  4. 禁止 root 用户远程登录:

    Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y 
    
    #仅应允许root从'localhost'连接
    
  5. 删除 test 数据库:

    Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y 
    
    #默认情况下, MySQL带有⼀个test数据库, 是否删除?
    
  6. 重新加载权限表:

    Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y 
    
    #是否现在加载配置, 使刚才的修改生效?
    
  7. 完成:

    All done!
    

通过以上步骤,MySQL 的安全设置已经完成,确保了数据库的安全性。设置密码


连接 MySQL 服务器


sudo mysql

使用 ALTER USER 命令修改密码


ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'BITE@yyds.666';

退出 MySQL


exit

image-20250529164241001


再次登录输入:

mysql -uroot -p   #  密码: BITE@yyds.666

卸载 MySQL


  1. 停止 MySQL
sudo systemctl stop mysql

  1. 卸载 MySQL
sudo apt-get remove --purge mysql-server mysql-client mysql-common

  1. 删除 MySQL 配置文件和数据
sudo rm -rf /etc/mysql /var/lib/mysql

  1. 清理残留文件和目录
sudo apt-get autoremove
sudo apt-get autoclean

  1. 验证卸载结果
mysql --version

部署 Web 项目到 Linux


环境配置


确保程序正常运行需完成以下配置:

  1. 数据库准备

    • 执行提供的建表脚本,确保表结构与服务器一致
  2. 多环境配置

    • 按环境创建配置文件(如开发/测试/生产环境)
    • 命名格式:application-XXX.ymlapplication-XXX.properties
    • 差异化配置项示例:MySQL账号密码、服务端口等

关键点:通过文件命名区分环境,避免硬编码敏感信息。


以下以application-XXX.yml为例:

application-dev.yml: 开发环境配置

image-20250529175414319

server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/java_blog_spring?characterEncoding=utf8&useSSL=false
    username: root
    password: 123456  # windows 数据库密码
    driver-class-name: com.mysql.cj.jdbc.Driver
  mybatis-plus:
    configuration:
      map-underscore-to-camel-case: true
#      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl   # linux 服务器没必要打日志, 打日志也会影响性能
logging:
  file:
    name: spring-blog.log

application-prod.yml: 生产环境配置

image-20250529175444889

server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/java_blog_spring?characterEncoding=utf8&useSSL=false
    username: root
    password: BITE@yyds.666
    driver-class-name: com.mysql.cj.jdbc.Driver
  mybatis-plus:
    configuration:
      map-underscore-to-camel-case: true
#      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
  file:
    name: spring-blog.log

如果同时有三个yml文件,通常只有主配置文件application.yml会自动生效。为了使其他配置文件(如application-prod.ymlapplication-dev.yml)生效,需要在主配置文件application.yml中进行相应的配置。具体步骤如下:

  1. 删除主配置文件中的数据库相关配置: 在application.yml中删除与数据库相关的配置项,以避免冲突。
  2. 指定生效的配置文件: 在application.yml中添加配置,指定使用application-prod.ymlapplication-dev.yml作为生效的配置文件。

image-20250529175812878

在Spring框架中,spring.profiles.active属性用于指定激活的配置文件,application.yml 二选一即可:

spring:
  profiles:
    active: prod    
spring:
  profiles:
    active: dev

这里的active属性值填的是配置文件名的一部分(如devprod等),而不是完整的文件名(如application-prod.ymlapplication-dev.yml)。


启动程序:

image-20250530103902446


测试接口:

image-20250529182232839


当前配置文件中的数据库密码是按照 Linux 系统的设置来配置的,与 Windows 系统的数据库密码不一致,从而导致接口访问失败:

image-20250529182539655


在不同环境之间来回切换时,需要频繁修改配置文件中的active值。在多人协作的场景下,很容易出现忘记修改active值的情况,从而导致配置错误。

为了避免这种情况,我们可以通过从 Maven 中读取环境配置变量来为active赋值:

image-20250529184152481

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <profile.name>dev</profile.name>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <profile.name>prod</profile.name>
        </properties>
    </profile>
</profiles>

注意,每次勾选新的 profile 都需要刷新 maven


修改 application.yml

spring:
  profiles:
    active: @profile.name@

image-20250529185215864


勾选好 profile 后,刷新 maven,重新运行程序:

image-20250529185507098


测试接口,此时接口访问成功:

image-20250529184623409


构建项目并打包


在本地使用 Maven 进行打包:

  1. 如果 Test 代码中有与环境配置相关的操作(比如数据库相关的操作),打包会失败,可以跳过测试。
  2. 点击 clean -> package

dev 切换成 prod,刷新 maven 并打包:

image-20250529190134939


因为这个项目使用的是 mybatis-plus ,所以不需要写 mybatis 的测试用例,所以打包成功

image-20250529192016934

  • 如果使用的是 MyBatis 而非 MyBatis-Plus,就需要在单元测试中编写 MyBatis 的接口测试代码

  • Maven 的配置文件中,如果选择了prod环境配置并刷新了 Maven,然后按照生命周期package命令进行打包,那么 Maven 会依次执行clean、validate、compile、test、package阶段:image-20250529191432762

  • 在 Maven 的 test 阶段运行单元测试时,由于配置的数据库密码与 Windows 系统的数据库密码不一致,导致 MyBatis 无法连接到数据库,从而使得单元测试失败

  • 单元测试失败会中断 Maven 的打包过程,导致打包失败

  • 解决方案:在打包前,设置去掉 test 阶段,避免打包过程因为 test 的问题导致打包过程被打断:image-20250529191733447

接下来,根据日志路径,在本地找到打好的 Jar 包:

image-20250529192828340


或者通过下面这个方法,找到在本地中打好的 Jar 包:

image-20250530154446261


上传 Jar 包到服务器并运行


1. 上传 Jar


在 linux 系统中,创建和 windows 对应数据库及数据表

-- 建表 SQL
create database if not exists java_blog_spring charset utf8mb4;

use java_blog_spring;

-- 用户表
DROP TABLE IF EXISTS java_blog_spring.user_info;
CREATE TABLE java_blog_spring.user_info(
`id` INT NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR (128) NOT NULL,
`password` VARCHAR (128) NOT NULL,
`github_url` VARCHAR (128) NULL,
`delete_flag` TINYINT (4) NULL DEFAULT 0,
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY (id),
UNIQUE INDEX user_name_UNIQUE (user_name ASC)) ENGINE = INNODB DEFAULT CHARACTER SET = utf8mb4 COMMENT = '用户表';

-- 博客表
drop table if exists java_blog_spring.blog_info;
CREATE TABLE java_blog_spring.blog_info (
`id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(200) NULL,
`content` TEXT NULL,
`user_id` INT(11) NULL,
`delete_flag` TINYINT(4) NULL DEFAULT 0,
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY (id))
ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '博客表';

-- 新增用户信息
insert into java_blog_spring.user_info (user_name, password, github_url) values("zhangsan", "123456", "https://gitee.com/bubblefish666/class-java45");
insert into java_blog_spring.user_info (user_name, password, github_url) values("lisi", "123456", "https://gitee.com/bubblefish666/class-java45");

insert into java_blog_spring.blog_info (title, content, user_id) values("第一篇博客", "111我是博客正文我是博客正文我是博客正文", 1);
insert into java_blog_spring.blog_info (title, content, user_id) values("第二篇博客", "222我是博客正文我是博客正文我是博客正文", 2);

为了能通过加密、加盐功能的密码校验,更新 linux 数据库表中,用户的密码:

update user_info set password= 'e5bf3de57e3243ab9d94b59b379a0a640f967f2e3ae738c2f5474ab0fe46389b' where id in(1,2);

image-20250529193626767


直接拖动打好的 Jar 包到 Xshell 窗口即可完成文件的上传。

image-20250529194002503

Xshell 可以直接拖动文件到窗口,达到上传文件的目的。如果使用其他客户端,不支持文件的上传,需要借助 lrzsz 命令;


借助 mv 改一下 jar 包名:

image-20250529194152710


2. 运行程序


接下来,在 linux 上运行该 jar 包:

java -jar blog.jar

image-20250529194511729

部署程序后,日志输出可能会非常频繁。如果使用以下命令启动程序:

java -jar blog.jar

那么在按下Ctrl+C停止日志输出时,程序也会随之停止运行,导致服务无法继续提供。为了避免这种情况,应使用以下命令启动程序:

nohup java -jar blog.jar &

nohup 命令详细介绍

这样,即使关闭终端或退出当前会话,程序仍能在后台 持续运行,不会因Ctrl+C操作而中断,从而确保服务的稳定性。


开放端口号


如果外网需要访问该服务,需要先服务器防火墙开放对应的端口号。

本着服务器安全的原则,云服务器上的端口非必要不开启。比如常见端口号:数据库 3306、Redis 6379,尽可能避免开放,而是采用其他方式来连接,比如配置隧道的方式。

image-20250529204038344


image-20250529204120904


确保列表中有添加的规则:

image-20250529204159836


验证程序


  1. 访问项目:http://IP:Port/blog_login.html

    • IP 改为云服务器的主机 IPPort 改为项目的端口号
  2. 按照项目功能进行验证:

    • 验证账号注册登录。image-20250529204225810

    • 验证展示博客列表。image-20250529204310510

    • 验证博客编辑功能image-20250529204430024

    • 验证新增博客。image-20250529204506265

    • 验证展示博客内容。image-20250529204453371

      image-20250530104741094


跟踪日志


实时追踪日志


tail -f [日志文件名]
特性 tail tail -f
功能 显示文件的最后几行(默认10行) 实时显示文件的最后几行,并持续更新
用途 用于查看文件的尾部内容 用于实时监控文件的动态更新,常用于日志文件
输出行为 输出文件的最后几行后即结束 输出文件的最后几行后,持续监控文件的新内容并实时显示
适用场景 查看静态文件的尾部内容 监控动态更新的日志文件,如服务器日志
命令格式 tail [文件名] tail -f [文件名]
示例 tail nohup.out tail -f nohup.out
是否实时 不实时,仅显示当前内容 实时,持续更新文件的新内容
退出方式 命令执行后自动退出 需手动按 Ctrl+C 退出
  • tail:用于查看文件的最后几行,适合查看静态文件的内容。
  • tail -f:用于实时监控文件的更新,适合查看动态更新的日志文件,如服务器日志。

image-20250530112349734


此时再访问接口,就会出现相关的日志:

image-20250530112514553


过滤日志


我们关注的重点是 ERROR 级别的日志,而非 INFO 级别的日志。因此,可以使用以下命令来跟踪日志,直接过滤出 ERROR 级别的日志内容:

tail -f nohup.out | grep "ERROR"

如果需要停止当前的日志跟踪,可以按 Ctrl+C,然后重新输入上述命令以继续跟踪。


过滤日志后,INFO级别的日志不在显示,只显示 ERROR级别的日志:

image-20250530113205342


如果我们想看更具体的 ERROR 级别的日志,比如错误日志连带着的堆栈信息,可以使用如下命令:

tail -f nohup.out | grep -A 10 "ERROR"
# 看带有 ERROR 日志往下的十条信息
  • -A 查看后 n 行
  • -B 查看前 n 行
  • -C 查看前后 n 行

image-20250530153119916


使用重定向将日志输出到自定义文件


如果想将输出的日志存储到自定义文件中,可以使用重定向操作

nohup java -jar blog.jar >指定文件路径 2>&1 &

例如:

nohup java -jar blog.jar >aa.log &

more aa.log | grep "ERROR"
  • >:将标准输出(日志信息)重定向到指定文件
  • 2>&1:将标准错误也重定向到指定文件,确保所有输出都写入同一文件
  • &将命令在后台运行,避免阻塞终端

在 Linux 中,>操作符可以将命令的输出内容写入指定文件,这种操作称为“重定向”


配置日志存储文件


我们没有看见 jar 包同目录下,生成对应存储日志的 spring-blog.log 文件,但是我们配置文件中配置了:

image-20250530115314750


后续发现,日志的格式配置错误了,纠正配置文件的 log 配置格式后,clean一下,重新上传并运行新的 Jar 包。:

image-20250530114205753


此时,在对应 Jar 包目录下,除了nohup.out,还会生成一个名为spring-blog.log的文件,专门用于存储服务生成的日志:

image-20250530115540628

在程序启动前,日志默认存储在nohup.out文件中。一旦程序启动,根据配置文件的指定,日志将存储到spring-blog.log文件中。


因此,若要追踪日志,应使用以下命令:

tail -f spring-blog.log | grep "ERROR"

而不是:

tail -f nohup.out | grep "ERROR"

常见问题


一个程序的正常运行,需要程序的正确环境的正确

同样的代码在 Windows 上可以运行成功,不一定在 Linux 上运行成功。不同的系统对代码的理解和支持是不同的。比如 Windows 系统对 MySQL 不区分大小写,Linux 区分大小写。

服务不能正常访问的原因有很多,主要分以下几个方面:

  1. 服务未启动

    • 使用 ps -ef | grep java 查看程序是否在运行。
    • 使用 curl http://127.0.0.1:8080/blog_login.html 看下是否有返回 HTML 页面。如果有返回,说明程序启动成功了,考虑端口未开放image-20250530160418290
    • 如果未启动成功,需要查看对应的日志,根据原因来分析:
      • 数据库不存在。
      • 表不存在(区分大小写)。
      • 数据库密码不正确。
      • JDK 安装版本不对,或者未安装。
      • MySQL 未设置密码。
  2. HTTP 端口未开放

    • 检查云服务器防火墙/安全组是否开放相应端口(如 8080)

杀掉进程


如果我们需要重启服务,或者重新部署等,都需要先停止之前的服务。

(1) 查看当前服务的进程

ps -ef | grep java

image-20250530130621426

上图中的 35104 就是该服务的进程。


也可以在启动程序后,输入如下命令

curl http://127.0.0.1:8080/blog_login.html

image-20250530160403821


(2) 杀掉进程

kill -9 PID

image-20250530130854027


杀掉服务对应正在运行的进程,服务此时就不能再访问了:

image-20250530131532681


再次运行 Jar 包:

image-20250530131508349


总结


  1. 连接 Linux 服务器的方式有很多,Xshell 只是其中一种。Xshell 是一个客户端,而非服务器
  2. Ubuntu 软件管理工具是 apt,其他的 Linux 发行版本软件包管理工具不同,比如 CentOS 是使用 yum 来管理软件的。
  3. Spring Boot 可以使用多个配置文件来完成不同平台的配置。
  4. 在 Windows 上可以运行成功的代码,在 Linux 上不一定能运行成功。
  5. 启动程序需要使用 nohup 后台运行,需要停止服务时,使用 kill 命令。

在这里插入图片描述

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到