我朋友和Nginx的故事

206 阅读5分钟

这里记录工作中遇到的技术点,以及自己对生活的一些思考,周三或周五发布。

封面图

讲个和Nginx相关的故事

王晓*是我的发小,和我一样也是一个前端开发工程师。但是也有和我不一样的地方,比如他原先的专业不是计算机,而且统招学历也不是本科。但是他有一个特点,就是对技术特别有热情,喜欢去思考一些问题,琢磨一些事情。

去年10月份的时候他找到我,问题如果想要在团队里做一次技术的分享,应该怎么做。我说:你小子现在可以啊,都能在团队里分享技术了,这是不是马上就要升职加薪,出任CEO,赢取白富美,走上人生巅峰了?

他说不是,他说他在一家大厂的外包,但是特别希望能转成正式员工,6月份的时候也参加了正式员工的年中述职,过了十月份马上又该年终述职了,所以TL似乎又给了个机会,让他进行一次分享,看看整体是个什么情况。

我说那这不就是板上钉钉的事儿了吗。然后我就问他,你觉得讲Nginx的话应该从哪里开始呢,都讲些什么内容呢?

然后他回答说,觉的应该从linux的一些基本命令开始。因为虽然正式员工(一般t5,t6以上)级别的对这些命令都很熟悉,但是有很多wb的同学其实并不熟悉,而且Nginx的配置基本上都是需要用这些命令才能进行配置,虽然公司提供了配置nginx的平台,但是大部分时候其实还是需要用命令进行配置的,比如一些常用的VIM的基本命令等等。有了这个基础,对于前端来讲,剩下的其实就只需要了解一些Nginx的常用指令,以及这些指令的使用场景基本上就可以对付遇到的所有的配置问题了。

我说你这个思路完全可以啊,有些个PPT什么的吗,给我看下可以吗?他说他写了个文档。

文档如下:

Linux相关

虽然Linux的使用在 前端的工作中似乎并不那么常见,但是熟悉它基本的命令,可以在某些方面显著提高我们的工作效率。

工作目录切换

  • 显示当前目录
pwd
  • 切换工作路径
cd
  • 显示目录中文件信息
 ls -a | -l

文本文件编辑

查看内容较少的文件

 cat fileName
 # -n 显示行号
 cat -n  fileName
  • 查看内容较多的文件
 more  fileName
  • 查看文件的前n行
 head -n 20 fileName  
  • 查看文件的后n行
 tail -n 20 fileName  
  • 统计文本的行数,字数,字节数
 wc -l|-w|-c  fileName  

文件权限管理

  • 权限概念
# - 普通文件
# d 目录文件
# r  - read 读
# w  - write 写
# x  - 执行

例如:

docs的权限为:

# drwxr-xr-x    6 liximei  staff     192 Nov 22 20:57 docs

drwxr-xr-x 表示它是一个目录,所有者具有rwx权限,即可读、可写,可执行。所属组具有r-x权限,即可读,可执行。其他用户具有r-x,即也是可读,可执行的权限。

  • 修改文件权限 chmod
chmod  777 docs 

可以看到docs的权限已经发生了变化

  • 修改文件所有者和所属组
chown root:bin docs

文件目录管理

  • 创建文件 touch
 touch fileName
 
 # 参数
 # -a 仅修改读取时间
 # -m 仅修改修改时间
 # -d 同时修改读取时间 及 修改时间
  • 创建目录 mkdir
 mkdir dirName
 
 # 参数
 # -p  递归创建目录 a/b/c/d/e
  • 复制文件或目录 cp
 cp sourceFile targetFile
 
 # 参数
 # -r  递归复制目录 a/b/c/d/e
 # -p  保留原始文件属性
  • 剪切或重命名 mv

只保留剪切后的文件

 mv sourceFile targetFile
  • 删除文件或目录 rm
 rm targetFile
 
 # 参数
 # -r  删除目录 
  • 查看文件类型
file targetFile

常用系统命令

  • echo 在终端数组字符串或变量值
FileName = "terrence"
echo $FileName
  • date 显示及设置系统时间
  date 
  # 2021年11月30日 13:42:51
  date "+%Y-%m-%d %H:%M:%S"
  # 2021-11-30 13:44:19
  • 重启命令 reboot
reboot
  • 查看进程 ps
ps
  • 查看网卡配置 ifconfig
ifconfig
# windows 为ipconfig
  • 查看系统内核版本
uname
  • 查看历史执行过的命令
history

Vim相关

Vim文本编辑器,它默认会安装在当前所有的Linux操作系统上,是一款超棒的文本编辑器Vim基本操作。

Vim编辑器中设置了三种模式——命令模式、末行模式和编辑模式,每种模式分别又支持多种不同的命令快捷键,这大大提高了工作效率,而且用户在习惯之后也会觉得相当顺手。

  • 命令模式

