TECH NOTES / 部署与运维

Nginx 配置与实践笔记

原笔记 2021-05-27 · 整理于 2026-10-05

Nginx 的安装、常用指令、反向代理和负载均衡笔记,配有配置与操作图。

阅读说明:这是一份持续积累的 Nginx 配置笔记。各配置片段展示不同场景,不应整篇拼成一个配置文件;修改后先运行 nginx -t 检查,再按部署方式重新加载。

一、Nginx可以干啥?

Nginx功能丰富,可作为HTTP服务器,也可作为反向代理服务器,邮件服务器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。

二、Nginx的几个比较常用的功能

1、反向代理

关于代理

说到代理,首先我们要明确一个概念,所谓代理就是一个代表、一个渠道;此时就涉及到两个角色,一个是被代理角色,一个是目标角色。

被代理角色通过这个代理访问目标角色完成一些任务的过程称为代理操作过程;如同生活中的专卖店,客人到 adidas 专卖店买了一双鞋,这个专卖店就是代理,被代理角色就是 adidas 厂家,目标角色就是用户。

正向代理

****\

说反向代理之前,我们先看看正向代理,正向代理也是大家最常接触到的代理模式,我们会从两个方面来说关于正向代理的处理模式,分别从软件方面和生活方面来解释一下什么叫正向代理。

在如今的网络环境下,我们如果由于技术需要要去访问国外的某些网站,此时你会发现位于国外的某网站我们通过浏览器是没有办法访问的。

此时大家可能都会用一个操作 FQ 进行访问,FQ 的方式主要是找到一个可以访问国外网站的代理服务器,我们将请求发送给代理服务器,代理服务器去访问国外的网站,然后将访问到的数据传递给我们!

上述这样的代理模式称为正向代理,正向代理最大的特点是客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息。

来看个示意图(我把客户端和正向代理框在一块,同属于一个环境,后面我有介绍):

Nginx详细教程配图 1

客户端必须设置正向代理服务器,当然前提是要知道正向代理服务器的 IP 地址,还有代理程序的端口。

如下图:

Nginx详细教程配图 2

****\

总结来说:

正向代理,"它代理的是客户端",是一个位于客户端和原始服务器(Origin Server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器)。

然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。

正向代理的用途:

  • 访问原来无法访问的资源,如 Google。
  • 可以做缓存,加速访问资源。
  • 对客户端访问授权,上网进行认证。
  • 代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息。

反向代理

明白了什么是正向代理,我们继续看关于反向代理的处理方式,举例如我国的某宝网站,每天同时连接到网站的访问人数已经爆表,单个服务器远远不能满足人民日益增长的购买欲望了。

此时就出现了一个大家耳熟能详的名词:分布式部署;也就是通过部署多台服务器来解决访问人数限制的问题。

某宝网站中大部分功能也是直接使用 Nginx 进行反向代理实现的,并且通过封装 Nginx 和其他的组件之后起了个高大上的名字:Tengine。

有兴趣的童鞋可以访问 Tengine 的官网查看具体的信息:

plain
http://tengine.taobao.org/

那么反向代理具体是通过什么样的方式实现的分布式的集群操作呢,我们先看一个示意图(我把服务器和反向代理框在一块,同属于一个环境,后面我有介绍):

Nginx详细教程配图 3

通过上述的图解大家就可以看清楚了,多个客户端给服务器发送的请求,Nginx 服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。

此时请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,Nginx 扮演的就是一个反向代理角色。

客户端是无感知代理的存在的,反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。因为客户端不需要任何配置就可以访问。

反向代理,"它代理的是服务端",主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息。

反向代理的作用:

  • 保证内网的安全,通常将反向代理作为公网访问地址,Web 服务器是内网。
  • 负载均衡,通过反向代理服务器来优化网站的负载。

2、负载均衡

我们已经明确了所谓代理服务器的概念,那么接下来,Nginx 扮演了反向代理服务器的角色,它是依据什么样的规则进行请求分发的呢?不用的项目应用场景,分发的规则是否可以控制呢?

这里提到的客户端发送的、Nginx 反向代理服务器接收到的请求数量,就是我们说的负载量。

请求数量按照一定的规则进行分发,到不同的服务器处理的规则,就是一种均衡规则。

所以将服务器接收到的请求按照规则分发的过程,称为负载均衡。

负载均衡在实际项目操作过程中,有硬件负载均衡和软件负载均衡两种,硬件负载均衡也称为硬负载,如 F5 负载均衡,相对造价昂贵成本较高。

但是数据的稳定性安全性等等有非常好的保障,如中国移动中国联通这样的公司才会选择硬负载进行操作。

更多的公司考虑到成本原因,会选择使用软件负载均衡,软件负载均衡是利用现有的技术结合主机硬件实现的一种消息队列分发机制。

