【JavaEE】(24) Linux 基础使用和程序部署

一、Linux 背景知识

Linux 的第一个版本开发者是 Linus,所以部分人会叫"林纳斯"。Linux 只是一个开源的操作系统内核 ,有些公司/开源组织基于 Linux 内核,配套了不同的应用程序,构成不同的操作系统(比如 vivo、),也就是不同"发行版":RedHat 收费,CentOS 社区免费版但是停止维护了(出了问题小公司不好搞,但是大公司有能力二次开发),Ubuntu 免费并且在持续维护。

Linux 免费开源、稳定(持续运行不重启很多年都没问题)、安全(管理员才能操作内核)、社区支持(有问题去社区问)。

我们程序员必学 Linux,只不过不同岗位侧重点不同。Linux 虽有图形界面,但不好用切占资源开销,所以 Java 开发需要学 Linux 基础命令 。Linux 自身提供了 API 给程序员完成复杂编程,比如文件操作、多线程、socket 编程等。但是 Java 有封装好的工具,并且跨平台,所以不需要学 Linux 的系统编程。然后就是在Linux 上部署项目 ,让用户访问,企业有自动化工具一键部署。安装程序是运维的事。最后就是读日志,tail 跟踪日志,grep 过滤信息。

二、Linux 环境搭建

物理机装 Linux 用起来不方便,虚拟机装 Linux 有各种环境问题,云服务器开机就用就是费钱,可以申请学生优惠。小的项目 2核2G够,大的比如微服务项目 2核4G 够。

买好后,要记住:公有 IP管理员账户 (默认root)、密码

XShell 终端软件,远程连接服务器,对服务器进行操作。

家庭/学校免费 - NetSarang Websitehttps://www.xshell.com/zh/free-for-home-school/

XShell 远程连接

复制粘贴设置:工具》选项》终端:

三、Linux 基础命令

  • ~ 表示 home 目录,root 管理员的 home 目录是 /root,普通用户是 /home/用户名。

1、创建文件夹(mkdir)

复制代码
语法:touch [选项] [⽬录]

mkdir:创建文件夹

mkdir -p:先创建所有不存在的父文件夹(parent),再创建文件夹(test)。

2、创建文件(touch)

touch:什么后缀都行

3、删除文件夹/文件(rm)

rm -rf:直接删除文件夹,及其下所有内容。包括只读文件也删除。(-r 指删除文件夹下,还有文件的情况)

不要轻易在根目录 / 下使用该命令,即删除所有包括系统文件,使用了系统也会提示不能操作:图中说明加 --no-preserve-root 选项会忽略警告强制删除。

rm -ri:删除所有文件之前,询问。

4、列出目录(ls)

ls :列出当前目录下的所有文件夹、文件。

ls -a:列出所有文件,包括 . 开头的隐藏文件。

ls -l:列出所有文件的详细信息。

ll:列出所有文件,包括隐藏文件的详细信息。

ls -dl:列出当前文件的详细信息。

5、改变工作目录(cd)

cd 绝对路径:

cd 相对路径:. 表示当前目录,.. 表示上一级目录。

cd -: 返回最近访问的目录。

6、显示当前目录(pwd)

7、快捷键

tab 自动补全:敲部分文件名,tab 可根据当前目录下的文件自动补全。

crl+c:输入输错了,取消命令。

8、复制文件夹/文件(cp)

cp源文件 目标路径

可以重命名:

若目标路径里有重复的,-f 是强制覆盖,-i 是覆盖前询问。

9、剪切文件夹/文件(mv)

mv

可以重命名剪切的源文件:

9、写文件(vi)

vi/vim 文件名:用 vim 文本编辑器打开文件。

i:进入编辑模式。

Esc:退出编辑模式。

:q 未修改,直接退出。

:wq 修改,保存退出。

:wq! 修改,强制保存退出。(另一个窗口也修改了这个文件并保存了,如果当前窗口不要另一个窗口修改的,就强制保存并退出)

:q 修改了,强制不保存退出。

更多参考使用文档,命令 vimtutor。

10、读文件

cat -n 文件名:读取文件所有内容,并显示行号。

more: 显示部分内容。按 enter 再显示一行,按 下箭头 再显示一页。 crl+c 结束。

less:滚动读取,:q 退出。

head -10:显示头 10 行。

tail -10:显示尾 10 行。

11、查找内容(grep)

常用于查看日志

grep -w 全字匹配。-r 递归查找所有文件。--color 高亮查找。

现实场景中,有很多用户请求,日志滚动得很快,所以需要用 tail -100f 跟踪最新日志 ,但是有些日志不是我们想要的,就用 grep 过滤日志

12、查看进程(ps)

