Linux背景知识
Linux是什么
Linux是一个操作系统和Window是并列关系。
Unix&Linux的发展

1、1969~1970年,贝尔实验室的Dennis Ritchie(左)和Ken Tompson(右)开发了Unix操作系统。
不知道大家看到这两张图片是否会觉得有些熟悉,没错他们也是"C语言之父"。他们本来是想开发一个操作系统,再开发过程中,发现当时的编程语言不太好用,于是两人就先开发了C语言。
2、Unix火了之后,衍生出很多的分支,其中有一支为"Minix"。由荷兰的Andrew S.Tanenbaum教授开发。源代码开放给大学教学和研究工作。

3、1991年,还在读大学的芬兰人Linus Benedict Torvalds基于Minux的启发,开发出了Linux的第一个版本。
除此之外,大佬在开发linux的时候,觉得现有的版本管理工具不太方便。于是便又开发了一个新版本管理工具,也就是现在广泛使用的git。
经过这么多年的发展,Linux已经成为世界第一大操作系统。
Linux发行版
Linux严格意义来说只是一个"操作系统内核"。
完整的操作系统 = 操作系统内核+配套的应用程序。
由于Linux是一个完全开源免费的内核,所以有些公司又基于Linux内核,提供了不同的配套程序。这就构成了不同的"发行版"。
企业中主要使用的是RedHat,CentOS(RedHat免费版本)和ubuntu。下面我们使用ubuntu进行讲解。
Linux的优势
- 开源(免费,便宜)
- 稳定(可以运行很多年,且不会发生重大问题)
- 安全(Linux只有管理员或者特定用户才能访问Linux内核)
- 自由(不会抢加商业产品和服务)
- 社区支持(Linux在全球社区都非常活跃和使用广泛,又很多志愿者在线帮我们解决问题)
关于Linux学习
1、基础命令
虽然Linux有图形化界面,但是在服务器设备上往往都是通过命令行的方式进行操作的,因此学习Linux命令就是使用Linux的重要基础。
2、部署javaweb项目
我们自己写的web项目,要想让其他用户能够访问,就需要发布到服务器上,这是我们下面要学习的重点内容。
Linux环境搭建
想要学习Linux,需要先有一个Linux环境。
这里博主推荐使用腾讯云购买云服务器:学生云服务器_学生云主机_学生云数据库_云+校园特惠套餐 - 腾讯云
1、通过学生认证后,可进行购买:
2、进入购买之后,需要把镜像切换为ubuntu 22.0.4LTS的,由于博主这里已经购买,无法给大家进行截图。
3、购买完成之后,可以在控制台中找到自己购买的服务器。点进去就可以看到服务器的ip地址
右下角为公网ip地址,稍后我们就会使用这个ip登录服务器。
4、设置root密码:点击更多->重置密码(这个环节可能需要手机短信验证)。
root密码建议设置稍微复杂一些,否则容易被黑客入侵!!!
在这个环节我们得到的三个重要信息:1、服务器的外网IP。2、服务器的管理员账户(固定为root)。3、管理员账户密码(在腾讯云网站上设置的)
Linux常用命令
点击这里的登录远程连接我们的服务器(这里的服务器不是在我们本机上的,而是在腾讯那边的)。
ls
语法:ls [选项] [目录或文件]
功能:对于目录,该命令列出该目录下的所有子目录与文件。对于文件,列出文件名以及其他信息。
可以看到我们,当前目录下存在如下目录和文件:
常用选项:
- -a 列出目录下的所有文件,包括以.开头的隐含文件。
- -d 将目录像文件一样显示,而不是显示其下的文件。如:ls -d指定目录
- -k 以k字节的形式标识文件的大小。ls-alk指定文件
- -l 列出文件的详细信息
- -r 对目录反向排序
- -t 以时间排序
- -R 列出所有子目录下的文件(递归)
pwd
语法:pwd
功能:显示用户当前所在的目录。
如图:显示我们当前处于根目录。

cd
Linux系统中,磁盘上的文件和目录被组成一棵目录树(类似我们之前讲的windows的文件),每个节点都是目录或者文件。
语法:cd目录名
功能:改变工作目录。将当前工作目录改变到指定目录下。
如图:进入了xmy这个目录里面

