Nginx

Nginx 基本概念

什么是 Nginx

Nginx 是一个高性能的 HTTP 和反向代理的 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务。Nginx 在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。也可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走 web 服务器,只要你正则写的没问题,又有相对应的服务器解决方案,你就可以随心所欲的玩,而且 Nginx 可以对返回结果进行错误页跳转,异常判断等。同时 Nginx 也可以通过负载均衡和高可用集群实现更加高性能的服务,比如被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器。

反向代理

了解反向代理之前,我们首先了解一下什么是正向代理

正向代理,就是在客户端(浏览器)配置代理服务器,通过代理服务器进行互联网访问,也就是说代理对象是客户端,不知道服务端是谁,比如把局域网外的 Internet 想象成一个巨大的资源库,则局域网中的客户端要访 问 Internet,则需要通过在客户端配置代理服务器来访问,这种代理服务就称为正向代理。
image


反向代理,就是客户端不需要任何配置就能访问(无感知),只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器,获取数据后再返回给客户端。对外就一个服务器,暴露的是反向代理服务器地址,隐藏了真实服务器IP地址。代理对象是服务端,不知道客户端是谁。
image

负载均衡

非并发架构模式下,客户端发送多个请求到服务器,服务器处理请求,有些可能要访问数据库,服务器处理完毕后再将结果返回客户端,但是这种架构模式只适合并发请求少的情况。
image

但是当客户端发送多个请求到服务器,服务器处理请求,有一些可能要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。当访问量很大时,单个服务器解决不了,这时我们可以通过增加服务器的数量,然后利用反向代理服务器(Nginx)将请求分发到各个服务器上(按照不同的负载策略),也就是将原先请求集中到单个服务器上的情况,改为将请求分发到多个服务器上,这就是所谓的负载均衡。
image

Nginx 的负载均衡内置策略包括以下三种:轮询、加权轮询以及 Ip_hash。轮询就是平均分发,比如10个请求,3个服务器,那每个服务器依次分发请求,也就是如下左图所示。加权轮询就是给每个服务器配置权重,权重越大,处理的请求越多,如下右图所示。
image

Ip_hash 算法,对客户端请求的 ip 进行 hash 操作,然后根据 hash 结果将同一个客户端 ip 的请求分发给同一台服务器进行处理,可以解决 session 不共享的问题。
image


动静分离

一般来说,我们的项目存在动态资源以及静态资源,但是当客户端请求静态资源时,反向代理服务器每次都通过服务器去找,那么此时会造成时间以及服务器的损耗,那么为了加快网站的解析速度,可以把动态页面和静态页面有不同的服务器来解析,减少服务器压力,加快解析速度,这就是动静分离。
image

下载安装

  • 安装编译工具
    yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
  • 下载 Nginx
    wget http://nginx.org/download/nginx-1.9.9.tar.gz
  • 解压
    tar zxvf nginx-1.9.9.tar.gz -C /usr/local
  • 配置
    ./configure --prefix=/usr/local/nginx
  • 编译
    make
  • 安装
    make install
  • 启动
    ./sbin/nginx

Nginx 配置文件

Nginx 的配置文件是 nginx.conf,也是整个 Nginx 功能实现的核心,下面则是配置文件的基本骨架以及每个部分的详细说明。

###### 全局块(events以上部分)

###### events块
events {
   ...
}
###### http块
http {
    ##### http全局块(server以上部分)
	
    ##### server块
    server { 
    	##### server全局块(location以上部分)
		
        ##### location块
        location [PATTERN] {
            ...
        }
        location [PATTERN] {
            ...
        }
    }
    server {
      ...
    }
}

全局块是从配置文件开始到 events 块之间的内容,主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker_processes 数、进程 PID 存放路径、日志类型和存放路径以及配置文件的引入等。

# 定义Nginx运行的用户和用户组
user www www;

# Nginx进程数,也就是Work的数量,建议设置为等于CPU总核心数
worker_processes 8;

# 全局错误日志保存路径以及类型,类型包括[ debug | info | notice | warn | error | crit ]
error_log /usr/local/nginx/logs/error.log info;