Nginx详细教程配图 4

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

①weight 轮询(默认)****:

接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,Nginx 会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。

这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率。

权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。

②ip_hash:

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

③fair:

智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配。

响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少,它是结合了前两者的优点的一种调度算法。

但是需要注意的是 Nginx 默认不支持 fair 算法,如果要使用这种调度算法,请安装 upstream_fair 模块。

④url_hash:

按照访问的 URL 的 hash 结果分配请求,每个请求的 URL 会指向后端固定的某个服务器,可以在 Nginx 作为静态服务器的情况下提高缓存效率。

同样要注意 Nginx 默认不支持这种调度算法,要使用的话需要安装 Nginx 的 hash 软件包。

3、邮箱服务器

移步:Nginx代理smtp、pop等邮件服务

4、 限流

Nginx官方版本限制IP的连接和并发分别有两个模块:

  • limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 "leaky bucket"。
  • limit_req_conn 用来限制同一时间连接数,即并发限制。

详见:

Nginx的限流模块,是基于漏桶算法实现的,在高并发的场景下非常实用。

1、配置参数

limit_req_zone定义在http块中,$binary_remote_addr 表示保存客户端IP地址的二进制形式。

Zone定义IP状态及URL访问频率的共享内存区域。

zone=keyword标识区域的名字,以及冒号后面跟区域大小。16000个IP地址的状态信息约1MB,所以示例中区域可以存储160000个IP地址。

Rate定义最大请求速率。示例中速率不能超过每秒100个请求。

2、设置限流

burst排队大小,nodelay不限制单个请求间的时间。

5、黑名单、白名单

参考:Nginx服务器设置黑名单屏蔽IP的方法

在Nginx的conf目录下面建立blockip.conf文件(名称可以随意),把想要屏蔽的IP只要加入这个文件即可,格式如下:

basic
deny 195.91.122.67;

在nginx的配置文件nginx.conf中加入如下配置,可以放到http, server, location, limit_except语句块,需要注意相对路径,本例当中nginx.conf,blocksip.conf在同一个目录中。

basic
include blockip.conf;

高级用法:

屏蔽ip的配置文件既可以屏蔽单个ip,也可以屏蔽ip段,或者只允许某个ip或者某个ip段访问。

basic
# 屏蔽单个ip访问
deny IP;
# 允许单个ip访问
allow IP;
# 屏蔽所有ip访问
deny all;
# 允许所有ip访问
allow all;
#屏蔽整个段即从123.0.0.1到123.255.255.254访问的命令
deny 123.0.0.0/8
#屏蔽IP段即从123.45.0.1到123.45.255.254访问的命令
deny 124.45.0.0/16
#屏蔽IP段即从123.45.6.1到123.45.6.254访问的命令
deny 123.45.6.0/24

如果你想实现这样的应用,除了几个IP外,其他全部拒绝,

那需要你在blockip.conf中这样写

basic
allow 1.1.1.1;
allow 1.1.1.2;
deny all;

单独网站屏蔽IP的方法,把include blocksip.conf; 放到网址对应的在server{}语句块,

所有网站屏蔽IP的方法,把include blocksip.conf; 放到http {}语句块。

屏蔽访问过于频繁的IP脚本需要根据实际的nginx log 格式,修改,取出 访问IP 和User-Agent.

在nginx配置文件中添加一条配置

basic
include ./vhost/blockip.conf;

脚本内容:

shell
#!/bin/bash
nginx_home=/usr/local/webserver/nginx
log_path=/usr/local/webserver/nginx/logs
tail -n50000 /usr/local/webserver/nginx/logs/access.log \
|awk '{print $1,$12}' \
|grep -i -v -E "google|yahoo|baidu|msnbot|FeedSky|sogou" \
|awk '{print $1}'|sort|uniq -c|sort -rn \
|awk '{if($1>1000)print "deny "$2";"}' >$nginx_home/conf/vhost/blockip.conf
/etc/init.d/nginx reload

解析:

shell
awk '{print $1,$4}' log.txt   #每行按空格或TAB分割,输出文本中的1、4项

三、配置详解

1、配置结构

json
...              #全局块

events {         #events块
   ...
}