光标移动,可对文本进行复制,粘贴,删除查找等操作。

  • 末行模式

保存或退出文档,设置编辑环境。

  • 编辑模式

主要用来录入文本。

在每次运行Vim编辑器时,默认进入命令模式,此时需要先切换到输入模式后再进行文档编写工作,而每次在编写完文档后需要先返回命令模式,然后再进入末行模式,执行文档的保存或退出操作。在Vim中,无法直接从输入模式切换到末行模式。

Nginx相关

启停控制

  • 启动

启动Nginx服务器直接运行安装目录下sbin目录中的二进制文件即可。

./sbin/Nginx
  • 停止
./sbin/Nginx -g term | int | quit

TERM和INT信号用于快速停止,QUIT用于平缓停止。

  • 重启

直接执行启动命令

service nginx restart

基础指令

  • error_log 错误日志
error_log logs/error.log error;
  • worker_connections 最大连接数

指令worker_connections主要用来设置允许每一个worker process同时开启的最大连接数。

# 默认值 512
worker_connections 512;
  • 网络资源媒体类型 mime-type
include mime.types;
  • 连接超时时间 keeplive_timeout
# 默认值 75s
keeplive_timeout 75s;
  • 网络监听 listen
# 监听IP 
listen 49.233.191.228;
# 监听端口
listen 80;
  • 虚拟主机 server_name
# 基于名称 
server_name www.909500.club;
# 基于IP
server_name 49.233.191.228;
  • location块儿
location [= |~|~*|^~] uri ...

“=”,用于标准uri前,要求请求字符串与uri严格匹配。如果已经匹配成功,就停止继续向下搜索并立即处理此请求。

“~”,用于表示uri包含正则表达式,并且区分大小写。

“~*”,用于表示uri包含正则表达式,并且不区分大小写。

“^~”,用于标准uri前,要求Nginx服务器找到标识uri和请求字符串匹配度最高的location后,立即使用此location处理请求,而不再使用location块中的正则uri和请求字符串做匹配

  • 请求的根目录 root
location / {
  root html;
}
  • 网站默认首页 index
location / {
  root html;
  index index.html index.htm;
}
  • 网站错误页面 error_page
error_page PageUrl

  • break 指令

用于中断当前相同作用域中的其他Nginx配置。与该指令处于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置无效。

  • return 指令

用于完成对请求的处理,直接向客户端返回响应状态代码。该指令可以在server块和location块以及if块中使用,其语法结构有以下几种:

return [texxt];
return code URL;
return URL;
  • rewrite指令

通过正则表达式的使用来改变URI。可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理。

  • ewrite_log指令

配置是否开启URL重写日志的输出功能。

rewrite_log on | off;
  • set指令

用于设置一个新的变量。

set root /ngixn/www/html;

nginx.conf文件

nginx.conf文件

# 全局块儿
worker_process 1;
# events块儿
events {
  worker_connections 1024;
}
# http块儿
http {
  include mime.types;
  default_type application/octet-stream;
  sendfile on;
  keepalice_timeout 65;
  # server 块儿
  server {
    listen 80;
    server_name localhost;
    location / {
      root html;
      index index.html index.htm;
    }
    error_page 500 502 503 504 /50x.html;
    location = /50x.html{
      root html;
    }
  }
}

nginx.conf一共由三部分组成,分别为全局块、events块和http块。在http块中,又包含http全局块、多个server块。每个server块中,可以包含server全局块和多个location块。在同一配置块中嵌套的配置块,各个之间不存在次序关系。

常见场景

反向代理

常用指令

  • proxy_pass

该指令用来设置被代理服务器的地址,可以是主机名称、IP地址加端口号等形式。其语法结构为。

proxy_pass http://www.909500.club;
  • upstream

如果被代理服务器是一组服务器的话,可以使用upstream指令配置后端服务器组。

upstream proxy_svrs {
  server http://192.168.1.1:8001/;
  server http://192.168.1.2:8001/;
  server http://192.168.1.3:8001/;
}

server{
  listen 80;
  server_name www.909500.club;
  location /{
    # 服务器组名称
    proxy_pass proxy_svrs;
  }
}

负载均衡

网络负载均衡技术的大致原理是利用一定的分配策略将网络负载平衡地分摊到网络集群的各个操作单元上,使得单个重负载任务能够分担到多个单元上并行处理,或者使得大量并发访问或数据流量分担到多个单元上分别处理,从而减少用户的等待响应时间。

对所有请求实现一般轮询规则

// 后端服务器组
upstream backend {
  server http://192.168.1.1:8001/;
  server http://192.168.1.2:8001/;
  server http://192.168.1.3:8001/;
}

server{
  listen 80;
  server_name www.909500.club;
  location /{
    # 服务器组名称
    proxy_pass http://backend;
  }
}