# 进程pid文件
pid /usr/local/nginx/logs/nginx.pid;

# 指定进程可以打开的最多文件描述符数目,也就是工作模式与连接数上限,最好与最多打开文件数(ulimit -n)保持一致
worker_rlimit_nofile 65535;

events块主要配置影响 Nginx 服务器或与用户的网络连接,主要包括每个 work_process 的最大连接数、选取哪种事件驱动模型处理连接请求、是否允许同时接受多个网路连接以及是否开启多个网络连接序列化等。

events {
    # 参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]
    # epoll是高性能网络I/O模型,linux建议epoll,如果跑在FreeBSD上面,就用kqueue模型。
    use epoll;

    # 单个进程最大连接数(最大连接数=连接数*进程数),理论最大65535
    worker_connections 65535;

    # keepalive超时时间。
    keepalive_timeout 60;

    # 客户端分页大小,必须是系统分页大小的整数倍,可以通过getconf PAGESIZE获取系统分页大小
    client_header_buffer_size 4k;

    # 开启文件缓存,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
    open_file_cache max=65535 inactive=60s;

    # 指多长时间检查一次缓存的有效信息,默认60s,当有一个文件在inactive时间内一次没被使用,它将被移除。
    open_file_cache_valid 80s;

    # 指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态,默认是1
    open_file_cache_min_uses 1;

    # 指定是否在搜索一个文件是记录cache错误,默认off
    open_file_cache_errors on;
}

http全局块可以配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。

http {
    # 文件扩展名与文件类型映射表
    include mime.types;

    # 默认文件类型
    default_type application/octet-stream;

    # 服务器名字的hash表大小
    server_names_hash_bucket_size 128;

    # 客户端分页大小,必须是系统分页大小的整数倍,可以通过getconf PAGESIZE获取系统分页大小
    client_header_buffer_size 32k;

    # 客户请求头缓冲大小,如果上面的buffer过大,采用下面的
    large_client_header_buffers 4 64k;

    # 设定通过nginx上传文件的大小
    client_max_body_size 8m;

    # 开启高效文件传输模式,普通应用必须设置为on,如果应用磁盘IO重负载应用,可设置为off
    sendfile on;

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

    # 此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
    tcp_nopush on;
    tcp_nodelay on;

    # keepalive超时时间,单位是秒
    keepalive_timeout 120;

    #FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;

    # gzip模块设置
    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;    #压缩等级
    #压缩类型,默认就已经包含textml,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
    gzip_types text/plain application/x-javascript text/css application/xml;
    gzip_vary on;

    # 开启限制IP连接数的时候需要使用
    # limit_zone crawler $binary_remote_addr 10m;
}

