从 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 项目

前端 Linux 部署命令与流程记录

守护进程

守护进程这部分因为方法很多,而且都很容易查到,我没有写具体步骤,但是对于 web 开发来说很重要,一定要提一下。

当我第一次开发好应用,上传服务器,(中间略去一大堆步骤),启动使用也 OK 以后,以为一切万事大吉就把远程工具关掉了,然后发现应用就不能访问了,了解了之后才知道我只是创建了一个前台的任务,就像 Windows 系统中你当前打开的窗口,你关闭窗口程序自然不再运行,然而还是有很多程序不依赖于窗口运行,这些后台任务默默地在执行着工作,就像我们的网站 24 小时在线一样,所以我们也要通过守护进程这一形式把我们的应用也变成后台任务,方法有很多,可以参考下面这篇:

Linux 守护进程的启动方法

权限

权限问题我们都会说很重要,但是在网上查资料的时候发现很多人改权限一点都不手软,这里以 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 中编辑文件。

编辑指令可以参考这篇

面向Web开发人员的Linux实用入门的更多相关文章

  1. 【Tomcat】面向初级 Web 开发人员的 Tomcat

    Apache Tomcat 应用服务器不再是高级 Web 系统开发人员的专用领域.在本教程中,Sing Li 将向初级 Web 开发人员展示如何利用他们当前的 Java™ 开发技能,使用 Tomcat ...

  2. Web开发人员常犯的10个错误

    说到开发一个运行在现代网络中的网站:Web开发人员需要选择虚拟主机平台和底层数据存储,准备编写HTML.CSS和JavaScript用的工具,要有设计执行方式,以及一些可用的JavaScript库/框 ...

  3. 初级 Web 开发人员的 Tomcat

    介绍使用 Tomcat 对 JavaServer Pages (JSP).servlet 和 Web 服务进行编程,Tomcat 是来自 Apache Foundation 的开源应用服务器.本教程引 ...

  4. 值得 Web 开发人员学习的20个 jQuery 实例教程

    这篇文章挑选了20个优秀的 jQuery 实例教程,这些 jQuery 教程将帮助你把你的网站提升到一个更高的水平.其中,既有网站中常用功能的的解决方案,也有极具吸引力的亮点功能的实现方法,相信通过对 ...

  5. SlimerJS – Web开发人员可编写 JS 控制的浏览器

    SlimerJS 是一个提供给 Web 开发人员,可通过脚本编程控制的浏览器.它可以让你使用 Javascript 脚本操纵一个网页:打开一个网页,点击链接,修改的内容等,这对于做功能测试,页面自动机 ...

  6. 面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序

    面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序 Ajax 为更好的 Web 应用程序铺平了道路 在 Web 应用程序开发中,页面重载循环是最大的一个使用障碍,对于 Java™ ...

  7. 成为Web开发人员的7个简单步骤

    你想成为一名 Web 开发人员,但现在你面前有这样一个问题,那就是你没有在高科技行业工作的经验.你上了一些课程,也花了时间在个人编码项目上,但是你的简历上关于“经验”的部分仍然不为企业承认.过渡到一个 ...

  8. Web开发人员vs网页设计师

    Web开发人员vs网页设计师 我们都遇到过,但实际的区别是什么?如果您是该领域的新手,请阅读详细内容,这些内容比您想象的更重要. 经过几周(或几个月)的规划和准备,进行市场调查,与其他企业家交谈,现在 ...

  9. 写给Web开发人员看的Nginx介绍

    译者注:不知道其他开发者是否和我一样,参与或者写了很多Web项目,但是却没有真正的去完整的部署应用,很多时候都是交给ops即运维的同学帮忙来做.而作为一个有节操的开发者,我认为了解一些服务器方面的知识 ...

  10. 【转】十步让你成为一名优秀的Web开发人员

    第一步:学好HTML HTML(超文本标记语言)是网页的核心,因此你首先应该学好它,不要害怕,HTML很容易学习的,但也很容易误用,学懂容易要学精还得费点功夫,但学好HTML是成为Web开发人员的基本 ...

随机推荐

  1. 计算机网络复习小结(3)-IPv4

    IPv4分组 一个IP分组由首部和数据两部分组成,首部前一部分的长度固定,共20B,是所有IP分组必须具有的.在IP数据报首部中有三个关于长度的标记,一个是首部长度,一个是总长度,一个是片偏移,基本单 ...

  2. 通过n个线程顺序打印26个英文字母

    通过n个线程顺序打印26个英文字母,例如 n=3 则输出: thread0: a thread1: b thread2: c thread0: d 方案一:轮询 多个线程不断轮询是否是该线程执行任务. ...

  3. NIO基本介绍

    同步和异步,同步指的是应用程序会直接参与IO读写操作,用阻塞或者长轮询的方式来获取数据.异步指的是IO交给操作系统,完成IO读写后通知程序,程序直接拿走数据. BIO:同步阻塞式IO,服务器实现模式为 ...

  4. e.target和this区别

    首先,this是指向当前事件所绑定的元素 e.target指向事件执行时所点击区域的元素, 易混淆点,当鼠标所点击的元素有子元素,e.target指向子元素,若没有,则和this一样指向事件所绑定的事 ...

  5. PHP Redis - Hash (哈希)

    Redis hash 是一个string类型的field和value的映射表,特别适合用于存储对象. Redis 中每个 hash 可以存储  232-1(4294967295) 键值对 赋值(hse ...

  6. 小梅哥课程学习——LED花式玩法(从计数器器到线性序列机)——实验六

    //每隔10ms,让led灯的一个8状态循环执行一次(每个变化时间值小一点,方便测试比如设置为10us) 源代码 module counter_led_6(    clk,    reset_n,   ...

  7. 学习JavaScript第五周

    MySQL基本内容: 访问:2种 ​ 1.图形化界面 - 傻瓜式 ​ 要求:同时打开apache和mysql ​ 访问:127.0.0.1:端口号/phpmyadmin ​ localhost:端口号 ...

  8. org.nutz.http.Http忽略https SSL证书验证

    访问的是一个https get请求,报错需要SSL证书验证,以下方法直接跳过 boolean check = Http.disableJvmHttpsCheck(); // 忽略https的证书检查

  9. java15配置环境后java_version无反应(不显示“不是内部或外部命令”)

    重新装了jdk15来使用eclipse 配置完环境变量之后打开cmd输入 java -version 好家伙,居然一点反映都没有, 然后傻乎乎的跑回去重新配置JAVA_HOME和path 还是没用,细 ...

  10. SQL Server 分页问题

    ------------- SQL Server 1.使用row_number分页 declare @PageSize int = 5 declare @PageIndex int = 1 selec ...