显示所有进程,并查找进程:ps aux 或者 ps -ef | grep "进行名" 或 "进程 id"

13、查看网络状态(netstat)

**|**表示把前一个命令得输出,作为后一个命令得输入。

netstat -anp | grep "进程名" 或 "端口号"。

14、上传/下载文件

安装命令:

复制代码
apt-get install lrzsz

上传文件:直接拖拽 /rz

下载文件:sz 文件名

四、搭建 Java 部署环境

1、软件管理(apt)

不同发行版的 Linux 软件管理命令不一样,Ubuntu 是 apt

(1)查找软件包

列出的软件包数据库apt list,不建议直接用,因为会显示所有的软件,信息太多会卡住。一般搭配 grep。

(2)管理员身份运行

普通用户 上进行 apt 更新、安装、卸载操作,需要在前面加上sudo ,表示以管理员身份运行。因为软件的更新、安装、卸载是管理员才能执行的操作。

sudo su,可切换至 root 用户。

(3)更新软件包数据库

安装软件前,需要更新软件包数据库。因为 apt 是按照系统上的软件包数据库的信息,从仓库中下载的。如果没有更新软件包数据库,就可能与仓库中的软件包信息不一致,导致下载失败。

apt-get update

(4)安装和卸载

apt install / remove 。remove 会残留配置文件,purge 会把配置文件也删了。但是也有可能没删干净,查百度。

2、JDK

安装:

复制代码
// 更新软件包
apt-get update

// 查找 jdk 软件包
apt list |grep "jdk"

// 安装 jdk
apt install openjdk-17-jdk

// 查看 jdk 版本
java -version

卸载:

复制代码
// 查看已安装 jdk,忽略大小写
dpkg --list | grep -i jdk

// 删除 jdk
apt-get purge openjdk*

// 卸载 jdk
apt-get purge icedtea-* openjdk-*

// 查看是否卸载
dpkg --list | grep -i jdk

3、MySQL

安装:

XML 复制代码
// 查找
apt list |grep "mysql-server"

// 安装
apt install mysql-server

// 查看 mysql 状态
sudo systemctl status mysql

安装安全设置。使用 mysql 的脚本,解决不安全的默认设置:

复制代码
sudo mysql_secure_installation

设置密码:

复制代码
// 启动 mysql
mysql

// 设置密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '密码'

// 登录 mysql
mysql -uroot -p
输入密码

// 退出 mysql
quit;

卸载 mysql:

复制代码
// 停止 mysql
sudo systemctl stop mysql

// 卸载 mysql
sudo apt-get remove --purge mysql-server mysql-client mysql-common

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

// 清理残留
sudo apt-get autoremove
sudo apt-get autoclean

// 验证卸载结果
mysql --version

4、部署 Web 到 Linux

环境分为:开发环境 dev(开发时用的服务器),测试环境 test(测试人员测试时用的服务器),预发布环境 stage(用的真实用户数据,但是是内部人员使用发起的请求),灰度环境 prob(逐步上线,一开始只要少量服务器接收用户请求),发布环境/线上环境 prod(所有服务器都能接收用户请求)。

按这个过程,程序最终上线,就叫做部署。一般公司使用自动化部署工具(如 Jenkins),避免手动部署出错。

在服务器上创建数据库:

复制代码
// 执行 .sql 脚本文件
source 脚本文件

(1)Spring Boot 多平台文件配置

修改**.yml 配置文件**,比如数据库密码不一样。但是多个运行环境(idea 本地、服务器开发/测试......)配置文件改来改去很麻烦,就给不同运行环境有不同的 .yml 文件。

主配置文件:放公共的部分。@属性名@

XML 复制代码
# 哪个环境激活
spring:
  profiles:
    active: @profile.name@

# 应用服务 WEB 访问端口
server:
  port: 8080
# Mybatis-Plus 配置
mybatis-plus:
  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 配置打印 MyBatis ⽇志
    map-underscore-to-camel-case: true # 配置驼峰⾃动转换
# Spring Boot 日志配置
logging:
  logback:
    rollingPolicy:
      fileNamePattern: logs/spring_blog-%d{yyyy-MM-dd}-%i.log
      max-file-size: 10MB
      max-history: 30

配置 pom 文件:

XML 复制代码
    <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>

dev:

XML 复制代码
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/spring_blog?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: "hdalddnasl"
    driver-class-name: com.mysql.jdbc.Driver

prod:

XML 复制代码
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/spring_blog?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: "Zhamuyan200114@"
    driver-class-name: com.mysql.jdbc.Driver

(2)打包并上线

如果

clean >> 打包:

把 target 下的 jar 包上传到服务器,运行程序

XML 复制代码
// 后台运行,就算把连接服务器的终端关闭了,也能运行
​​nohup 执行的命令(java -jar jar包) &

