从 web 开发的视角说一下在使用 Linux 时遇到的问题,主要是针对操作本身,因为指令在网上都可以查到,不会深入原理,但尽量实用。
基础认知#
为什么使用 Linux#
最初我使用 Linux 是因为我需要的应用在教程里只提供了 Linux 版本,于是我就按步骤把它部署起来,就这样顺其自然地用了下去,期间也解决了一些问题,在这个过程中,我逐渐产生了一些疑问:为什么使用 Linux 作为服务端,而不是我们日常使用更加熟悉的 Windows 系统,二者在服务端有什么区别?
1. 操作性#
在这点上,毋庸置疑是 Windows 更胜一筹,图形化界面操作友好,Windows Server 版相对于面向大众的版本在操作上也没有特别大的差别,大部分人应该还是对于微软这种一以贯之的风格更加习惯。
Linux 也有带图形界面的发行版,但作为服务器使用时这样反而丧失了一部分优势,图形壳程序会占用服务器宝贵的硬件资源,通常不做考虑。
2. 价格成本#
客观来说,Linux 开源免费,而 Windows Server 则需要付费授权。实际上多数情况我们购买云服务器的时候,这部分成本已经平摊了。
腾讯云选择 Windows Server 时的提示:
3. 稳定性#
Linux 是开源的,它的代码由全世界最优秀的程序员维护更新,如果有漏洞被发现也会被迅速修复。而 Windows 方面,由于我使用 Windows Server 的经验并没有多少,不做过多评价,但对于面向普通用户的版本,大家都有发言权,尽管微软的程序员非常优秀,但是 Windows 仍然会频繁地向你推送漏洞修复补丁,并且偶尔蓝屏、死机
Linux 对于用户是完全开放的,因为它假定用户知道自己在做什么,你可以操作系统中所有的文件,但 Linux 不会对你的操作负责,这就如同我们在安卓手机中获取 root 权限一样,你获取了底层文件的操作权限,可以按你自己的想法去修改系统,但这样手机的服务商就不再提供保修服务,因为你做出了超出他们预期的行为。
在 Windows 这边,不知道是不是大家都经历过被提示没有操作权限的情况,或者想设置权限却被告知没有权限的情况,我还遇到过微软自家的软件没有权限读取文件而无法识别已安装的应用程序的问题,这都是因为 Windows 较为复杂的权限系统。
为什么将权限系统放在稳定性这一节,因为在用户可以自由修改权限的情况下,系统的稳定性当然会受影响,在 Linux 操作中,我们可以很轻松的给文件设置 777 权限(最高的权限,在后面会说到),或者开放防火墙所有端口,而这无疑增加了系统运行的风险,所以在设计这部分的操作时,应该更加谨慎,先看看有没有其他的方法再进行操作。
选择不同的发行版#
严格来说,Linux 是内核而不是操作系统,借助于不同的发行版提供的操作系统相关组件才变成了操作系统,平常我们会简称为 Linux 系统,而实际上由于开源的特性,不同的分支会存在不小的差距。这部分涉及很多我不懂的专业知识,而且可以在网上查到很多说明比较,所以不在这里赘述,我想要说明的是在查找指令和资料时要注意先决条件,区分不同系统的操作。
这里借用一下菜鸟教程的图:
由于云服务商的问题,国内使用 CentOS 较多,总体是个很好上手的版本,这个版本是基于免费的 RHEL 的源代码重新编译成的,这两种都属于 Red Hat 公司。而其他的比如 Debian、Ubuntu 都是同样使用很广泛的系统,每一种发行版都有它所属于的社群在使用,并且还有大量自行编译的定制化版本。
但要注意的是 CentOS 8 已于 2021 年 12 月 31 日停止维护,Cent OS 7 将于 2024 年 6 月 30 日停止维护,这可能会成为一个隐患,在选择发行版时需要将其纳入考量。
腾讯云中选择系统时的镜像介绍:
Debian 是一款稳定、便捷、快速的 Linux 发行版,它拥有比大多数 Linux 发行版更为强大的软件包管理工具,是目前用于建站的首选服务器操作系统之一。
Ubuntu 是最热门的 Linux 发行版之一,是一款开放源代码的免费软件,基于 Debian Linux 操作系统,其易用性和稳定性均非常出色,并且拥有非常强大成熟的社区资源。
CentOS 是一款流行的开源 Linux 发行版,是 RHEL(Red Hat Enterprise Linux)源代码经过再编译而成。(注意:CentOS 社区将于 2024 年 6 月 30 日停止维护 CentOS 7,推荐您选用兼容 CentOS 8 的 OpenCloudOS 8 镜像替代。)
远程操作#
说了那么多,不如实际进入系统操作一下,使用云服务器时,虽然 web 端都会提供控制台,但是操作和功能都不能完全满足我们日常开发的需要,只要能支持 SSH 协议(默认端口 22)的软件都可以用于远程连接 Linux,也支持 Telnet 协议,但是由于 Telnet 协议本身并不安全,所以很多发行版都关闭了这一连接方式。
软件方面有很多选择,最简单直接的是 PuTTY,也可以使用 SecureCRT,我自己用得比较多的是 XShell,可以在官网申请免费的家庭/学校版本,完全可以满足日常的开发使用需求。
上传软件使用的是配套 XFTP,其他还可以选择 WinSCP 等。
目录结构#
默认文件目录如下:
有箭头指向的文件夹代表是软连接,可以理解为 Windows 的快捷方式,在 ftp 中可以看到图标左下角有个快捷方式的标志。
可以将一些常用的文件夹或文件链接到外层的目录方便日常使用。
通常我会在根目录再创建一个“app”文件夹,用来存放我们的 web 应用。
如果一个目录或文件名是以一个点开始,就表示这个目录或文件是一个隐藏目录或文件。即以默认方式査找(
ls
)时,不显示该目录或文件。可以使用ls -a
查看。
安装软件#
包安装工具#
在 Windows 中我们要安装一个新软件通常又两种情况,一种是打开 exe 文件或其他什么格式的安装程序,然后它会把文件安装到我们指定的目录下,同时也会在在注册表中添加信息或在系统盘中创建一些配置文件之类的,具体有很多情况,另一种是解压一个压缩包,打开即用,通常是一些相对简易的工具类软件。
在 Linux 中也是类似的,一方面你可以通过包管理工具来安装文件,它会自动将文件放置到固定的目录或者你指定的目录下,另一方面,你也可以下载压缩包,解压后再按照软件的具体用法去使用。
不过即使是安装包,在 Linux 中也是有区别的,在查资料的时候我们会看到 rpm、yum、apt 等各种各样格式的文件,它们都可以安装软件,但是却有着区别。
对比项 | rpm | yum | dpkg | apt |
---|---|---|---|---|
系列 | RedHat 系 | RedHat 系 | Debian 系 | Debian 系 |
区别 | 包安装工具 | 依赖管理工具 | 包安装工具 | 依赖管理工具 |
其中,包安装工具就是简单的安装工具,如果某个软件需要一个依赖库,你要先手动安装好才能继续,类似在 Windows 系统中运行一些软件需要先安装.Net Framework XX 这种依赖库,而依赖管理工具与前端的 npm 类似,会自动帮你安装所依赖的库,就是所谓的一键安装升级卸载工具。
从上面的表格中可以看出 RedHat 系和 Debian 系的安装工具有所区别,这也就是为什么我前面要强调先区分发行版系统再执行命令,在 Debian 中执行 yum 是不可行的,虽然我们可以把 yum 安装到 Debian 中,但这显然违反了设计的初衷,因为 Debian 已经有 apt 了,另外需要注意的是,即使是同样功能的依赖库,软件包的名字可能也是不一样的,可能是因为由不同的人开发了相同功能的软件,例如编译 Nginx 所需要的 5 个依赖:
RPM 包默认安装路径:
安装路径 | 含 义 |
---|---|
/etc/ | 配置文件安装目录 |
/usr/bin/ | 可执行的命令安装目录 |
/usr/lib/ | 程序所使用的函数库保存位置 |
/usr/share/doc/ | 基本的软件使用手册保存位置 |
/usr/share/man/ | 帮助文件保存位置 |
环境变量#
另外需要注意的是,指令文件通常不会作用到全局,需要我们自己去修改环境变量。如果有在 Windows 中安装过 Java 可能会有印象,我们安装完成后并不能在 cmd 中直接使用 Java 指令,而是要到对应的目录中才可以执行,但是通过设置环境变量,将指令文件映射到全局,就可以在任意文件夹目录使用 Java 指令,Linux 也是一样的,上文目录结构那张图中有个名为“sbin”的文件,其中存储的就是指令。有些人提供的安装脚本会帮你添加好全局指令,具体操作需要自己斟酌。
一些常用软件的安装流程我之前写过,可以参考下面两篇:
在 Linux 上从零开始部署前后端分离的 Vue+Spring boot 项目
守护进程#
守护进程这部分因为方法很多,而且都很容易查到,我没有写具体步骤,但是对于 web 开发来说很重要,一定要提一下。
当我第一次开发好应用,上传服务器,(中间略去一大堆步骤),启动使用也 OK 以后,以为一切万事大吉就把远程工具关掉了,然后发现应用就不能访问了,了解了之后才知道我只是创建了一个前台的任务,就像 Windows 系统中你当前打开的窗口,你关闭窗口程序自然不再运行,然而还是有很多程序不依赖于窗口运行,这些后台任务默默地在执行着工作,就像我们的网站 24 小时在线一样,所以我们也要通过守护进程这一形式把我们的应用也变成后台任务,方法有很多,可以参考下面这篇:
权限#
权限问题我们都会说很重要,但是在网上查资料的时候发现很多人改权限一点都不手软,这里以 Nginx 创建自定义日志为例,Nginx 默认配置第一行如下:
#user nobody;
意思是 Nginx 是通过 nobody 这个用户来启动的,所以 Nginx 的最大权限就是 nobody 的权限,虽然这里注释掉了,但是默认值就是 nobody,这个可以在系统中查到。
Nginx 的默认日志文件为/usr/local/nginx/logs/access.log
,通过下图可以看到它的权限 rwxrwxrwx,可以简单来说就是完全权限,任何人都可以读、写或删除,如果我们想让 Nginx 在 /usr/local/nginx/logs
这个目录中写自定义日志会得到没有权限的错误,因为 nobody 这个用户没有对这个目录的读写权限。
我查到一种很常见的解决方法:如果 nobody 没有读写权限,那么哪个用户有读写权限呢?root 肯定有,所以就把 Nginx 的用户改成了 root,这种思路看起来合理,但是这种权限操作却并不必要,回过头来思考一下,如果没有目录的读写权限,给目录设置相应用户的读写权限就可以了。
现在我们回到权限的设置上,rwx 其实很容易就能猜到分别代表读(用 r 表示)、写(用 w 表示)和执行(用 x 表示,针对可执行文件或目录),为什么有三个,看下图:
至于为什么最开始提到 777 权限,并且很多文章会让你执行 chmod 777
,这里面:
- r:表示读取,对应的数字为 4;
- w:表示写入,对应的数字为 2;
- x:表示执行,对应的数字为 1
通过 4、2、1 的组合,我们可以得到以下几种权限
- 0:没有权限,用 - 表示
- 4:读取权限,用 w 表示
- 5:读取和执行权限,用 rx 表示
- 6:读取和写入权限,用 rw 表示
- 7:读取、写入和执行权限,用 rwx 表示
所以 777 就表示不应该被滥用的最高权限。
注意#
还有很多零散的点需要注意一下不单独分章节了。
大小写#
这点很容易被忽视,但是遇到这个问题后很让人头疼,我们习惯使用的 Windows 系统文件名是大小写不敏感的,也就是说一个名字叫 a.txt
的文件,和一个名字叫 A.txt
是同名的,然而在 Linux 中是对大小写敏感的,这一点需要留意。
端口开放(防火墙)#
我们的 web 应用经常要暴露一些端口给外部访问,除了要在系统内部的防火墙中开放所需要的端口,还要在云服务器平台上开放相应的端口。另外,不要图省事把防火墙整个关掉。
编码格式及行尾格式#
- Linux 的换行,在每一行的末尾只有一个换行符(LF)
\n
, 行尾以\n
来标识 - Windows 的换行,在每一行的末尾是 一个回车(CR)
\r
和一个换行符(LF)\n
和,行尾以\r\n
来标识
所以两边文件互相转移时可能会有多余字符。
sudo#
在很多文章中,会有以sudo
开头的命令,它的作用是临时提升命令的权限,让它获得最高权限,也许能提高一些命令的成功率,但如果你已经是 root 用户了,加上sudo
也没用。
文本处理#
如果想在 Linux 中直接编辑文本会比想象中复杂,但是多操作几遍就能理解,条件允许的情况下我会在 ftp 中编辑文件。
编辑指令可以参考这篇