Nginx架构原理及使用

什么是Nginx?

代理服务器:代理服务器是介于客户端和Web服务器之间的一台特殊服务器,浏览器不是直接访问Web服务器获取资源,而是请求代理服务器,由代理服务器来向Web服务器获取所需资源,然后返回给浏览器。

正向代理:为了从Web服务器获取资源,客户端需要向代理发送一个请求并指定Web服务器,然后代理向Web服务器转交请求,并将获取的资源返回给客户端。客户端必须要进行一些特别的设置(如正向代理服务器的IP地址、代理程序的端口号)才能使用正向代理。正向代理的特点就是客户端明确知道想要访问的web服务器地址,而代理服务器向web服务器隐藏了客户端信息,典型正向代理应用就是我们访问外网所需的代理服务器。

反向代理:客户端直接发送普通请求,代理服务器把请求分发给具体的服务器进行处理,再将获取的资源反馈给客户端。客户端就像发送普通请求一样,不需要知道反向代理服务器的存在,不需要进行特殊的设置。Nginx本身可以作为一个HTTP服务器进行网站的发布处理(动静分离),nginx也  可以作为反向代理进行负载均衡的实现。由于防火墙的作用,Web服务器只允许反向代理服务器访问,而不允许客户端访问。防火墙和反向代理的共同作用保护了Web资源服务器,而客户端并不知情。反向代理的特点就是反向代理服务器向客户端隐藏了web服务器信息。典型应用就是我们的淘宝系统。当然很多情况下正向代理和反向代理是共存的。

Nginx的特点?

  • 跨平台:既可以在大多数Unix like OS编译运行,也有Windows移植版;
  • 配置简单
  • 非阻塞、高并发:官方测试能够支撑5万并发连接,在实际生产环境中跑到2~3万并发连接;
  • 事件驱动
  • 无需长连接、减轻web服务器压力:nginx代理和web服务器之间无需长连接,接收请求是异步的,即先将用户请求全部接收下来,再一次性发送给后端web服务器,极大的减轻web服务器的压力;
  • 支持web服务器故障检测:Nginx能够根据web服务器返回的状态码、超时信息等检测服务器是否出现故障,并及时返回错误的请求重新提交到其他节点。

Nginx的事件处理机制?

阻塞调用:如果在服务端采用阻塞调用的方式,当网络请求的读写事件没有准备好时,服务器的读写线程只能等待事件准备好,才能进行读写事件。于是服务器的读写线程只能进入内核等待,并让出CPU给其他线程用。对于单线程的Worker进程来说,cpu将空闲下来,同时外面又有大量网络事件在等待处理。因此服务器CPU就浪费了,cpu利用率上不去,更别谈高并发了。

非阻塞调用:如果在服务端采用非阻塞调用方式,当网络请求事件没有准备好时,服务器的读写线程将马上返回EAGAIN,告诉你事件还未准备好,待会再来看看。因此服务器的读写线程将先去做一些其他事情,然后再来看看事件好了没。这样CPU的利用率就高的多了。虽然不阻塞了,但是服务器读写线程得不时地来检查一下事件的状态,因此开销仍然不小。

异步非阻塞:如果在服务端采用非阻塞调用方式,且对客户端采用异步发送事件请求的方式,服务器就可以同时监控多个事件,并采用非阻塞的方式处理读写事件。以epoll为例,对于客户端,当事件没有准备好,就将事件放入epoll队列里面;对于服务端如果事件有事件准备好,就去处理,如果返回的是EAGAIN,那么继续将其放入epoll里面。因此就能做到只要有事件准备好就去处理,除非所有事件都没准备好,就在epoll里面等待。因此,我们就可以处理大量的并发了,当然,线程只有一个,这里的并发只是在不同请求间切换,但是这种切换是没有任何代价的,不需要进行上下文切换。

与多线程比较:与多线程相比,这种事件处理方式优势很大,不需要创建多个线程,没有上下文切换,并且每个请求占用的内存也很少,事件处理非常轻量级。并发数再多也不会导致武威的资源浪费(上下文切换)。

 

Nginx内部模型?

Nginx是以多进程的方式来工作的,当然nginx也是支持多线程的方式的,只是我们主流的方式还是多进程的方式,也是nginx的默认方式。

 (1) nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控 worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了 。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的 。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。 worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的 。

(2)Master接收到信号以后怎样进行处理(./nginx -s reload )?首先master进程在接到信号后,会先重新加载配置文件,然后再启动新的进程,并向所有老的进程发送信号,告诉他们可以光荣退休了。新的进程在启动后,就开始接收新的请求,而老的进程在收到来自master的信号后,就不再接收新的请求,并且在当前进程中的所有未处理完的请求处理完成后,再退出 .

(3) worker进程又是如何处理请求的呢?我们前面有提到,worker进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供80端口的http服务时,一个连接请求过来,每个进程都有可能处理这个连接,怎么做到的呢?首先,每个worker进程都是从master进程fork过来,在master进程里面,先建立好需要listen的socket之后,然后再fork出多个worker进程,这样每个worker进程都可以去accept这个socket(当然不是同一个socket,只是每个进程的这个socket会监控在同一个ip地址与端口,这个在网络协议里面是允许的)。一般来说,当一个连接进来后,所有在accept在这个socket上面的进程,都会收到通知,而只有一个进程可以accept这个连接,其它的则accept失败,这是所谓的惊群现象。当然,nginx也不会视而不见,所以nginx提供了一个accept_mutex这个东西,从名字上,我们可以看这是一个加在accept上的一把共享锁。有了这把锁之后,同一时刻,就只会有一个进程在accpet连接,这样就不会有惊群问题了。accept_mutex是一个可控选项,我们可以显示地关掉,默认是打开的。