常用选项:
- cd .. 返回上级目录
- cd ~ 进入用户的根目录
- cd - 返回最近访问目录
Linux目录结构
Linux是一个树形目录结构:
几个特殊目录:
- / 根目录
- . 当前目录
- .. 当前目录的上级目录
绝对路径和相对路径
形如:/user/share/xmy/以根目录开头的,称为绝对路径。
形如:../xmy以.或者..开头的,称为相对路径。
操作相关
在Linux中,如果发现文件名过长或者忘记一部分可以只用tab间尝试补全、加快效率。
如果命令或者目录敲错了,可以ctrl+c取消当前命令。
mkdir
语法:mkdir [选项] dirname...
功能:在当前目录下创建一个名为"dirrname"的目录
如图就创建了一个xmy1的目录:
touch
语法:touch[选项]...文件...
功能:touch命令参数可更改文档或目录的日期时间,包括存取时间和更改时间,或者新建一个不存在的文件。
如图所示,在xmy1目录下创建了a.txt文件
vim
vim是一个知名的文本编辑器,使用 vim就可以进行文本编辑了。vim就相当于Windows记事本,只不过功能比记事本强大一些。
1、创建/打开文件
2、进入插入模式
vim打开文件后默认是**普通模式。**普通模式下键盘的按键表示一些特殊功能的快捷键。(例如按下j并不是输入字母"j",而是表示光标往下移动一行)。需要进入插入模式才能进行文本编辑。
使用i键可以进入到插入模式。 (左下角会提示INSERT),然后就可以像记事本一样正常编辑了。

3、保存
在插入模式下不能保存文件,需要先回到普通模式,按下Esc回到普通模式。
在普通模式下输入:w,再按下回车,即可保存文件

4、退出
在插入模式下不能退出,需要Esc回到普通模式。
退出时,分以下情况:
1、文件未修改:输入:q,再按下回车,即可退出。
2、文件修改并保存:使用:wq同时执行保存和退出。
3、文件修改,不希望保存:使:q!进行强制退出。
我们重新进入插入模式,添加一行文字,退回普通模式后使用:q进行退出,观察现象:
报出异常(此时文件是有修改的,无法使用:q退出):

我们使用:wq试试(注意这里先要使用ctrl+c强行终止):
我们使用下面要将的cat命令查看文件内容:
可以看到,我们新增的语句已经被保存了。
重复上面的步骤,测试:q!


cat
语法:cat [选项] [文件]
功能:查看目标文件的内容
示例:

rm
语法:rm [-f/-i/-r/-v] [dirName/dir]
功能删除文件或者目录
常用选项:
- -f 即使文件属性为只读(即写保护),亦直接删除
- -i 删除前逐一询问确认
- -r 删除目录及其的所有文件
使用rm来删除文本文件:
注意:千万不要运行 rm -rf /,尤其是在公司的生产服务器上。
cp
语法:cp [选项] 源文件或目录 目标文件或目录
功能:复制文件或目录
说明:cp指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把签名指定的所有文件或者目录复制到此目录中。若同时指定多个文件或目录,而最后的目的地并非一个已存在的目录,则会出现错误信息
常用选项:
- -f 强行复制文件或目录,不论目的文件或目录是否已经存在
- -i 覆盖文件之前先询问用户
- -r 递归处理,将指定目录下的文件与子目录一并处理。若源文件或目录的形态,不属于目录或符号链接,则一律视为普通文件处理
- -R 递归处理,将指定目录下的文件及子目录一并处理
举例:
mv
语法:mv [选项] 源文件或目录 目标文件或目录
功能:
- 视mv命令中第二个参数类型的不同(是目标文件还是目标目录),mv命令将文件重命名或将其移至一个新的目录中。
- 当第二个参数类型是文件时,mv命令完成文件重命名,此时,源文件只能有一个(也可以是源目录名),它将所给的源文件或目录重命名为给定的目标文件名。
- 当第二个参数是已存在的目录名称时,源文件或目录参数可以有多个,mv命令将个参数指定的源文件均移至目标目录中。
常用选项:
- -f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖。
- -i :若目标文件已经存在时,就会询问是否覆盖。
举例,将b.txt移动到上级目录中:
tail
语法:tail [必要参数] [选择参数] [文件]
功能:用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理。常用于查看日志文件。
选项:
- -f 循环读取
- -n <行数> 显示行数
我们可以尝试使用tail来读取后2行的数据(这里为了方便测试把刚才的"go go go"进行了保存):

grep
语法:grep [参数]...[文件]...
功能:用于查找文件中是否包含指定字符串,并显示对应的行。
选项:
- -n <行数> 显示的行数
- -w 全字匹配
- -r 递归查找。可以搜索多级目录下的所有文件。
- --color 高亮查找到的结果
- --include 指定查找某些文件
- --exclude 指定排除某些文件
例如,在b.txt中查找"hello":