// 也可以把输出的内容重定向到 指定文件
​​nohup 执行的命令(java -jar jar包) >文件名 &

查看程序是否运行:

云服务器开放端口号:若有多个端口号,以逗号分隔。

如果需要重启服务,需要先杀掉之前的服务进程,如 8080:kill -9 进程id

(3)存在的问题

spring-boot-starter-parent 自带自动化的资源过滤,如果 springboot 项目没有指定 spring-boot-starter-parent 的话,使用 @@ 的时候就会报 ScannerException 异常:

解决方案:启用对 src/main/resources 目录下资源文件的过滤处理,允许通过占位符动态替换配置文件中的变量。在 build 下加入,主要只需要过滤配置文件,避免把前端静态资源也过滤了。

XML 复制代码
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/application*</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
                <excludes>
                    <exclude>**/application*</exclude>
                </excludes>
            </resource>
        </resources>

jar中没有主清单属性错误。原因是 jar 包里的 META-INF 文件下的 MANIFEST.MF 中缺少 Main-Class 元素声明,即启动类所在包。

解决办法:

服务器本地 root 用户运行的 Spring Boot 程序无法连接本地数据库的 root 用户。解决办法:

查看本地 root 用户的认证方式:

sql 复制代码
SELECT User, Host, plugin FROM mysql.user WHERE User = 'root' AND Host = 'localhost';

auth_socket 认证方式,只能通过本地(只能用 UNIX 的 socket 方式登陆)登录、操作系统用户必须与数据库用户同名。在服务器上 root 用户直接通过命令行连接 本地 mysql (若不指定 --protocol=tcp,则默认通过本地的 mysqld.sock socket 文件连接)的 root 用户,无需登陆密码 。而 JDBC 默认通过 TCP/IP 协议通信,所以会出现程序连接本地数据库失败。

解决办法1(不建议):直接将本地 root 用户认证方式改为 mysql_native_password,这样就是通过密码连接。不建议的原因是,不能使用本地 root 用户免密连接的功能;再一个是没有 只给业务用户 指定的数据库操作权限安全。

sql 复制代码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '密码';

解决办法2(推荐):

sql 复制代码
// 创建专用业务用户
CREATE USER 'spring-blog'@'localhost' IDENTIFIED BY '你的密码';

// 赋予数据库操作权限
GRANT ALL PRIVILEGES ON 数据库名.* TO 'spring-blog'@'localhost';

// 刷新
FLUSH PRIVILEGES;

-parameters 参数问题。 IDEA 的 Java Compiler设置只影响本地编译,Maven/Gradle 打包时自行调用 Javac,不会读取 IDEA 的这些配置。

解决办法:在 maven 插件中配置参数。

XML 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <compilerArgs>
            <arg>-parameters</arg>
        </compilerArgs>
    </configuration>
</plugin>

如果还有问题,可以查看日志跟踪。

sql 复制代码
tail -100f logs/spring_blog.log | grep 'Exception'

因为 Spring Boot 项目已经配置了日志持久化,不想 nohup 将输入保存到 nohup.out,可以使用以下命令丢弃:

java 复制代码
nohup 命令 > /dev/null 2>&1 &

// 表示将标准输出(stdout)重定向到 /dev/null(Linux/Unix 系统中的一个特殊文件,也被称为"黑洞"或"空设备"。),丢弃所有正常输出。
> /dev/null

// 表示将标准错误输出(stderr)重定向到标准输出(stdout),也就是所有错误信息也一起丢弃。
2>&1

// 表示在后台运行该命令
&
相关推荐
Haven-3 小时前
Linux常见命令
linux·基本指令
IT 小阿姨(数据库)3 小时前
PgSQL中pg_stat_user_tables 和 pg_stat_user_objects参数详解
linux·运维·数据库·sql·postgresql·oracle
❀͜͡傀儡师3 小时前
Docker部署搜索引擎SearXNG
运维·docker·容器·searxng
MChine慕青3 小时前
顺序表与单链表:核心原理与实战应用
linux·c语言·开发语言·数据结构·c++·算法·链表
虎头金猫3 小时前
如何在Linux上使用Docker在本地部署开源PDF工具Stirling PDF:StirlingPDF+cpolar让专业操作像在线文档一样简单
linux·运维·ubuntu·docker·pdf·开源·centos
荣光波比4 小时前
Nginx 实战系列(七)—— Nginx一键安装脚本详解
运维·nginx·自动化·云计算
努力学习的小廉4 小时前
深入了解linux系统—— 线程同步
linux·服务器·数据库·算法
sinat_602035364 小时前
模块与包的导入
运维·服务器·开发语言·python
鲸屿1954 小时前
Ansible之playbook
服务器·网络·ansible