学习nginx的一点记录

一、nginx定义

Nginx是一款轻量级的高性能的,具备HTTP反向代理负载均衡的web服务器,同时还提供IMAP/POP3/SMTP服务,其特点是占用内存少并发能力强

二、nginx基本功能

1、部署多个虚拟主机

多个虚拟机就是指在nginx目录下建立多个文件夹,作为虚拟工作目录。使多个虚拟空间可以使用不同的地址访问。

在配置文件中设置如下:

server {
    listen       8001;
    server_name  localhost;
    location / {
    root   html8001;
        index  index.html index.htm;
    }
}
server {
    listen       8002;
    server_name  localhost;
    location / {
        root   html8002;
        index  index.html index.htm;
    }
}

2、反向代理

首先说一下正向代理,正向代理是指对客户端的代理,简单来说就是客户端想要访问某个资源,但是无法直接访问,于是通过代理服务器访问服务器,代理服务器是为客户端服务的,代理对象是客户端。反向代理是指代理对象是服务器,客户端访问的对象是代理服务器,然后由代理服务器将请求转到服务器,并将结果转到客户端。代理服务器由服务端部署,可以帮助服务端做负载均衡、网关等事情,减轻了服务端的压力,从而达到保护服务器的目的。

反向代理配置

 upstrem lxpsun {
    server 127.0.0.1:8080
}
server {
    listen    8080;
    listen    somename:8080;
    server_name somename alias another.alias;
    
    location / {
        proxy_pass //lxpsun;
        index index.html index.htm;
    }
}

在配置文件中将root即本地主机目的地址使用Proxy_pass替换,Proxy_pass对应的值为要访问的服务器域名,upstrem lxpsun即为域名对应的服务器IP地址。

3、负载均衡

负载均衡是指将多个请求按照某种策略分配不同的服务器上进行处理,其目的是避免服务器在短时间内接收大量的请求,导致服务器崩溃,也就是说给服务器分配的请求要尽可能的均衡。Nginx负载均衡通常需要使用反向代理,通过反向代理将请求交给服务器处理。

Nginx目前自带有三种负载均衡策略,分别是轮询策略、权重策略和ip_harsh策略,第三方策略有fair(根据响应时间)策略、url_harsh策略。

  • 轮询策略

轮询策略是Nginx默认的,通过将每个请求按顺序分配给服务器,如果有服务器挂掉,则从表中删除该服务器。该方法的优点是算法逻辑简单,缺点是未考虑到每台服务器之间的不同性能等因素,导致负载分配不均衡。

  • 权重策略

考虑到不同服务器处理请求的时间等因素,选择给处理请求较快的服务器分配的权重值大,反之,给处理请求较慢的服务器分配的权重值小。也就是给处理请求快的服务器更多的请求任务,给较慢的分配少一些的请求任务。保证负载的均衡性。

upstream lxpsun {
     server localhost:8080 weight=7;
     server localhost:8081 weight=3;
}

此时代表给8080端口的服务器分配70%的请求任务,给8081端口分配30%的请求任务。

  • ip_hash策略

前两个策略适合处理无状态的请求任务,也就是一次访问。但是当访问一些登录等需要保存客户端用户信息的网站,那么服务端需要保存session信息,便于下次访问。如果使用前两种策略,就会造成每次访问都要提供客户端信息。因此,通过ip计算对应的hash的结果进行分配,可以确保每次访问都会转到同一个服务器,避免了每次都要提供客户端信息。

upstream lxpsun {
    ip_hash;
    server localhost:8080;
    server localhost:8081;
}
  • farir(响应时间)策略

该策略根据服务器的响应时间进行分配,响应时间快的优先分配。

upstream lxpsun { 
    fair; 
    server localhost:8080;
    server localhost:8081;
}
  • url_hash策略

该方法与ip_hash策略相似,通过计算url并映射为hash值,使得同一个url访问同一个服务器,避免session等缓存不起作用。

upstream lxpsun { 
    hash $request_uri; 
    hash_method crc32; 
    server localhost:8080;
    server localhost:8081;
} 