ps
语法:ps [参数]...
功能:用于查看当前系统上运行的进程
选项:
- a 显示一个终端的所有进程
- u 以用户为主的格式来显示程序状况
- x 显示所有程序,不止是会话中的进程
- e 显示所有进程,包括系统守护进程
- f 显示完整格式输出
举例 :ps aux 显示系统上的所有进程

ps aux | grep "进程名" 通过"进程名"查找进程。

ps aux | grep "进程id" 通过"进程id"查找进程。

netstat
语法:netstat[参数]...
功能:查看系统上的网络状态
选项:
- -a 显示所有正在或不在侦听的套接字
- -n 显示数字形式地址而不是去解析主机、端口或用户名
- -p 显示套接字所属进程的PID和名称
举例:
netstat -anp:
netstat -anp | grep "进程名":
netstat -anp | grep "端口号":
管道
管道是一种古老的"进程间通信"的方式。在Linux指令中可以使用 | 作为管道标记。
意思是将前一个指令标准输出的内容,作为第二个指令的标准输入的内容。
举例:ps -ef | grep "java":

ps -ef | head -10:

以上就是Linux常见指令的全部内容了。
小结



搭建Java部署环境
apt
apt是Linux软件包管理工具,用于在Debian和相关Linux发行版上安装、更新、删除和管理ddeb软件包。
大多数apt命令都必须具有sudo权限的用户身份进行。
apt常用命令
列出所有软件包:apt list
这个命令输出所有包的列表,内容比较多,这里不做展示,我们还可以使用grep命令进行过滤输出:
apt list | grep "java"

更新软件包数据库
sudo apt -get update

apt实际上是在可用软件包的数据库上工作。如果数据库没有更新,系统将不知道是否有更新的软件包可用。所以在安装任何Linux系统时候,第一件事应该是更新apt数据库。
运行此命令,就能够看到从各种服务器检索到的软件包信息。
如果切换到root用户,命令前就不需要加sudo了。
切换root 用户:sudo su
安装软件包
sudo apt install package_name
这个我们后面安装jdk和mysq-server要用到,这里先不做演示。
移除软件包
sudo apt remove package_name
remove命令将卸载给定软件包,但可能会留下一些配置文件。如果要删除包含所有配置文件的软件包,请使用purge而不是remove。
JDK
接下来我们在我们的云服务器上下载JDK,下面的命令直接复制即可。
1、更新软件包
sudo apt-get update

2、安装openjdk
查找jdk包
apt list | grep "jdk"

安装jdk:
sudo apt install openjdk-17-jdk
因为博主这里已经下载过了,无法给大家进行演示,第一次下载,是会有一个选项,选择Y即可。
使用java -version 验证是否安装成功

MySQL
1、使用apt安装MySQL
查找安装包:
apt list | grep "mysql-server"

安装mysql:
sudo apt install mysql-server
这里安装过程中会有一个询问,全Y即可。

2、查看MySQL状态
sudo systemctl status mysql