server块,每个 server 块就相当于一个虚拟主机,一个 http 中可以有多个 server。server全局块,主要配置虚拟主机的相关参数,比如本虚拟机主机的监听配置和本虚拟主机的名称或IP配置。location块,一个 server 块可以配置多个 location 块,这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称 (也可以是IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理,比如配置请求的路由,以及各种页面的处理情况,包括地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

http {
    # 虚拟主机的配置
    server {
        # 监听端口
        listen 80;
        # 域名可以有多个,用空格隔开
        server_name www.jd.com jd.com 192.168.1.11;

        # 日志格式设定
        # $remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
        # $remote_user:用来记录客户端用户名称;
        # $time_local: 用来记录访问时间与时区;
        # $request: 用来记录请求的url与http协议;
        # $status: 用来记录请求状态;成功是200,
        # $body_bytes_sent :记录发送给客户端文件主体内容大小;
        # $http_referer:用来记录从那个页面链接访问过来的;
        # $http_user_agent:记录客户浏览器的相关信息;
        # 通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。
        #反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
        log_format access '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" $http_x_forwarded_for';

        # 定义本虚拟主机的访问日志
        access_log  /usr/local/nginx/logs/host.access.log  main;
        access_log  /usr/local/nginx/logs/host.access.404.log  log404;

        #对 "/" 启用反向代理
        location / {
            proxy_pass http://127.0.0.1:88;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            # 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            # 以下是一些反向代理的配置,可选。
            proxy_set_header Host $host;
            # 允许客户端请求的最大单文件字节数
            client_max_body_size 10m;
            # 缓冲区代理缓冲用户端请求的最大字节数,
            client_body_buffer_size 128k;
            # 表示使nginx阻止HTTP应答代码为400或者更高的应答。
            proxy_intercept_errors on;
            # nginx跟后端服务器连接超时时间(代理连接超时),就是发起握手等候响应超时时间
            proxy_connect_timeout 90;
            #后端服务器数据回传时间(代理发送超时),就是在规定时间之内后端服务器必须传完所有的数据
            proxy_send_timeout 90;

            #连接成功后,后端服务器响应时间(代理接收超时),就是等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)
            proxy_read_timeout 90;

            # 设置代理服务器(nginx)保存用户头信息的缓冲区大小
            proxy_buffer_size 4k;

            # proxy_buffers缓冲区,网页平均在32k以下的设置
            proxy_buffers 4 32k;

            #高负荷下缓冲大小(proxy_buffers*2)
            proxy_busy_buffers_size 64k;

            # 设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
            # 设定缓存文件夹大小,大于这个值,将从upstream服务器传
            proxy_temp_file_write_size 64k;
        }
    }
}

Nginx 配置实例

所有的场景配置都是基于 location 不同的匹配规则进行的,所以在开始尝试之前,先了解一些 location 的匹配规则。location 的语法是 location [=|~|~*|^~] uri { … },其中,方括号中的四种标识符是可选项,用来改变请求字符串和 URI 的匹配方式。URI 是待匹配的请求字符串,可以是不包含正则的字符串,这种模式被称为“标准的 URI";也可以包含正则,这种模式被称为"正则 URI"。例如:

# 标准URI
location / {
    root /var/www/html;
}

# 正则URI
location ~ .*\.(php|php5)?$ {
  root /var/www/html;
  ……
}

四种可选标识符是用来改变请求字符串和 URI 的匹配方式,其中

  • "=" 是精准匹配,用于标准 URI 前,要求请求字符串和 URI 严格匹配,如果匹配成功就停止匹配,立即执行该location里-面的请求;
  • "~" 是正则匹配,用于正则 URI 前,表示 URI 里面包含正则,并且区分大小写;
  • "~*" 是正则匹配,用于正则 URI 前,表示 URI 里面包含正则,不区分大小写;
  • "^~" 是非正则匹配,用于标准 URI 前,nginx服务器匹配到前缀最多的uri后就结束,该模式匹配成功后,不会使用正则匹配。
# "=" 精准匹配
location = /news/ {
    echo "test1";
}
#  "~" 区分大小写正则匹配
location ~ \.(html) {
    echo 'test2';
}
# "~*" 不区分大小写的正则匹配
location ~* \.(html){
            echo 'test4';
}
# "^~" 不进行正则匹配的标准匹配,只匹配前缀
location ^~ /index/ {
    echo 'test5';
}

反向代理

实现反向代理时,当我访问反向代理服务器时,代理服务器根据不同的匹配规则,跳转到不同的服务器,从而做出响应。首先,我们在A服务器中配置 Nginx 服务器地址映射(host文件),当我们访问此地址时,Nginx 通过不同的匹配规则,转发到不同的服务器进行处理。

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    # ...
    server {
        listen       80;
        server_name  192.168.1.11;
        # 配置反向代理,当访问根目录时,跳转到8080服务器
        location / {
            root   html;
            proxy_pass 192.168.1.11:8080
            index  index.html index.htm;
        }
        # 配置反向代理,当访问路径包含dev-api时,跳转到8081服务器
        location ~ /dev-api {
            root   html;
            proxy_pass 192.168.1.11:8082
        }
        # 配置反向代理,当访问路径包含dev-api时,跳转到8081服务器
        location ~ /prod-api {
            proxy_pass  192.168.1.11:8083
        }
    }
}

负载均衡

负载均衡即是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快,给用户很好的体验。当我们通过A服务器的地址访问时,Nginx 会根据不同的分配策略自动的选择要转发的服务器,从而保证服务的高性能,以下是不同策略的负责均衡:

# 轮询:每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
upstream myserver {
    server 208.208.128.122:8081;
    server 208.208.128.122:8082;
}
server {
    listen       80;
    server_name  208.208.128.122;
    location / {
        root   html;
        # 负载均衡服务器名称
        proxy_pass   http://myserver;
        index  index.html index.htm;
    }
}
# 权重:权重越高被分配的客户端越多
upstream myserver {
    server 208.208.128.122:8081 weight=10;   # 指定权重
    server 208.208.128.122:8082 weight=10;
}
server {
    listen       80;
    server_name  208.208.128.122;
    location / {
        root   html;
        # 负载均衡服务器名称
        proxy_pass   http://myserver;
        index  index.html index.htm;
    }
}
# ip_hash:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题
upstream myserver {
    # 指定为ip_hash的方式
    ip_hash;
    server 208.208.128.122:8081;
    server 208.208.128.122:8082;
}
server {
    listen       80;
    server_name  208.208.128.122;
    location / {
        root   html;
        # 负载均衡服务器名称
        proxy_pass   http://myserver;
        index  index.html index.htm;
    }
}

# fair: 扩展策略,按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream myserver {
    server 208.208.128.122:8081;
    server 208.208.128.122:8082;
    # 指定为fair方式
    fair;
}
server {
    listen       80;
    server_name  208.208.128.122;
    location / {
        root   html;
        proxy_pass   http://myserver;
        index  index.html index.htm;
    }
}

动静分离

Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用 Nginx 处理静态页面,Tomcat 处理动态页面。动静分离从目前实现角度来讲大致分为两种:

  • 一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;
  • 一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开。

通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。具体 Expires 定义:给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可, 所以不会产生额外的流量,不适合经常变动的资源,我这里设置 30d,表示在这30天之内访问这个 URL,发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态码 200。

server {
    listen       80;
    server_name  192.168.1.11;
    location / {
        proxy_next_upstream http_502 http_504 error timeout invalid_header;
        proxy_pass http://localhost:8082;
        # 真实的客户端IP
        proxy_set_header   X-Real-IP        $remote_addr; 
        # 请求头中Host信息
        proxy_set_header   Host             $host; 
        # 代理路由信息,此处取IP有安全隐患
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        # 真实的用户访问协议
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

    #静态文件交给nginx处理
    location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
        root /static;
        expires 30d;
    }
    #静态文件交给nginx处理
    location ~ .*\.(js|css)?$ {
        root /static;
        expires 1h;
    }
}

集群高可用

客户端发起请求到首先会通过虚拟的 IP 到主 Nginx 进行处理,此时发现 Nginx 宏机了,那么请求就中断了。因此 Ngin 配置高可用集群,主要是用来解决 Ngin 挂了之后无法工作的问题。此时可以通过虚拟的 IP 指向多个 Nginx,通过 keepalived 监测每个 Nginx 心跳,当发现主 Nginx 挂了后,通过另一个 Nginx 来执行服务。
image

接下来通过两台 Nginx 服务器来实现高可用集群配置。首先准备两台服务器,分别安装 Nginx 和 keepalived,分别修改 keepalived 配置文件,完成主从配置。

global_defs {
    notification_email {
        acassen@firewall.loc
        failover@firewall.loc
        sysadmin@firewall.loc
    }
    notification_email_from Alexandre.Cassen@firewall.loc
    smtp_server 192.168.17.129
    smtp_connect_timeout 30
    # 通过它,可以访问到主机,在hosts文件中,要做映射关系,类似于 127.0.0.1 LVS_DEVEL
    router_id LVS_DEVEL
}
# 心跳监测脚本
vrrp_script chk_http_port {
    # 执行脚本所在的位置
    script "/usr/local/src/nginx_check.sh"
    # 检测脚本执行的间隔,单位秒,每个2秒执行一次脚本
    interval 2
    weight 2
}
# 实例
vrrp_instance VI_1 {
    # 备份服务器上将 MASTER 改为 BACKUP
    state MASTER
    # 绑定的网卡
    interface ens33
    # 主、备机的 virtual_router_id 必须相同
    virtual_router_id 51
    # 主、备机取不同的优先级,主机值较大,备份机值较小
    priority 90
    #每隔一秒发送一次心跳,确保从服务器是否还活着
    advert_int 1
    # 心跳检测需要的密码
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
      # VRRP H 虚拟地址
      192.168.17.50
    }
}