http      #http块
{
    ...   #http全局块
    server        #server块
    {
        ...       #server全局块
        location [PATTERN]   #location块
        {
            ...
        }
        location [PATTERN]
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     #http全局块
}

1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。

2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。

3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。

4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。

5、location块:配置请求的路由,以及各种页面的处理情况。

2、配置示例

官方默认配置:

json
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

带注释配置:

nginx.conf

json
### 配置前先看看这里!!!
### 需要注意的事项:
### 1. 每个指令必须有分号结束
### 2. Nginx reload 不会中断现有连接。 master 会加载新的配置,然后新建 work去执行新的配置,旧的work没有任务后销毁。
###### 一、使用Nginx reload 不会中断现有连接的特性,可以做到不停机发布生产,具体做法:
######  1. 换端口,发布新版服务,旧版不要停;
######  2. 把 Nginx 反向代理改向新版服务,然后reload配置;
######  3. 监控 Nginx 和旧版jar的请求日志,如果一段时间不打了,应该就是所有请求都搞完了,可以把旧版jar停掉;
###### 二、还可以在发布的时候先将服务指向一个正在维护的页面去,不至于让用户打不开,具体做法:
######  1. 将前端的 Nginx 反向代理到一个类似正在维护的静态页面,然后reload配置;
######  2. 停止旧的后端服务,发布新的后端服务;
######  3. 后端服务发布成功后,将前端的代理改回来;
### 3. 在NGINX上配置HTTPS---血的教训--要重启NGINX, 重启,不是重载!!!是STOP & START 而不是RELOAD!!!
### 4. Nginx配置在线生成(需翻墙):https://www.digitalocean.com/community/tools/nginx?global.app.lang=zhCN


########################################## 下面为 Nginx 的配置 ###################################################################################


### --------------------------------- 全局块 ------------------------------------ ###
## 全局块配置说明: 配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等

## Tips: 关于user、pid,默认的就好,因为更改与否没有什么提升
## 配置用户或者组,默认为nobody nobody
# user administrator administrators;

## 指定nginx进程运行文件存放地址
# pid /nginx/pid/nginx.pid;

## 全局错误日志,这个设置可以放入全局块,http块,server块,级别从低到高为 debug,info,notice,warn,error,crit,默认为crit, 生产环境用error;crit记录的日志最少,而debug记录的日志最多
## 格式:error_log(关键字) 日志文件 错误日志级别
error_log logs/error.log error;

## 定义了 nginx 对外提供 web 服务时的 worker 进程数。
## 最优值取决于许多因素,包括(但不限于)CPU核的数量、存储数据的硬盘数量及负载模式。不能确定的时候,将其设置为可用的CPU内核数将是一个好的开始(设置为“auto”将尝试自动检测它)
worker_processes auto;

## 因为上面配置了auto,所以下面这个配置用不上,注释掉。了解其作用:https://blog.csdn.net/u011957758/article/details/50959823
# worker_cpu_affinity 0101 1010;

## 更改worker进程的最大打开文件数限制。如果没设置的话,这个值为操作系统的限制。设置后你的操作系统和Nginx可以处理比“ulimit -a”更多的文件,所以把这个值设高,这样nginx就不会有“too many open files”问题了
worker_rlimit_nofile 102400;

### --------------------------------- 全局块 ------------------------------------ ###


### --------------------------------- Events模块 -------------------------------- ###
## Events模块说明:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。

events {
    ## 设置网路连接序列化,防止惊群现象发生,默认为on
    accept_mutex on;

    ## 设置可由一个worker进程同时打开的最大连接数,默认为512。如果设置了上面提到的worker_rlimit_nofile,我们可以将这个值设得很高。NGINX最大连接数=连接数*进程数,一般1GB内存的机器上可以打开的最大数大约是10万左右
    worker_connections 102400;

    ## 设置一个进程是否同时接受多个网络连接,默认为off
    multi_accept on;

    ## 多路复用客户端线程的轮询方法。如果你使用Linux 2.6+,你应该使用epoll。如果你使用BSD,你应该使用kqueue(windows下均不支持,注释掉)
    ## 事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
    # use epoll;
}

### --------------------------------- Events模块 --------------------------------- ###


### --------------------------------- 常用:HTTP模块 ------------------------------ ###
## HTTP模块说明:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。

http {
    ### ------------------------- 基本配置 ------------------------ ###
    ###
    ## 引用mime.types文件,这个里面定义了很多类型,当web服务器收到静态的资源文件请求时,依据请求文件的后缀名在服务器的MIME配置文件中找到对应的MIMEType,根据MIMETYPE设置response响应类型(Content-type)
    include mime.types;

    ## 设置默认的MIME-type。若设为octet-stream(二进制流),用浏览器访问 mime.types 未定义的文件类型时(比如JSP文件),就会出现下载窗口;设为text,那就会在网页上显示字符(即使文件是二进制文件)。所以,默认什么类型,跟我们要发布网页还是资源下载是有关
    default_type text/html;

    ## 设置我们的头文件中的默认的字符集
    charset UTF-8;

    ## 关闭在错误页面中的nginx版本数字,虽然不会让nginx执行的速度更快,但这样对于安全性是有好处的
    server_tokens off;

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

    ## 不存储访问日志,可以减少磁盘IO,性能更快(aka,YOLO)
    access_log off;

    ## 日志格式,依次是:远程ip、远程用户、当地时间、请求URL、状态、发送的大小、响应头、客户端使用的浏览器、页面响应的时间
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                 '$status $body_bytes_sent "$http_referer" '
                 '"$http_user_agent" $request_time';
    ###
    ### ------------------------- 基本配置 ------------------------ ###


    ### ------------------------IO、传输、链接 ------------------------ ###
    ###
    ## 让sendfile()发挥作用。sendfile()可以在磁盘和TCP socket之间互相拷贝数据(或任意两个文件描述符),可以立即将数据从磁盘读到OS缓存,这种拷贝是在内核完成的,所以要比组合read()和write()以及打开关闭丢弃缓冲更加有效。如果NGINX专门做为一个下载端的话可以关掉,好处是降低磁盘与网络的IO处理数及系统的UPTIME
    sendfile on;

    ## tcp传输在一个数据包里发送所有头文件,而不一个接一个的发送,可以防止网络阻塞
    tcp_nopush on;

    ## tcp传输不要缓存数据,实时响应
    tcp_nodelay on;
    ###
    ### ------------------------IO、传输、链接 ------------------------ ###


    ### ----------------------- 压缩 ---------------------------------- ###
    ###
    ## 压缩静态资源,比例我的静态资源有10M,压缩后只有2M,那么浏览器下载的就少了
    gzip on;

    gzip_http_version 1.1;

    ## 为指定的客户端禁用gzip功能。我们设置成IE6或者更低版本以使我们的方案能够广泛兼容
    gzip_disable "msie6";

    ## 告诉nginx在压缩资源之前,先查找是否有预先gzip处理过的资源。这要求你预先压缩你的文件(在这个例子中被注释掉了),从而允许你使用最高压缩比,这样nginx就不用再压缩这些文件了
    # gzip_static on;

    ## 允许或者禁止压缩基于请求和响应的响应流。我们设置为any,意味着将会压缩所有的请求
    gzip_proxied any;

    ## 设置对数据启用压缩的最少字节数。如果一个请求小于1k,我们最好不要压缩它,因为压缩这些小的数据会降低处理此请求的所有进程的速度
    gzip_min_length 1k;

    ## 设置数据的压缩等级。这个等级可以是1-9之间的任意数值,值越小,压缩后比例越小,CPU处理更快,9压缩比最大但是最慢的
    gzip_comp_level 2;

    gzip_buffers 4 16k;

    ## 作用是在http响应中增加一行改变反向代理服务器的缓存策略
    gzip_vary on;

    ## 设置需要压缩的数据格式。你可以再添加更多的格式
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    ###
    ### ----------------------- 压缩 ---------------------------------- ###


    ### ------------------ 静态文件缓存优化 ----------------------------- ###
    ###
    # 打开缓存的同时也指定了两个参数,max表示缓存静态文件最大数目,inactive与下面的min_uses表示,如果在inactive时间内某文件被访问的次数低于min_uses次,那就将它从缓存中删除
    open_file_cache max=51200 inactive=20s;

    ## 定义了open_file_cache中指令参数不活动时间期间里最小的文件数
    open_file_cache_min_uses 2;

    ## 表示检查一次缓存中的文件元信息是否是最新的(如果不是则更新之)的时间间隔
    open_file_cache_valid 30s;

    ## 指定了当搜索一个文件时是否缓存错误信息,如“找不到文件”,“不读权限”等等
    open_file_cache_errors on;
    ###
    ### ------------------ 静态文件缓存优化 ----------------------------- ###


    ### ------------------------- 负载均衡(上游服务池) ----------------------------- ###
    ### server里面这样用:
    ### 请求转向mysvr 定义的服务器列表
    ### proxy_pass  http://mysvr1;
    ###
    upstream mysvr1 {
        ## weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
        ## max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
        ## fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
        server 127.0.0.1:7878      weight=2 max_fails=2 fail_timeout=2;
        server 192.0.2.121:3333 weight=1 max_fails=2 fail_timeout=1;

        ## ip_hash:nginx会让相同的客户端ip请求相同的服务器。
        #ip_hash;
    }

    ## 热备
    ## 如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB.....
    upstream mysvr2 {
        ## weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
        ## max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
        ## fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
        server 127.0.0.1:7878;

        ## backup:热备
        server 192.0.2.121:3333 backup;
    }
    ###
    ### ------------------------- 负载均衡 ----------------------------- ###


    ### ------------------ 客户端(浏览器 - nginx)优化 ------------------ ###
    ### 关于长连接设置参考:nginx优化——包括https、keepalive等: https://blog.csdn.net/dream_flying_bj/article/details/54709549
    ###
    ## 设置客户端到nginx长连接保持开启的时间,超时自动关闭长连接,默认75秒,可以在http,server,location块, 一般情况下也够用,对于一些请求比较大的内部服务器通讯的场景,适当加大为120s或者300s(如非必要不要设置太大,容易拖死服务器)
    keepalive_timeout 3660;

    ## 用于设置一个keep-alive连接上可以服务的请求的最大数量,当最大请求数量达到时,连接被关闭,默认是100
    keepalive_requests 10000;

    ## 关闭不响应的客户端连接,这将会释放那个客户端所占有的内存空间
    reset_timedout_connection on;

    ## 指定等待客户端发送一个请求头、体的超时时间,仅当在一次read中,没有收到请求头、体,才会算成超时。如果在超时时间内,client没发送任何东西,nginx返回HTTP状态码408(“Request timed out”)。两个默认值都是60s,我们可以设置低一些
    client_header_timeout 10;

    client_body_timeout 10;

    ## 指定客户端的响应超时时间。这个设置不会用于整个转发器,而是在两次客户端读取操作之间。如果在这段时间内,客户端没有读取任何数据,nginx就会关闭连接
    send_timeout 10;

    ## 用来缓存请求头信息的,容量4K,如果header头信息请求超过了,nginx会直接返回400错误,先根据client_header_buffer_size配置的值分配一个buffer,如果分配的buffer无法容纳 request_line/request_header,那么就会再次根据large_client_header_buffers配置的参数分配large_buffer,如果large_buffer还是无法容纳,那么就会返回414(处理request_line)/400(处理request_header)错误。
    client_header_buffer_size 4k;

    ## 此指令规定了用于读取大型客户端请求头的缓冲区的最大数量和大小。 这些缓冲区仅在缺省缓冲区不足时按需分配。 当处理请求或连接转换到保持活动状态时,释放缓冲区
    large_client_header_buffers 4 32k;

    ## 此指令设置用于请求主体的缓冲区大小。 如果主体超过缓冲区大小,则完整主体或其一部分将写入临时文件。 如果NGINX配置为使用文件而不是内存缓冲区,则该指令会被忽略。 默认情况下,该指令为32位系统设置一个8k缓冲区,为64位系统设置一个16k缓冲区
    client_body_buffer_size 512k;

    ## 此指令设置NGINX能处理的最大请求主体大小。 如果请求大于指定的大小,则NGINX发回HTTP 413(Request Entity too large)错误。 如果服务器处理大文件上传,则该指令非常重要
    client_max_body_size 500m;
    ###
    ### ------------------ 客户端(浏览器 - nginx)优化 ------------------ ###


    ### --------------- 代理(nginx - 后端服务器)优化 ---------------------- ###
    ###
    ## nginx跟后端服务器连接超时时间
    proxy_connect_timeout   5;

    ## 连接成功后,nginx等待后端服务器响应超时时间。这个时间不是获得整个response的时间,而是两次reading操作的时间(下同)
    proxy_read_timeout      3660;

    ## 指定了nginx发送请求给后端服务器的超时时间
    proxy_send_timeout 500;

    ## 设置代理服务器(nginx)响应头的缓冲区大小
    proxy_buffer_size 16k;

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

    ## 高负荷下缓冲大小
    proxy_busy_buffers_size 128k;

    ## 设定缓存文件夹大小,大于这个值,将从upstream服务器传
    proxy_temp_file_write_size 128k;
    ###
    ### --------------- 代理(nginx - 后端服务器)优化 ---------------------- ###


    ### ----------------------- 限制连接数 --------------------------- ###
    ### (防DDOS攻击,参考:http://www.ttlsa.com/nginx/nginx-limited-connection-number-ngx_http_limit_conn_module-module/)
    ###
    ## 设置用于保存各种key(比如当前连接数)的共享内存的参数。5m就是5兆字节,这个值应该被设置的足够大以存储(32K*5)32byte状态或者(16K*5)64byte状态
    # limit_conn_zone $binary_remote_addr zone=addr:5m;

    ## 为给定的key设置最大连接数。这里key是addr,我们设置的值是100,也就是说我们允许每一个IP地址最多同时打开有100个连接
    # limit_conn addr 100;
    ###
    ### ----------------------- 限制连接数 --------------------------- ###


    ### ------------------------- 其他优化 --------------------------- ###
    ###
    ## 表示接收fastcgi输出的http 1.0 response code
    fastcgi_intercept_errors on;

    ## 保存服务器名字的hash表,could not build the server_names_hash, you should increase server_names_hash_bucket_size: 64
    server_names_hash_bucket_size 128;

    ## 错误页
    # error_page 404 https://www.baidu.com;
    ###
    ### ------------------------- 其他优化 --------------------------- ###


    ## 默认服务,未经允许任何人不能修改这里面的配置
    ## include 指令用于包含拆分的配置文件
    include server-r720-commons.conf;

    ## gdae本地测试环境
    ## include 指令用于包含拆分的配置文件
    include server-gdae-test.conf;

}

### --------------------------------- 常用:HTTP模块 ------------------------------ ###

server-r720-commons.conf

json
    # *.xbdream.cn 默认配置START(未经允许任何人不能修改这里面的配置) ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    # nexus配置
    server {
        listen 8000;
        server_name nexus.xbdream.cn;

        location / {
            proxy_pass http://192.0.2.146:8001;
            proxy_set_header Host $host:$server_port;
            proxy_redirect  off;
            # proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

    # gitea配置
    server {
        listen 8000;
        server_name gitea.xbdream.cn;

        location / {
            proxy_pass http://192.0.2.146:8002;
            proxy_set_header Host $host:$server_port;
        }
    }

    # jenkins配置
    server {
        listen 8000;
        server_name jenkins.xbdream.cn;

        location / {
            proxy_pass http://192.0.2.146:8003;
            proxy_set_header Host $host:$server_port;
        }
    }

    # gogs配置
     server {
        listen 8000;
        server_name gogs.xbdream.cn;

        location / {
            proxy_pass http://192.0.2.146:8004;
            proxy_set_header Host $host:$server_port;
        }
    }
    # *.xbdream.cn 默认配置END(未经允许任何人不能修改这里面的配置) ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

server-gdae-test.conf

json
## server{} 包含在http{}内部,每一个server{}都是一个虚拟主机(站点)
server {
    ## 监听端口为8000,可以自定义其他端口,也可以加上IP地址,如,listen 127.0.0.1:8080;
    listen 8000;

    ## 定义网站域名,可以写多个,用空格分隔。
    server_name gdae.xbdream.cn;

    ## 定义网站的字符集,一般不设置,而是在网页代码中设置。
    #charset koi8-r;

    ## 定义访问日志,可以针对每一个server(即每一个站点)设置它们自己的访问日志。
    #access_log  logs/host.access.log  main;

    ## 配置请求的路由,以及各种页面的处理情况。在server{}里有很多location配置段
    ## location 是平时使用得最多的
    ## nginx location配置详细解释:https://my.oschina.net/u/4399002/blog/3590199
    ## nginx 常见正则匹配符号表示:https://www.cnblogs.com/netsa/p/6383094.html
    location / {
        ## 定义网站根目录,目录可以是相对路径也可以是绝对路径。
        root html/GdaeWww/cn;

        ## 定义站点的默认页。
        index home.html;

        ## 拒绝的ip
        # deny 127.0.0.1;

        ## 允许的ip
        # allow 172.18.5.54;

        ## Https

    }

    location ~ /cn {
        root html/GdaeWww;
        index home.html index.htm;
    }

    location /en {
        root html/GdaeWww;
        index home.html index.htm;
    }

    # app更新
    location /apps {
        ## 表示nginx的安装目录,而不是conf文件所在的目录
        root ./;

        ## 解决java后台request.getScheme()取不到正确的https的问题
        proxy_set_header X-Forwarded-Proto  $scheme;

        ## 下面这行是解决SSL_do_handshake()握手失败,参考:https://blog.csdn.net/C_offee_Y/article/details/78707700
        # proxy_ssl_session_reuse off;
    }

    location /wap {
        root html/GdaeWww-old;
        index index.html index.htm;
    }
    location /wap_en {
        root html/GdaeWww-old;
        index index.html index.htm;
    }
    location /messages {
        root html/GdaeWww-old;
    }
    location /static {
        root html/GdaeWww-old;
    }

    # location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
    #     ## 所有静态文件直接读取硬盘
    #     root C:\ProductionTools\Nginx\html\GdaeWww\cn ;
    #     expires 1d; #缓存1天
    # }

    location ~ ^/(admin|cms|platform|dfs|cache).*$ {
        ## 设置后端代理服务器的地址。这个地址(address)可以是一个域名或ip地址和端口,或者一个 unix-domain socket路径。
				## 在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走
        ## 详见官方文档: http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_pass
        proxy_pass http://192.0.2.146:8085;
        proxy_set_header Host $host:$server_port;

				## 获取客户端真实IP
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        ## 解决java后台request.getScheme()取不到正确的https的问题
        proxy_set_header X-Forwarded-Proto  $scheme;

        ## 下面这行是解决SSL_do_handshake()握手失败,参考:https://blog.csdn.net/C_offee_Y/article/details/78707700
        # proxy_ssl_session_reuse off;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection  "upgrade";
    }

    location ~ ^/(trade).*$ {
        proxy_pass http://192.0.2.146:8085;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        ## 解决java后台request.getScheme()取不到正确的https的问题
        proxy_set_header X-Forwarded-Proto  $scheme;

        ## 下面这行是解决SSL_do_handshake()握手失败,参考:https://blog.csdn.net/C_offee_Y/article/details/78707700
        # proxy_ssl_session_reuse off;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection  "upgrade";
    }

		# 跨站访问
		location ~ .*\.(html|htm)$ {
     add_header Access-Control-Allow-Origin *;
     add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;

     ## 允许cookie跨域
     ## 在响应中指定 Access-Control-Allow-Credentials 为 true 时,Access-Control-Allow-Origin 不能指定为 *,需要指定到具体域名相关跨域内容可参考 Laravel 跨域功能中间件 使用代码实现跨域,原理与nginx跨域配置相同
     # Access-Control-Allow-Credentials true
		}

}

3、几个常见配置项

  • $remote_addr 与 $http_x_forwarded_for 用以记录客户端的ip地址;
  • $remote_user :用来记录客户端用户名称;
  • $time_local : 用来记录访问时间与时区;
  • $request : 用来记录请求的url与http协议;
  • $status : 用来记录请求状态;成功是200;
  • $body_bytes_sent :记录发送给客户端文件主体内容大小;
  • $http_referer :用来记录从那个页面链接访问过来的;
  • $http_user_agent :记录客户端浏览器的相关信息;

4、常用命令

Linux环境下:

shell
# nginx默认安装目录
cd /usr/local/nginx/sbin/

# 启动
./nginx

# 停止 相当于先查出nginx进程id再使用kill命令强制杀掉进程,退出之后需再次启动
./nginx -s stop

# 退出 停止步骤是待nginx进程处理任务完毕进行停止(推荐),退出之后需再次启动
./nginx -s quit

# 重载配置文件 不用先停止 ngin x再启动 nginx 即可将配置信息在 nginx 中生效
./nginx -s reload

# 查找安装路径
whereis nginx

# 查询nginx进程
ps aux|grep nginx

# 大写V查看所有模块,小写v查看版本
./nginx -V

# 查看Nginx版本:
./nginx -v

# 查看帮助
./nginx -help
Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
[-e filename] [-c filename] [-g directives]

Options:
-?,-h         : this help
-v            : show version and exit
-V            : show version and configure options then exit
-t            : test configuration and exit
-T            : test configuration, dump it and exit
-q            : suppress non-error messages during configuration testing
-s signal     : send signal to a master process: stop, quit, reopen, reload
-p prefix     : set prefix path (default: NONE)
-e filename   : set error log file (default: logs/error.log)
-c filename   : set configuration file (default: conf/nginx.conf)
-g directives : set global directives out of configuration file

# 查看此配置文件 是否存在语法错误
./nginx -tc /usr/local/nginx/conf/nginx.conf

windows环境下:

json
# 启动:
C:\server\nginx-1.0.2>start nginx或
C:\server\nginx-1.0.2>nginx.exe

# 停止:
C:\server\nginx-1.0.2>nginx.exe -s stop或
C:\server\nginx-1.0.2>nginx.exe -s quit
注:stop是快速停止nginx,可能并不保存相关信息;quit是完整有序的停止nginx,并保存相关信息。

# 重新载入Nginx:
C:\server\nginx-1.0.2>nginx.exe -s reload
当配置信息修改,需要重新载入这些配置时使用此命令。


# 重新打开日志文件:
C:\server\nginx-1.0.2>nginx.exe -s reopen

# 查看Nginx版本:
C:\server\nginx-1.0.2>nginx -v

# 查看帮助
C:\server\nginx-1.0.2>nginx.exe -help
Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
             [-e filename] [-c filename] [-g directives]

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: NONE)
  -e filename   : set error log file (default: logs/error.log)
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file

# 已某个配置文件启动
C:\server\nginx-1.0.2>nginx.exe -c ./conf/nginx_original.conf

# 大写V查看所有模块,小写v查看版本
C:\server\nginx-1.0.2>nginx.exe -V
nginx version: nginx/1.20.0
built by cl 16.00.40219.01 for 80x86
built with OpenSSL 1.1.1k  25 Mar 2021
TLS SNI support enabled
configure arguments: --with-cc=cl --builddir=objs.msvc8 --with-debug --prefix= --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log --error-log-path=logs/error.log --sbin-path=nginx.exe --http-client-body-temp-path=temp/client_body_temp --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp/fastcgi_temp --http-scgi-temp-path=temp/scgi_temp --http-uwsgi-temp-path=temp/uwsgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs.msvc8/lib/pcre-8.44 --with-zlib=objs.msvc8/lib/zlib-1.2.11 --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_stub_status_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_slice_module --with-mail --with-stream --with-openssl=objs.msvc8/lib/openssl-1.1.1k --with-openssl-opt='no-asm no-tests -D_WIN32_WINNT=0x0501' --with-http_ssl_module --with-mail_ssl_module --with-stream_ssl_module

# 查看此配置文件 是否存在语法错误
C:\server\nginx-1.0.2>nginx.exe -tc C:\server\nginx-1.0.2\conf\nginx.conf

5、常用模块

四、安装

windows的安装就不说了,直接去官网下载没配置下就能用了

Linux安装 :https://blog.csdn.net/qq_34845394/article/details/90675004

五、脚本

以下脚本需要注意如果目录不同则需要改变 脚本中的 NGINX_PATH、NGINX_DIR

shell
====================================================
@echo off
rem 当前bat的作用

echo ==================begin========================

cls
SET NGINX_PATH=C:
SET NGINX_DIR=C:\Users\Administrator\Desktop\nginx-1.20.0\
color 0a
TITLE Nginx 管理程序控制面板

CLS

ECHO.
ECHO. * Nginx 管理程序 *
ECHO.

:MENU

ECHO. * nginx 进程list *
tasklist|findstr /i "nginx.exe"

ECHO.
ECHO. [1] 启动Nginx
ECHO. [2] 关闭Nginx
ECHO. [3] 重启Nginx
ECHO. [4] 退 出
ECHO.

ECHO.请输入选择项目的序号:
set /p ID=
IF "%id%"=="1" GOTO start
IF "%id%"=="2" GOTO stop
IF "%id%"=="3" GOTO restart
IF "%id%"=="4" EXIT
PAUSE

:start
call :startNginx
GOTO MENU

:stop
call :shutdownNginx
GOTO MENU

:restart
call :shutdownNginx
call :startNginx
GOTO MENU

:shutdownNginx
ECHO.
ECHO.关闭Nginx......
taskkill /F /IM nginx.exe > nul
ECHO.OK,关闭所有nginx 进程
goto :eof

:startNginx
ECHO.
ECHO.启动Nginx......
IF NOT EXIST "%NGINX_DIR%nginx.exe" ECHO "%NGINX_DIR%nginx.exe"不存在

%NGINX_PATH%

cd "%NGINX_DIR%"

IF EXIST "%NGINX_DIR%nginx.exe" (
echo "start '' nginx.exe"
start "" nginx.exe
)
ECHO.OK
goto :eof

Nginx详细教程配图 6

六、常见问题

1、相同 server_name 多个虚拟主机优先级

json
# 当出现虚拟主机域名相同的情况,重启nginx时,会出现警告处理,但是并不不会阻止nginx继续使用
server {
    listen 80;
    server_name www.baidu.com
    ...
}
server {
    listen 80;
    server_name www.baidu.com
    ...
}
...
# 优先选择最新读取到的配置文件,当多个文件是通过include时,文件排序越靠前,越早被读取

2、location 匹配优先级

json
=        # 进行普通字符精确匹配,完全匹配
^~       # 进行普通字符匹配,当前表示前缀匹配
~\~*     # 表示执行一个正则匹配()

# 当程序使用精确匹配时,一但匹配成功,将停止其他匹配
# 当正则匹配成功时,会继续接下来的匹配,寻找是否还有更精准的匹配

3、try_files的使用

按顺序检查文件是否存在

json
location / {
    try_files $uri $uri/ /index.php;
}

# 先查找$uri下是否有文件存在,若存在直接返回给用户
# 若$url下没有文件存在,再次访问$uri/的路径是否有文件存在
# 还是没有文件存在,交给index.php处理

例:
location / {
    root /test/index.html
    try_files $uri @test
}

location @test {
    proxy_pass http://127.0.0.1:9090;
}

# 访问 / 时,查看 /test/index.html 文件是否存在
# 若不存在,让9090端口的程序去处理这个请求

4、alias和root的区别

json
location /request_path/image/ {
    root /local_path/image/;
}

# 当我们访问 http://xxx.com/request_path/image/cat.png时
# 将访问 http://xxx.com/request_path/image/local_path/image/cat.png 下的文件

location /request_path/image/ {
    alias /local_path/image/;
}

# 当我们访问 http://xxx.com/request_path/image/cat.png时
# 将访问 http://xxx.com/local_path/image/cat.png 下的文件

5、获取用户真实IP

当一个请求通过多个代理服务器时,用户的IP将会被代理服务器IP覆盖

json
# 在第一个代理服务器中设置
set x_real_ip=$remote_addr
# 最后一个代理服务器中获取
$x_real_ip=IP1

6、Nginx 常见错误码

json
413 Request Entity Too Large    # 上传文件过大,设置 client_max_body_size
503 bad gateway                 # 后端服务无响应
504 Gateway Time-out            # 后端服务执行超时

七、其它文章

文章配图