3、MySQL安装安全设置
默认MySQL设置是不安全的,MySQL安装提供了一个安全脚本,用于解决不太安全的默认选项。
运行以下命令:
sudo mysql_secure_installation
这里安装过程中会有四个选项,依旧全Y即可。
4、设置密码
连接mysql服务器
sudo mysql
使用alter user 命令修改密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '要设置的密码'
这里博主建议大家把密码设置得复杂一些,防止被黑客攻击。
部署Web项目到Linux
什么是部署
工作中涉及到的环境有:
- 开发环境:开发人员写代码用的机器
- 测试环境:测试人员测试程序使用的机器
- 生产环境(线上环境):最终项目发布时所使用的机器。对稳定性要求很高。
把程序安装到生产环境上,这个过程就称为"部署",也叫"上线"。一旦部署成功,这个程序就能被公网中千千万万的普通用户访问到了。
环境配置
程序正常运行,需要保证环境和程序都要正确,我们需要先设置环境。
数据准备
按照之前的数据库建表脚本,在服务器上运行,建立相同的表结构。
下面尝试上线一个图书管理系统:
使用mysql -uroot -p,输入密码后,将下面的sql语句粘贴进去:
sql
-- 创建数据库
DROP DATABASE IF EXISTS book_test;
CREATE DATABASE book_test DEFAULT CHARACTER SET utf8mb4;
USE book_test;
-- 用户表
DROP TABLE IF EXISTS user_info;
CREATE TABLE user_info (
`id` INT NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR ( 128 ) NOT NULL,
`password` VARCHAR ( 128 ) NOT 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 book_info;
CREATE TABLE `book_info` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`book_name` VARCHAR ( 127 ) NOT NULL,
`author` VARCHAR ( 127 ) NOT NULL,
`count` INT ( 11 ) NOT NULL,
`price` DECIMAL (7,2 ) NOT NULL,
`publish` VARCHAR ( 256 ) NOT NULL,
`status` TINYINT ( 4 ) DEFAULT 1 COMMENT '0-无效, 1-正常, 2-不允许借阅',
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
-- 初始化数据
INSERT INTO user_info ( user_name, PASSWORD ) VALUES ( "admin", "admin" );
INSERT INTO user_info ( user_name, PASSWORD ) VALUES ( "zhangsan", "123456" );
-- 初始化图书数据
INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('活着', '余华', 29, 22.00, '北京文艺出版社');
INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('平凡的世界', '路遥', 5, 98.56, '北京十月文艺出版社');
INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('三体', '刘慈欣', 9, 102.67, '重庆出版社');
INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('金字塔原理', '麦肯锡', 16, 178.00, '民主与建设出版社');
程序配置文件修改
实际工作中,开发环境,测试环境以及生产环境的配置都是不一样的
比如:11111mysql的用户名和密码
我们可以针对不同的环境,设置不同的配置。
多平台文件配置
针对不同平台创建不同的配置文件,要求名字为application-XXX.yml或者application-XXX.properties。
下面以yml为例:

固定格式,只有后面的字母可以修改。
application-dev.yml(这是测试的配置文件,数据库密码为本机数据库密码):
bash
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/book_test?characterEncoding=utf8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
# ?? Mybatis ? xml ????
mapper-locations: classpath:mapper/*Mapper.xml
configuration: # ???? MyBatis??
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true #??????
application-prod.yml(这是要上线的配置文件,数据库密码应改为服务器上的数据库密码)
bash
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/book_test?characterEncoding=utf8&useSSL=false
username: root
password: 服务器上的数据库密码
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
# ?? Mybatis ? xml ????
mapper-locations: classpath:mapper/*Mapper.xml
configuration: # ???? MyBatis??
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true #??????
#设置日志文件名
logging:
file:
name: spring-library.log
在主配置文件application.yml中指定配置文件,并删除数据库相关配置
bash
spring:
profiles:
active: prod
但这么做,灵活度太低了,我们期望根据环境的变化选择配置文件~~。
从Maven中读取环境配置变量
将下面的标签添加在pom.xml文件中
XML
<profiles>
<profile>
<id>dev</id>
<properties>
<profile.name>dev</profile.name>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profile.name>prod</profile.name>
</properties>
</profile>
</profiles>
加在dependencies标签后面即可:
修改application.yml:
bash
spring:
profiles:
active: @profile.name@

构建项目并打包
在本地使用maven进行打包
1、如果Test代码中有与环境配置相关操作(比如数据库相关的操作),打包会失败,点击红框的图标,可以跳过测试。
2、勾选配置文件+clean->package

上传Jar包到服务器,并运行
1、上传Jar包
直接拖动打好的jar包到服务器上即可完成文件的上传

2、运行程序
nohup java -jar 文件名 &
nohup:后台运行程序。用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。
语法格式:
nohup Command [Arg...] [&]
参数说明:
Command:要执行的命令
Arg:一些参数,可以指定输出文件
&:让命令在后台执行,终端退出后命令仍旧执行
3、开放端口号
如果外网需要访问该服务,需要先服务器防火墙开放对应的端口号。
以腾讯云服务器举例:
1、进入防火墙管理页面
2、添加规则
开放在配置文件设置的端口号。
3、尝试访问当前网址

访问成功。
补充:
一个程序的正常运行需要程序的正确和环境的正确。同样的代码在Windows上可以运行成功,不一定在Linux上运行成功。不同的系统对代码的理解和支持是不同的。比如Windows的MySQL不区分大小写,但是Linux区分大小写。
服务不能正常访问的原因有很多,主要分以下几个方面:
1、服务未启动
- 使用ps -ef | grep java 查看程序是否在运行
- 使用curl http://127.0.0.1:端口号/....html看下是否有返回html页面,如果有返回,说明程序启动成功了,考虑端口未开放。
- 如果未启动成功,则需要查看对应的日志(使用tail -f来追踪日志,如:tail -100f spring-library.log | grep "Exception"),可能的问题有:1、数据库不存在 2、表不存在 3、数据库密码不正确 4、JDK安装版本不对,或者未安装 5、mysql未设置密码
2、http端口未开放
检查云服务器防火墙/安全组是否开放对应端口(如8080)
杀掉进程(慎用!!!)
1、使用ps -ef | grep java查看当前服务的进程Id

2、杀掉进程
kill -9 PID