其中hash_method表示使用该hash算法。

4、Web服务器

Nginx本身适合处理静态资源的访问,在动态请求任务方面,则不如Apache服务器。对于动静分离的项目来说,可以把如html、css、图片等静态资源放在Nginx服务器上,对于动态请求,可以反向代理给Apache等服务器去处理,以减轻服务器的访问压力。因此,Nginx比较适合接收大量的请求,可以体现出Nginx高并发的能力,并进行反向代理和负载均衡。此外,还可以将服务器返回的数据进行存储,使得下次相同的请求直接返回对应的值,起到了缓存作用。Nginx作为流量入口还可以当做网关使用。

三、nginx配置文件

Nginx的配置文件Nginx.conf总共可以分为三个部分,分别是:全局模块、event模块、http模块或其它模块。

   1、全局模块

主要做一些全局方面的Nginx配置,例如worker_process,该变量表示Nginx的worker进程的数量,值越大,并发处理的量也越多,也与服务器的硬件相关,一般设置为服务器的CPU或者核心的数量。

 

   2、event模块

event模块用于配置Nginx服务器与用户之间的网络连接,主要包含accept_mutex, multi_accept,worker_connections 和 use这几个配置。

  • accept_mutex  

该配置主要是解决“惊群”问题,由于Nginx后台采用多进程模式,也就是运行了多个worker_process进程,当请求来临时,会造成多个进程会被唤醒,获取请求,但是最终只能有一个进程得到并处理请求。因为唤醒的进程数过多时,会影响Nginx整体的性能,所以需要设置accept_mutex,当设置为on时,会一个个唤醒进程去接收请求,直到请求被处理。如果Nginx服务器worker进程较多,而请求较少时,适合开启这种设置。一般worker进程的个数与服务器的CPU个数有关,worker进程数较少,发生“惊群”情况也不会太严重,如果服务器本身访问量比较大的话,最好不要开启,Nginx默认关闭该设置。

  • multi-accept

设置是否同时接收多个请求。

  • worker_connections

设置单个worker进程最大连接个数,默认1024。

  • use

设置Nginx服务器用哪种方式去处理请求。分别有select、poll、epoll等。

events{ 
	accept_mutex on; 
	multi_accept on; 
	worker_commections 1024; 
	use epoll; 
}

详情请参考:(64条消息) nginx events 模块配置_小星星1991的博客-CSDN博客_nginx 的events

     3、http模块

http模块主要分为全局部分、多个server部分、以及server下的多个location部分。

  • 全局部分

全局部分主要用来设置客户端的类型、发送的请求大小、超时时间、 keepalive_timeout、是否开启文件压缩等。

  •  server部分

一个server部分相当于配置一个虚拟主机,server公共部分主要有listen和server_name两个设置,listen为监听的端口号,server_name为主机名,其他的还有ssl设置、proxy设置等。location部分主要用于根据请求的路径匹配要访问的资源或者代理服务器。root表示要访问的文件夹,proxy_pass表示代理服务器名或者地址,配合upstream模块使用,用于负载均衡,请见关于2.3负载均衡的说明。

四、为什么Nginx可以实现高并发

1、Nginx的工作过程

Nginx分为单工作进程(默认)和多工作进程模式。当Nginx服务器启动时,分别有一个master进程和一个或者多个worker进程。

master进程的作用:主要用于接收外界的信号、给worker进程发送消息、监控worker进程、当老的worker进程因异常退出后,及时开启新的worker进程补上。作为管理进程,他的主要任务是补齐worker进程、平滑升级、配置文件实时生效等。

worker进程的作用:主要用于接收请求,处理请求并返回数据。由于worker进程是由master进程fork过来的(包含listenfd,用于注册读事件)。当请求过来时,所有worker进程的listenfd都变成可读的,但最终只有一个进程能够处理该请求。

 