(4)nginx采用这种进程模型有什么好处呢?采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快重新启动新的worker进程。当然,worker进程的异常退出,肯定是程序有bug了,异常退出,会导致当前worker上的所有请求失败,不过不会影响到所有请求,所以降低了风险。

(5)每个worker里面只有一个主线程,那能够处理的并发数很有限啊,何来高并发呢?nginx采用了异步非阻塞的方式来处理请求,也就是说,nginx是可以同时处理成千上万个请求的。我们之前说过,推荐设置worker的个数为cpu的核数,在这里就很容易理解了,一个worker只有一个线程,但可以处理几千个网络事件,更多的worker数,只会导致进程来竞争cpu资源了,从而带来不必要的上下文切换。而对于普通IIS服务器来说,每个请求会独占一个工作线程,当并发数上到几千时,就同时有几千的线程在处理请求了,这对操作系统来说,是个不小的挑战,线程带来的内存占用非常大,线程的上下文切换带来的cpu开销很大,自然性能就上不去了,而这些开销完全是没有意义的。 

 

Nginx是如何处理一个请求?

首先,nginx在启动时,会解析配置文件,得到需要监听的端口与ip地址,然后在nginx的master进程里面,先初始化好这个监控的socket(创建socket,设置addrreuse等选项,绑定到指定的ip地址端口,再listen),然后再fork(一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程 )出多个子进程出来,然后子进程会竞争accept新的连接。此时,客户端就可以向nginx发起连接了。当客户端与nginx进行三次握手,与nginx建立好一个连接后,此时,某一个子进程会accept成功,得到这个建立好的连接的socket,然后创建nginx对连接的封装,即ngx_connection_t结构体。接着,设置读写事件处理函数并添加读写事件来与客户端进行数据的交换。最后,nginx或客户端来主动关掉连接,到此,一个连接就寿终正寝了。 

当然,nginx也是可以作为客户端来请求其它server的数据的(如upstream模块),此时,与其它server创建的连接,也封装在ngx_connection_t中。作为客户端,nginx先获取一个ngx_connection_t结构体,然后创建socket,并设置socket的属性( 比如非阻塞)。然后再通过添加读写事件,调用connect/read/write来调用连接,最后关掉连接,并释放ngx_connection_t。 

说明:nginx在实现时,是通过一个连接池来管理的,每个worker进程都有一个独立的连接池,连接池的大小是worker_connections。这里的连接池里面保存的其实不是真实的连接,它只是一个worker_connections大小的一个ngx_connection_t结构的数组。并且,nginx会通过一个链表free_connections来保存所有的空闲ngx_connection_t,每次获取一个连接时,就从空闲连接链表中获取一个,用完后,再放回空闲连接链表里面。

对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。

Nginx典型应用场景?

负载均衡技术在现有网络结构之上提供了一种廉价、有效、透明的方法,它有两方面的含义:首先,大量的并发访问或数据流量分担到多台节点设备上分别处理,减少用户等待响应的时间;其次,单个重负载的运算分担 到多台节点设备上做并行处理,每个节点设备处理结束后,将结果汇总,返回给用户,系统处理能力得到大幅度提高。

nginx支持的负载均衡调度算法方式如下:

  1. weight轮询(默认):接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。 这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。

  2. ip_hash:每个请求按照发起客户端的ip的hash结果进行匹配,这样的算法下一个固定ip地址的客户端总会访问到同一个后端服务器,这也在一定程度上解决了集群部署环境下session共享的问题。

  3. fair:智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法。但是需要注意的是nginx默认不支持fair算法,如果要使用这种调度算法,请安装upstream_fair模块

  4. url_hash:按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在nginx作为静态服务器的情况下提高缓存效率。同样要注意nginx默认不支持这种调度算法,要使用的话需要安装nginx的hash软件包

Nginx应用说明?

Nginx作为http服务器参考:使用详解

Nginx作为反向代理服务器实现负载均衡和动静分离参考https://www.cnblogs.com/yyy116008/p/7072168.html

1、到官网下载Windows版本,下载地址:http://nginx.org/en/download.html

2、解压到磁盘任一目录

3、修改配置文件:具体参考备注。

4、启动服务:直接运行nginx.exe,缺点控制台窗口关闭,服务关闭。守护进程的方式启动:start nginx.exe

5、停止服务:nginx -s stop

重新加载配置:nginx -s  reload

Nginx常见配置说明

worker_processes 8;

#nginx进程数,建议设置为等于CPU总核心数

worker_connections 65535;

#单个进程最大连接数(最大连接数=连接数*进程数)

client_header_buffer_size 32k; #上传文件大小限制

large_client_header_buffers 4 64k; #设定请求缓

client_max_body_size 8m; #设定请求缓

autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。

tcp_nopush on; #防止网络阻塞

tcp_nodelay on; #防止网络阻塞

keepalive_timeout 120; #长连接超时时间,单位是秒

gzip on; #开启gzip压缩输出

gzip_min_length 1k; #最小压缩文件大小

gzip_buffers 4 16k; #压缩缓冲区

gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)

gzip_comp_level 2; #压缩等级

upstream blog.ha97.com {

#upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。

server 192.168.80.121:80 weight=3;

server 192.168.80.122:80 weight=2;

server 192.168.80.123:80 weight=3;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值