在 /usr/local/src 中添加心跳监测脚本,检查 Nginx 是否还活着,之后可以分别启动两台服务器的 Nginx 和 keepalived,通过 virtual_ipaddress 配置的虚拟 IP 进行访问。

#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -eq 0 ];then
    #Nginx启动命令的位置
    /usr/local/nginx/sbin/nginx
    sleep 2
    if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
    killall keepalived
    fi
fi

Nginx 工作原理

基本组成

Nginx 是由内核和模块组成的。Nginx 本身做的工作实际很少,当它接到一个HTTP请求时,它仅仅是通过查找配置文件将此次请求映射到一个location block,而此 location 中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看做 Nginx 真正的劳动工作者。通常一个 location 中的指令会涉及一个 handler 模块和多个 filter 模块(当然,多个location可以复用同一个模块)。handler 模块负责处理请求,完成响应内容的生成,而 filter 模块对响应内容进行处理。

Nginx的模块从结构上分为核心模块、基础模块和第三方模块:

  • 核心模块:HTTP模块、EVENT模块和MAIL模块
  • 基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块,
  • 第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。

Nginx的模块从功能上分为处理器、过滤器和代理类三个模块:

  • Handlers(处理器模块):此类模块直接处理请求,并进行输出内容和修改 headers 信息等操作。Handlers 处理器模块一般只能有一个。
  • Filters (过滤器模块):此类模块主要对其他处理器模块输出的内容进行修改操作,最后由 Nginx 输出。
  • Proxies (代理类模块)。此类模块是 Nginx 的 HTTP Upstream 之类的模块,这些模块主要与后端一些服务比如 FastCGI 等进行交互,实现服务代理和负载均衡等功能。
    image

进程模型

Nginx 默认采用多进程工作方式,Nginx 启动后,会运行一个 maste r进程和多个 worke r进程。其中 master 充当整个进程组与用户的交互接口,同时对进程进行监护,管理 worker 进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。worker 用来处理基本的网络事件,worker 之间是平等的,他们共同竞争来处理来自客户端的请求
image

在创建 master 进程时,先建立需要监听的 socket(listenfd),然后从 master 进程中 fork() 出多个 worker 进程,如此一来每个 worker 进程多可以监听用户请求的s ocket。一般来说,当一个连接进来后,所有在 worker 都会收到通知,但是只有一个进程可以接受这个连接请求,其它的都失败,这是所谓的惊群现象。nginx提供了一个accept_mutex(互斥锁),有了这把锁之后,同一时刻,就只会有一个进程在accpet连接,这样就不会有惊群问题了。

先打开 accept_mutex 选项,只有获得了 accept_mutex 的进程才会去添加 accept 事件。Nginx 使用一个叫ngx_accept_disabled 的变量来控制是否去竞争 accept_mutex 锁。ngx_accept_disabled = nginx 单进程的所有连接总数 / 8 -空闲连接数量,当 ngx_accept_disabled 大于0时,不会去尝试获取 accept_mutex 锁,ngx_accept_disable 越大,于是让出的机会就越多,这样其它进程获取锁的机会也就越大。不去 accept,每个 worker进程的连接数就控制下来了,其它进程的连接池就会得到利用,这样,Nginx 就控制了多进程间连接的平衡。

每个 worker 进程都有一个独立的连接池,连接池的大小是 worker_connections。这里的连接池里面保存的其实不是真实的连接,它只是一个 worker_connections 大小的一个 ngx_connection_t 结构的数组,并且,Nginx 会通过一个链表 free_connections 来保存所有的空闲 ngx_connection_t,每次获取一个连接时,就从空闲连接链表中获取一个,用完后,再放回空闲连接链表里面。一个nginx能建立的最大连接数,应该是 worker_connections * worker_processes。当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes / 2,因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。

posted @ 2021-08-26 11:02  静守己心&笑淡浮华  阅读(175)  评论(0编辑  收藏  举报