当客户端发送请求到master进程后,由master进程通知给worker进程,如果请求较少时可以开启accept_mutex,然后只能有一个worker进程抢到该请求。当worker进程抢到请求后,便使用 accept()接收到该请求,然后开始处理该请求,当请求需要IO操作或者访问其它服务器时,这个时候worker进程不会一直被阻塞,而是会注册一个事件,等缓冲区里有数据时,再通知worker进程处理,这样一来,worker进程就可以快速处理多个请求,实现高并发。

2、IO多路复用模型epoll

Nginx服务器采用的是多进程工作模式,在每个worker进程下,只有一个线程,如果采用阻塞IO处理请求的话,就会造成处理请求缓慢,那么就无法进行高并发处理,因此Nginx采用IO多路复用模型epoll进行处理。

首先当请求需要进行IO操作时,worker进程会将该请求对应的fd注册为一个事件,并与执行IO操作的驱动程序建立回调关系,当驱动程序执行完成后,就会回调该事件,并将该事件添加到就绪链表中,然后通知主线程。因为IO多路复用使用了异步阻塞,无需用户进程负责读写,异步 IO会负责将数据从内核空间拷贝到用户空间。这样情况下,Nginx就实现了在同一个进程中,利用同一个主线程去处理大量的请求。相较于select和poll来说,epoll能更好的完成IO复用操作,且不会随着请求的增多,处理能力反而降低。

关于select、poll和epoll的区别和工作原理请参考:

你管这破玩意叫 IO 多路复用? (qq.com)

一文搞懂select、poll和epoll区别 – 知乎 (zhihu.com)

本部分参考如下:

Nginx工作原理(Master+Worker) – yblackd – 博客园 (cnblogs.com)

Nginx为什么支持那么高的并发量? – 嗨,阿良 – 博客园 (cnblogs.com)

(64条消息) nginx基本功能和工作原理_妄想翻身的咸鱼的博客-CSDN博客_nginx作用和工作原理

五、Nginx和Apache服务器的区别

Nginx和Apache都是Web服务器,但是因为两个的工作原理不同,所以应用侧重点也有所不同。Apache也是多进程的工作模式,分别有prefork、worker和event三种工作模式。

1、Apache服务器的工作模式

prefork工作模式(默认)

在prefork模式中,服务器会先fork若干个进程,避免因同时有多个请求时,需要创建进程带来的开销。也是为了避免频繁的销毁和创建进程。在prefork模式下,一个进程在同一时间内只能处理一个请求。那么如果同时出现大量的请求时,就需要创建大量的进程来处理这些请求。在这种情况下,就会极大的加重操作系统的负担,这点也是和Nginx服务器不同的地方。

worker工作模式

在worker模式中,服务器也会先fork若干个进程,其工作模式是阻塞IO+多进程中+多线程模式,在每个进程中开启多个线程去处理请求。每个线程都会对应一个请求并处理。相比于prefork模式而言,开启线程需要的时间和资源也小于开启进程,适合于高并发的场景。但是缺点是随着请求的增多,线程也会随之增多,线程间的调度开销也会增长,且如果单个线程出现问题时,也会影响同一进程中的其它线程。

2、两者的缺点与结合

因此与Apache服务器相比,Nginx服务器适合处理IO密集型的请求。因为当请求需要IO处理时,Nginx服务器的worker进程会通过注册事件,然后去处理其它请求或者空闲,等待事件处理完毕后,再处理该请求。因此Nginx之所以更适合处理静态资源,也是因为只涉及到IO操作。

如果请求本身涉及到复杂的计算时,Nginx的worker进程也就只能处理该请求,而不能同时处理其它请求,和Apache服务器的prework工作模式差不多。不能发挥出Nginx的长处。

因此可以利用Nginx做反向代理和负载均衡,在前端接收大量的请求,然后根据负载均衡将请求转发到多个服务器。后台采用多个Apache服务器接收请求,处理请求,计算结果,并将结果返回给Nginx服务器。这样做利用了Nginx服务器高性能、高并发的优势,同时由于Apache服务器本身具有稳定性、模块多、功能强大,也能发挥出Apache服务器的优势。

Tags: