源码:nginx – nginx
官网:nginx news
Nginx是俄罗斯人Igor Sysoev编写的轻量级Web服务器,它的发音为 [ˈendʒɪnks] ,它不仅是一个自由的、开源的、高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器。
Nginx以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡服务器。在性能上,Nginx占用很少的系统资源,能支持更多的并发连接,达到更高的访问效率;在功能上,Nginx是优秀的代理服务器和负载均衡服务器;在安装配置上,Nginx安装简单、配置灵活。
Nginx的稳定性、功能集、示例配置文件和低系统资源的消耗让他后来居上,在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。所以作为一个开发者,学会Nginx的使用和配置很有必要。
- 跨平台:可以在大多数Unix like 系统编译运行。而且也有Windows的移植版本。
- 配置异常简单:非常的简单,易上手。
- 非阻塞、高并发连接:数据复制时,磁盘I/O的第一阶段是非阻塞的。官方测试能支持5万并发连接,实际生产中能跑2~3万并发连接数(得益于Nginx采用了最新的epoll事件处理模型(消息队列)。
- Nginx代理和后端Web服务器间无需长连接;
- Nginx接收用户请求是异步的,即先将用户请求全部接收下来,再一次性发送到后端Web服务器,极大减轻后端Web服务器的压力。
- 发送响应报文时,是边接收来自后端Web服务器的数据,边发送给客户端。
- 网络依赖性低,理论上只要能够ping通就可以实施负载均衡,而且可以有效区分内网、外网流量。
- 支持内置服务器检测。Nginx能够根据应用服务器处理页面返回的状态码、超时信息等检测服务器是否出现故障,并及时返回错误的请求重新提交到其它节点上。
- 采用Master/worker多进程工作模式
- 此外还有内存消耗小、成本低廉(比F5硬件负载均衡器廉价太多)、节省带宽、稳定性高等特点
Nginx是以多进程的方式来工作的,当然Nginx也是支持多线程的方式的,只是我们主流的方式还是多进程的方式,也是Nginx的默认方式。Nginx采用多进程的方式有诸多好处。
Nginx在启动后,会有一个master进程和多个worker进程。master 进程并不处理网络请求,主要负责调度工作进程:加载配置、启动工作进程及非停升级。worker 进程负责处理网络请求与响应。
master进程主要用来管理worker进程,具体包括如下4个主要功能:
- 接收来自外界的信号。
- 向各worker进程发送信号。
- 监控woker进程的运行状态。
- 当woker进程退出后(异常情况下),会自动重新启动新的woker进程。
woker进程主要用来处理基本的网络事件:
- 多个worker进程之间是对等且相互独立的,他们同等竞争来自客户端的请求。
- 一个请求只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。
- worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致。同时,nginx为了更好的利用多核特性,具有cpu绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效。
首先,Nginx在启动时,会解析配置文件,得到需要监听的端口与IP地址,然后在Nginx的master进程里面,先初始化好这个监控的socket(创建socket,设置addrreuse等选项,绑定到指定的IP地址端口,再listen),然后再fork(一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程 )出多个子进程出来,然后子进程会竞争accept新的连接。
此时,客户端就可以向Nginx发起连接了。当客户端与Nginx进行三次握手,与Nginx建立好一个连接后,某一个子进程会accept成功,得到这个建立好的连接的socket,然后创建Nginx对连接的封装,即ngx_connection_t结构体。
接着,设置读写事件处理函数并添加读写事件来与客户端进行数据的交换。最后,Nginx或客户端来主动关掉连接,到此,一个连接就寿终正寝了。
【1】正向代理
案例1:
A同学打算开启他的创业之路,但是目前他遇到一个问题就是启动资金,于是他决定去找马云爸爸借钱,可想而知,最后碰一鼻子灰回来了,情急之下,他想到一个办法,找关系开后门,经过一番消息打探,原来A同学的大学老师王老师是马云的同学,于是A同学找到王老师,托王老师帮忙去马云那借500万过来,当然最后事成了。不过马云并不知道这钱是A同学借的,马云是借给王老师的,最后由王老师转交给A同学。这里的王老师在这个过程中扮演了一个非常关键的角色,就是代理,也可以说是正向代理,王老师代替A同学办这件事,这个过程中,真正借钱的人是谁,马云是不知道的,这点非常关键。
案例2:
我是一个用户A,我访问不了某网站C,但是我能访问一个代理服务器B。这个代理服务器B能访问那个我不能访问的网站C,于是我先连上代理服务器,告诉它我需要那个C网站的内容,代理服务器去取回来,然后返回给我。从网站C的角度,只在代理服务器来取内容的时候有一次记录。并不知道是用户的请求,也隐藏了用户的资料
结论:
正向代理 是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。
【2】反向代理
案例1:
大家都有过这样的经历,拨打10086客服电话,可能一个地区的10086客服有几个或者几十个,你永远都不需要关心在电话那头的是哪一个,叫什么,男的,还是女的,漂亮的还是帅气的,你都不关心,你关心的是你的问题能不能得到专业的解答,你只需要拨通了10086的总机号码,电话那头总会有人会回答你,只是有时慢有时快而已。那么这里的10086总机号码就是我们说的反向代理。客户不知道真正提供服务人的是谁。
案例2:
A用户访问 http://xxx.xxx.xxx/userList页面,但是这个网站并不存在userList页面,它是偷偷从另外一台服务器上取回来,然后作为自己的内容吐给用户,但用户并不知情。这里所提到的xxx.xxx.xxx 这个域名对应的服务器就设置了反向代理功能
结论:
反向代理正好相反,对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理 的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容 原本就是它自己的一样。
【3】共同点
【4】区别
到 官网 下载压缩包解压到本地,解压后的文件目录如下:
conf目录下的nginx.conf文件就是我们需要修改的配置文件
修改完配置文件,接下来需要启动Nginx:
方法一:直接双击nginx.exe,双击后会有一个黑色的弹窗一闪而过
方法二:打开cmd命令窗口,切换到nginx解压目录下,输入命令 nginx.exe 或者 start nginx,按Enter回车即可
启动后,我们在浏览器中输入你配置的ip和端口访问页面, Nginx默认的是 http://localhost:80,出现以下页面说明启动成功
【1】systemctl 系统命令
// 开机配置
systemctl enable nginx // 开机自动启动
systemctl disable nginx // 关闭开机自动启动
// 启动Nginx
systemctl start nginx // 启动Nginx成功后,可以直接访问主机IP, 此时会展示Nginx默认页面
// 停止Nginx
systemctl stop nginx
// 重启Nginx
systemctl restart nginx
// 重新加载Nginx
systemctl reload nginx
// 查看Nginx运行状态
systemctl status nginx
// 查看Nginx进程
ps -ef | grep nginx
// 杀死Nginx进程
kill -9 pid // 根据上面查看到的Nginx进程号, 杀死Nginx进程, -9表示强制结束进程
【2】Nginx 应用程序命令
nginx - s reload // 向主进程发送信号,重新加载配置文件,热重启
nginx - s reopen // 重启Nginx
nginx - s stop // 快速关闭
nginx - s quit // 等待工作进程处理完成后关闭
nginx - T // 查看当前Nginx最终的配置
nginx - t // 检查配置是否有问题
打开Nginx安装目录下的conf文件夹的nginx.conf文件,Nginx服务器的基础配置,默认的配置也存放在此。在 nginx.conf 的注释符号为: #,每个指令必须有分号结束
【1】Nginx配置文件的整体结构
1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker 进程数等。
2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。
5、location块:配置请求的路由,以及各种页面的处理情况。
【2】Nginx配置文件详细介绍
########### 每个指令必须有分号结束。#################
#user administrator administrators; #配置用户或者组,默认为nobody nobody。
#worker_processes 2; #允许生成的进程数,默认为1
#pid /nginx/pid/nginx.pid; #指定nginx进程运行文件存放地址
error_log log/error.log debug; #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
events {
accept_mutex on; #设置网路连接序列化,防止惊群现象发生,默认为on
multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为off
#use epoll; #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
worker_connections 1024; #最大连接数,默认为512
}
http {
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型,默认为text/plain
#access_log off; #取消服务日志
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
access_log log/access.log myFormat; #combined为日志格式的默认值
sendfile on; #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
error_page 404 https://www.baidu.com; #错误页
server {
keepalive_requests 120; #单连接请求上限次数。
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址
location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}
}
【1】Nginx用户(组)配置
#格式
user user [group];
#user:指定可以运行Nginx的用户
#group:指定可以运行Nginx的用户组(可选项)
#如果user指令不配置或者配置为 user nobody nobody ,则默认所有用户都可以启动Nginx进程。
【2】worker进程数配置
#格式
worker_processes number;
#这是Nginx服务器实现并发处理的关键配置
#number:Nginx进程最多可以产生的worker process数量,默认为1
#如果设置为auto,则Nginx将进行自动检测
【3】error日志路径配置
#格式
error_log file [可选日志级别];
#这个设置可以放入全局块,http块,server块
#file:指定日志输出到某个文件file
#常见的可选日志级别包括:info、debug、warn、error...等
【4】Nginx进程PID存放路径配置
#格式
pid file;
#由于Nginx进程是作为系统守护进程在后台运行,所以该选项用于自定义配置PID文件的保存路径
#file:指定其存放路径+文件名称
#如果不指定默认置于路径 logs/nginx.pid
【5】事件驱动模型配置
#格式
use model;
#model模型可选择项包括:select|poll|kqueue|epoll|resig|/dev/poll|eventport
【6】最大连接数配置
#格式
worker_connections number;
#number默认值为512,表示允许每一个worker进程可以同时开启的最大连接数
【7】配置文件的引入
#格式
include conf_file;
#该配置主要用于引入其他或者第三方的Nginx配置文件到当前的主配置文件中
【8】网络连接的序列化配置
#格式
accept_mutex on;
#设置网路连接序列化,防止惊群现象发生,默认为on
#惊群介绍:当一个新网络连接来到时,多个worker进程会被同时唤醒,但仅仅只有一个进程可以真正获得连接并处理之。如果每次唤醒的进程数目过多的话,其实是会影响一部分性能的。
#如果accept_mutex on,那么多个worker将是以串行方式来处理,其中有一个worker会被唤醒;反之若accept_mutex off,那么所有的worker都会被唤醒,不过只有一个worker能获取新连接,其它的worker会重新进入休眠状态。
【9】多网络连接接收配置
#格式
multi_accept off;
#该配置默认为off,意指每个worker进程一次只能接收一个新到达的网络连接
#如果想让每个Nginx的worker process都能同时接收多个网络连接,则需要开启此配置
【10】MIME-Type定义
#格式
include mime.types;
default_type type;
#MIME-Type指的是网络资源的媒体类型,即前端请求的资源类型
#include配置用于将mime.types文件包含进来
#type:默认为text/plain
我们打开conf目录下的mime.types文件查看内容,我们发现其就是一个types结构,里面包含了各种浏览器能够识别的MIME类型以及对应类型的文件后缀名,如下所示:
【11】访问日志配置
#格式
access_log path [format];
#path:自定义访问日志的路径+名称
#format:自定义服务日志的格式(可选项)
#access_log off; 取消服务日志
#自定义日志格式format
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for';
#使用
access_log log/access.log myFormat;
【12】连接超时配置
#格式
keepalive_timeout timeout [header_timeout];
#timeout 表示server端对连接的保持时间,默认75s
#header_timeout表示在应答报文头部的 Keep-Alive 域设置超时时间,可选项
#可以在http,server,location块配置
【13】sendfile配置
#格式
sendfile on;
#sendfile配置用于开启或关闭使用sendfile()系统调用来传输文件,默认off
#在很多Web Server中,都引入了sendfile的机制,来实现高性能文件传输
#可以在http块,server块,location块设置
【14】网络地址监听配置
#第一种:配置监听的IP地址
listen IP[:PORT];
#第二种:配置监听的端口
listen PORT;
listen 192.168.25.177:8080; # 监听特定IP和端口上的连接
listen 192.168.25.177; # 监听特定IP上所有端口的连接
listen 8080; # 监听特定端口上的所有IP的连接
【15】基于名称或IP的虚拟主机配置
#基于name
server_name name1 name2 ..;
#name可以有多个并列名称,而且此处的name支持正则表达式书写server_name ~^www\.codesheep\d+\.com$;
#基于IP
server_name IP地址
【16】location配置
#格式
location [ = | ~ | ~* | ^~ ] /uri/ {...};
#这里的uri可包含正则表达式的模糊匹配
#uri前面的方括号中的内容是可选项,几种常见的情形如下:
#'=':用于标准uri,进行字符串的精确匹配
#'~':用于正则uri,表示区分大小写的匹配
#'~*':用于正则uri,表示不区分大小写的匹配
#'^~':用于标准uri,^进行前缀匹配,~表示区分大小写
【17】根目录配置
#格式
root path;
#path:表示Nginx接收到请求以后查找资源的根目录路径
#也可以通过alias指令来更改location接收到的URI请求路径,指令为:
alias path; #path为修改后的根路径
【18】默认首页配置
#格式
index index_file ......;
#index_file可以包含多个用空格隔开的文件名,首先找到哪个页面,就使用哪个进行响应。
文章每周持续更新,可以微信搜索「 前端大集锦 」第一时间阅读,回复【视频】【书籍】领取200G视频资料和30本PDF书籍资料