对所有请求实现加权轮询规则

// 后端服务器组
upstream backend {
  server http://192.168.1.1:80 weight=5;
  server http://192.168.1.2:80 weight=2;
  server http://192.168.1.3:80;
}

server{
  listen 80;
  server_name www.909500.club;
  location /{
    # 服务器组名称
    proxy_pass http://backend;
    #...
  }
}

对特定资源的负载均衡

// 后端服务器组
upstream videoBackend {
  server http://192.168.1.1:80 weight=5;
  server http://192.168.1.2:80 weight=2;
  server http://192.168.1.3:80;
}

upstream fileBackend {
  server http://192.168.1.4:80 weight=5;
  server http://192.168.1.5:80 weight=2;
  server http://192.168.1.6:80;
}
server{
  listen 80;
  server_name www.909500.club;
  location /video/ {
    # 服务器组名称
    proxy_pass http://videoBackend;
    #...
  }
  location /file/ {
    # 服务器组名称
    proxy_pass http://fileBackend;
    #...
  }
}

域名跳转

通过Rewrite功能可以实现一级域名跳转,也可以实现多级域名跳转。在server块中配置Rewrite功能即可。

server {
  listen 80;
  server_name www.909500.club;
  # 域名跳转
  rewrite ^/ http:www.myweb.info;
}

域名镜像

镜像网站是指将一个完全相同的网站分别放置到几个服务器上,并分别使用独立的URL,其中一个服务器上的网站叫主站,其他的为镜像网站。

镜像网站和主站没有太大区别,或者可算是主站的后备。镜像网站可以保存网页信息、历史性数据,以防止丢失。可以通过镜像网站提高网站在不同地区的响应速度。镜像网站可以平衡网站的流量负载,可以解决网络带宽限制、封锁等。

使用Nginx服务器的Rewrite功能可以轻松地实现域名镜像的跳转。其实原理很简单,就是在server块中配置Rewrite功能,将不同的镜像URL重写到指定的URL就可以了。

server {
  listen 80;
  server_name mirror1.909500.club;
  # 域名跳转
  rewrite ^(.*) http:mirror2.909500.club;
}

防盗链

盗链是一种损害原有网站合法利益,给原网站所在服务器造成额外负担的非法行为。

要实现防盗链,需要了解HTTP协议中的请求头部的Referer头域和采用URL的格式表示访问当前网页或者文件的源地址。通过该头域的值,我们可以检测到访问目标资源的源地址。这样,如果我们检测到Referer头域中的值并不是自己站点内的URL,就采取阻止措施,实现防盗链。但是,需要提醒大家的是,由于Referer头域中的值是可以被更改的,因此该方法不能够完全阻止所有的盗链行为。

Nginx配置中有一个指令valid_referers,用来获取Referer头域中的值,并且根据该值的情况给Nginx全局变量invalidreferer赋值。如果Referer头域中没有符合validreferers指令配置的值,invalid_referer赋值。如果Referer头域中没有符合valid_referers指令配置的值,invalid_referer变量将会被赋值为1。

  • 根据文件类型实现防盗链
server {
  listen 80;
  server_name www.909500.club;
  location ~* ^.+\(gif|jpg|png|swf|flv|rar|zip)$ {
    valid_referers none blocked servers_name www.909500.club;
    if($valid_referer){
      rewrite ^/ http:/www.909500.club/imgs/err.png;
    }
  }
  # 域名跳转
  rewrite ^(.*) http:mirror2.909500.club;
}

文件下载

文件下载有时候会遇到权限不足的问题,需要修改文件夹的权限 chomd 777

location /book {
#	root /usr/share/nginx/html;
	autoindex on;
	autoindex_exact_size off;
	autoindex_localtime on;
	if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx)$){
            add_header Content-Disposition: 'p_w_upload;';
         }
}

我看了这个文档后跟他说,我擦,你这个文档有点东西啊,你都写的这么清晰了,还需要我给你指导?

他说主要是不知道该怎么讲,没见过那么大阵仗,要给一二十号人分享,有的又不熟,有的还是领导,万一紧张了怎么办?

我说你就放轻松,按照自己的思路来,结合具体案例相对来说会比较有意思,不会那么枯燥,然后多问几个问题,来个互动啥的就行了。

然后又随便聊了聊,就散了。

再次见面是今年年初,我问他,怎么样转正了吗?

他说他辞职了...

最后

  • 公众号《JavaScript高级程序设计》
  • 公众号内回复”vue-router“ 或 ”router“即可收到 VueRouter源码分析的文档。
  • 回复”vuex“ 或 ”Vuex“即可收到 Vuex 源码分析的文档。

全文完,如果喜欢。

请点赞和"在看"吧,最好也加个"关注",或者分享到朋友圈。