Nginx复习面试资料整理

Nginx复习资料整理

文章目录

Nginx原理特性详解及编译部署Nginx

Nginx简介

传统上基于进程或者线程模型架构的Web服务通过进程或者线程处理并发连接请求,这势必会在网络和I/O操作时产生阻塞,其另一个必然结果则是对内存或CPU的利用率低下。生成一个新的进程/线程需要实现备好其运行环境,这包括为其分配堆内存和栈内存,以及为其创建新的执行上下文等。这些操作需都要占用CPU,而且过多的进程/线程还会带来线程抖动或者频繁上下文切换,系统性能也会由此进一步下降。

另一种高性能Web服务器/Web反向代理服务器/邮件服务器——Nginx,Nginx的主要特点就是其高性能以及对物理计算资源的高密度利用,因此采用了不同的架构模型。受启发于多种操作系统设计中基于“事件”的高级处理机制,Nginx采用模块化、事件驱动、异步、单线程及阻塞的架构,并大量采用了多路复用及时间通知机制。在Nginx中,连接请求由为数不多的几个仅包含一个线程的进程worker以高效的回环(run-loop)机制处理,而每个worker可以并行处理数千个并发连接以及请求。

Nginx是工作在七层协议上应用层的应用。

Nginx架构

img
图解:

  1. Nginx主进程Master来管理子进程,每个子进程Worker通过HTTP/HTTPS协议来处理多个客户端请求。为什么每个子进程可以处理多个客户端请求的原因是因为在网络IO中使用了kevent/epoll/select模型实现了网络的多路管理和使用;三种机制模型,不过主要是使用epoll机制来实现的。更多kevent/epoll/select模型知识点击“传送门”
  2. 如果Nginx为代理服务器,子进程Worker接收到客户端的请求后会转发给后端应用,如通过HTTP协议传给Web server;通过FastCGI协议发送给后端Application server(如php等);通过memcache协议来把请求转发给Memcached server;众多server都可以称为后端服务器,可以统一被称为Backend。
  3. 如果Nginx反代服务器启用了缓存功能,则Nginx直接去调用内核空间去本地磁盘进行读取缓存信息,拿到缓存数据后直接返回给客户端,从而少了一层转发,也加快了数据返回速度。Nginx缓存功能需要两个进程来管理,两个进程来管理Cache loader(缓存项)、Cache manager(缓存管理器)。
  4. 整个Nginx大概利用了这几种特性:
    1)Event-driven(事件驱动)
    2)Asynchronous(异步)
    3)Non-blocking(非阻塞模型)
  5. 对于磁盘来讲,它可以支持以下模型:
    1)Advanced I/O(高级IO)
    2)sendfile
    3)AIO(AIO为五种I/O模型中的异步IO) 五种模型知识讲解“传送门”
    4)mmap etc(内存映射)

Nginx工作原理

Nginx会按需同时运行多个进程:一个主进程(master)和几个工作进程(worker),配置了缓存时还会有缓存加载器进程(cache loader)和缓存管理器进程(cache manager)等。所有进程均是仅含有一个线程,并主要通过“共享内存”的机制实现进程间通信。主进程以root用户身份运行,而worker、cache loader和cache manager均应以非特权用户身份运行,其特权用户身份可以在Nginx主配置文件内定义"user nginx nginx;"字段,第一个nginx代表nginx的worker进程的运行用户,第二个代表用户组。

Nginx进程功能

Nginx进程分为Master主进程和Worker子进程组成
主进程Master主要完成以下工作:

  1. 读取并验证配置文件信息
  2. 创建、绑定及关闭套接字
  3. 启动、终止及维护worker进程的个数
  4. 无须终止服务而重新配置工作特性
  5. 可以不关闭进程进行版本升级,俗称“平滑升级”
  6. 重新打开日志文件
  7. 编译嵌入式perl脚本

子进程Worker主要完成以下工作

  1. 接收、传入、处理来自客户端的连接及请求
  2. 提供反向代理以及过滤功能
  3. Nginx任何能完成的其他任务

注:worker进程数量设置
worker可在nginx主配置文件中"worker_processes auto;" 字段配置,auto代表自动分配进程数量,一般自动分配进程数量是与nginx的cpu个数一致。我们在生产环境中一般设置Nginx进程数只有两个选择。
1)Nginx的worker进程数等于CPU核心数
2)Nginx的worker进程数小于CPU核心数
因为进程数大于了CPU的核心数之后就没有多余的CPU核心来承担worker进程的工作了

Nginx组成

Nginx的代码有一个核心和一系列模块组成,核心主要用于提供Web Server的基本功能,以及Web和Mail的反向代理功能;还用于启用网络协议,创建必要的运行环境以及确保不同模块之间平滑地进行交互。不过大多数协议相关的功能和某应用特有的用能都是由Nginx的模块而实现。这些功能模块大致可以分为事件模块、阶段性处理器、输出过滤器、变量处理器、协议、upstream和负载均衡几个类别,这些共同组成了Nginx和HTTP功能。
事件模块主要用于提供OS独立的事件通知机制(如kqueue或者epoll模型)。协议模块则负责实现Nginx通过HTTP(超文本传输协议)、SSL(安全套接层)、TLS(安全传输层)、SMTP(简单邮件传输协议)、IMAP(邮件访问协议)、POP3(邮局协议版本3)与对应的客户端建立回话。在Nginx内部,进程间的通信时通过模块的pipeline或chain而实现;换句话说,每个功能或者操作都有一个模块来实现。

Nginx功能

Nginx基础功能
  1. 处理静态文件、索引文件以及自动索引
  2. 反向代理加速(无缓存)
  3. FastCGI、简单负载均衡及容错
  4. 模块化结构。过滤器包括gzipping、byte、ranges、chunked responses、SSI-fitter,在SSI过滤器中,到同一个proxy或者FastCGI的多个字请求并发处理
  5. SSL和TLS和SNI认证的支持
Nginx IMAP/POP3代理服务功能
  • 使用外部HTTP认证服务器重定向用户到IMAP/POP3后端
  • 使用外部HTTP认证服务器认证用户后连接重定向到内部的SMTP后端
  • 认证方法:
  • POP3: POP3 USER/PASS, APOP, AUTH LOGIN PLAIN CRAM-MD5
  • IMAP: IMAP LOGIN
  • SMTP: AUTH LOGIN PLAIN CRAM-MD5
  • SSL 支持
  • 在 IMAP 和 POP3 模式下的 STARTTLS 和 STLS 支持

Nginx的特性

  • 基于IP和名称的虚拟主机服务
  • Memcached的GET接口
  • 支持keep-alive和管道连接
  • 灵活简单的配置
  • 重新配置和在线平滑升级
  • 可定制的访问日志,日志写入缓存,以及快捷的日志回卷
  • 4xx-5xx状态码重定向
  • 基于PCRE的rewrite重写模块
  • 基于客户端IP地址和HTTP基本认证和访问控制
  • PUT、DELETE、MKCOL方法
  • 支持FLV(Flash视频)
  • 带宽限制
  • 工作在OSI参考模型7层的应用层,可针对http应用做分流策略
  • Nginx对网络依赖较小,端口能通就能进行负载均衡功能
  • 对后端服务器简单的健康检测
  • 可以通过ip_hash来进行Session保持
  • 支持高并发,最好的并发为3万,测试4.5万的时候,失败连接数达到了1.5w左右
  • 支持异步网络I/O事件模型epoll(Linux内核2.6以上才支持)

Nginx与其它软件对比

Apache的特点
  • Apache2.2版本非常稳定强大,据官方说,Apache2.4版本性能更强
  • Prefork模式取消了进程创建开销,性能很高
  • 处理动态业务数据时,因关联到后端的引擎和数据库,瓶颈不在Apache上
  • 高并发时消耗系统资源相对多一些
  • 基于传统的select模型,高并发能力有限
  • 支持扩展库,可通过DSO、apxs方法编译安装额外的插件功能,不需要重新编译Apache
  • 功能多,更稳定,更安全,插件也多
  • 市场份额在逐年递减
Nginx的特点
  • 基于异步网结I/O模 型(epollk kqueue)
  • 具备支持高性能,高并发的特性,并发连接可达数万
  • 对小文件(小于1 MB的静态文件)高并发支持很好,性能很高
  • 不支持类似 Apache的DSO模式、扩展库必须编译进主程序(缺点)
  • 进程占用系统资源比较低
  • 支持Web、反向Proxy、Mail三大重点功能,幷且都很优秀
  • 市场份额在逐年快速增加

为什么选择Nginx

  • ​ 在高连接并发的情况下,Nginx是Apache服务器不错的替代品: Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一. 能够支持高达 50,000 个并发连接数的响应, 感谢Nginx为我们选择了 epoll and kqueue 作为开发模型。
  • ​ Nginx作为负载均衡服务器: Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务, 也可以支持作为 HTTP代理 服务器对外进行服务. Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多。
  • ​ 作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器), Last.fm 描述了成功并且美妙的使用经验.
  • ​ Nginx 是一个安装非常的简单 , 配置文件 非常简洁(还能够支持perl语法),Bugs 非常少的服务器: Nginx 启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动. 你还能够 不间断服务的情况下进行软件版本的升级 。
  • ​ Nginx 的诞生主要解决C10K问题。

安装依赖开发组件

  • pcre-devel: 扩展的正则表达式引擎,为了使Nginx处理更复杂的正则表达式机制
  • openssl-devel:–with-http_ssl_module使用该模块必需装openssl库,来实现http支持https协议
  • zlib-devel:zlib库是网络通信压缩库,ngx_http_gzip_module(gzip压缩模块)所必需的
yum install gcc-c++ libtool -y
yum install pcre pcre-devel openssl openssl-devel zlib zlib-devel -y

创建nginx用户组

Nginx的Master主进程以root用户身份运行,而worker子进程我们指定它为nginx用户运行

groupadd nginx 
useradd -d /home/nginx -g nginx -s /sbin/nginx nginx

下载并编译安装

1.下载Nginx

wget http://nginx.org/download/nginx-1.16.1.tar.gz

2.编译安装Nginx

tar xf nginx-1.16.1.tar.gz
cd nginx-1.16.1
./configure --prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--pid-path=/usr/local/nginx/run/nginx.pid \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--with-pcre \
--user=nginx \
--group=nginx \
--with-stream \
--with-threads \
--with-file-aio \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module 
make && make install

Nginx文件组成

tree /usr/local/nginx/ | grep -v 'default'
tree /usr/local/nginx/
/usr/local/nginx/
├── conf
│   ├── fastcgi.conf
│   ├── fastcgi.conf.default
│   ├── fastcgi_params
│   ├── fastcgi_params.default
│   ├── koi-utf
│   ├── koi-win
│   ├── mime.types
│   ├── mime.types.default
│   ├── nginx.conf
│   ├── nginx.conf.default
│   ├── scgi_params
│   ├── scgi_params.default
│   ├── uwsgi_params
│   ├── uwsgi_params.default
│   └── win-utf
├── html
│   ├── 50x.html
│   └── index.html
├── logs
├── run
└── sbin
    └── nginx

5 directories, 18 files

一级目录

  1. conf:配置文件目录
  2. html:网页文件目录
  3. logs:日志存储目录
  4. run:编译时指定的nginx pid目录
  5. sbin:程序脚本目录

二级目录

  1. conf/nginx.conf:主配置文件
  2. conf/{fastcgi scgi uwsgi}:这四个文件是相关协议配置文件
  3. conf/mime.types:支持的mime类型
  4. conf/win-utf:设置nginx的字符编码

Nginx主程序管理命令

Nginx启动文件目录:/usr/local/nginx/sbin/nginx,通过-h来查看帮助

 /usr/local/nginx/sbin/nginx -h
nginx version: nginx/1.16.1
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-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: /usr/local/nginx/)
  -c filename   : set configuration file (default: /usr/local/nginx/conf/nginx.conf)
  -g directives : set global directives out of configuration file

-v显示Nginx版本号,不过-h和-V也都能显示

/usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.16.1

-V显示Nginx配置选项,即是我们在编译Nginx时添加的参数

/usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --pid-path=/usr/local/nginx/run/nginx.pid --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --with-pcre --user=nginx --group=nginx --with-stream --with-threads --with-file-aio --with-http_v2_module --with-http_ssl_module --with-http_realip_module --with-http_gzip_static_module --with-http_stub_status_module

-t检测Nginx配置文件是否有语法错误

正确示范
/usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

错误示范
/usr/local/nginx/sbin/nginx -t
nginx: [emerg] unexpected end of file, expecting ";" or "}" in /usr/local/nginx/conf/nginx.conf:120
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

-T检测Nginx配置文件语法,然后进行输出配置文件信息并关闭

/usr/local/nginx/sbin/nginx -T

-s向主进程发送信号,分别为:stop(停止), quit(退出), reopen(重新打开日志文件), reload(重载)

/usr/local/nginx/sbin/nginx 
/usr/local/nginx/sbin/nginx -s reload
/usr/local/nginx/sbin/nginx -s reopen
/usr/local/nginx/sbin/nginx -s quit
/usr/local/nginx/sbin/nginx -s stop

-p指定Nginx安装路径

/usr/local/nginx/sbin/nginx -p /usr/local/nginx 

-c指定Nginx配置文件

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf -t

-g命令指定Nginx全局配置文件指令启动nginx

/usr/local/nginx/sbin/nginx -g "user nginx;"
ps -ef|grep nginx
root      9840     1  0 13:29 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -g user nginx;
nginx     9841  9840  0 13:29 ?        00:00:00 nginx: worker process
root      9843  6673  0 13:29 pts/0    00:00:00 grep --color=auto nginx

Nginx加入环境变量

cat > /etc/profile.d/nginx.sh <<EOF
export PATH=\$PATH:/usr/local/nginx/sbin
EOF
source /etc/profile

Nginx默认配置文件

以下内容过滤了以空行和注释为首的行

[root@CentOS7-node1 /]# cat /usr/local/nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

nginx.conf主配置文件结构:

main block:主配置段,也即全局配置段;
    event {
        ...
    }:事件驱动相关的配置;
http {
    ...
}:http/https 协议相关的配置段;
mail {
    ...
}
stream {
    ...    四层代理相关配置段
}

main block:主配置文件段,又称全局配置段,在该段的配置会应用到整个Nginx服务器内
http:http字段内的配置会应用到所有主机上
mail:邮件功能段
stream:四层代理功能段

启动测试Nginx站点

/usr/local/nginx/sbin/nginx -t
/usr/local/nginx/sbin/nginx
curl http://127.0.0.1 -I
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Fri, 20 Mar 2020 05:45:18 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Fri, 20 Mar 2020 05:22:06 GMT
Connection: keep-alive
ETag: "5e7452fe-264"
Accept-Ranges: bytes

nginx默认监听80端口
img

客户端测试访问
img

Nginx编译参数

常用的编译参数

  • –prefix=path :定义保留服务器文件的目录,它/usr/local/nginx默认设置目录
  • –sbin-path=path :设置nginx可执行文件的名称。该名称仅在安装期间使用,默认情况下该文件被命名prefix(即安装目录)/sbin/nginx
  • –conf-path=path :设置nginx配置文件的名称
  • –pid-path=path :设置将存储主进程ID的nginx.pid文件的名称。安装后,可以nginx.config使用pid指令随机在配置文件中更改文件名。默认情况下该文件命名prefix/logs/nginx.pid
  • –error-log-path=path :设置主要错误的名称,警告和诊断文件,安装完成后,可以nginx.conf使用error_log指令始终在配置文件中更改文件名,默认情况下该文件被命名prefix/logs/error.log
  • –http-log-path=path :设置HTTP服务器的主要请求日志文件的名称。安装完成后,可以nginx.conf使用access_log指令随时在配置文件中更改文件名。默认情况下该文件被命名为prefix/logs/access.log
  • –build=name :设置一个可选的nginx构建名称
  • –user=name :设置其凭据将由工作进程使用的非特权用户的名称,安装后,可以nginx.conf使用user指令始终在配置文件更改名称。默认的用户名是nobody
  • –group=name : 设置将由工作进程使用凭据的组的名称。安装后,可以nginx.conf使用user指令始终在配置文件中 更改名称 。默认情况下,组名称设置为非特权用户的名称
  • –with-pcre=path :localtion指令和重写模块中支持正则表达式所需的PCRE库源路径
  • –with-pcre-jit :用“即时编译”支持(pcre-jit指令)构建pcre库
  • –with-zlib=path :Gzip模块zlib需要库源路径并不是安装路径

配置Nginx GCC选项

  • –with-cc-opt=”“其他参数添加到CFLAGS变量中。当在FreeBSD下使用系统PCRE库时,必需的值是。如果需要增加支持的文件数量,它也可以在这里指定,如下例所示:。–with-cc-opt=”-I /usr/local/include”select()–with-cc-opt=”-D FD_SETSIZE=2048″
  • –with-ld-opt= ““在链接过程中使用的其他参数。当在FreeBSD下使用系统PCRE库时,强制值为。–with-ld-opt=”-L /usr/local/lib”

指定Nginx连接处理方法

  • –without-select_module :禁用select模块
  • –with-select_module:启用select模块支持(一种轮询模式,不推荐在高载环境下使用)
  • –with-poll_module :启用pooll()模块支持,功能与select模块相同,特性相同,不推荐在高载环境下使用
  • –without-select_module :禁用poll()模块支持

默认建立的模块

如果不需要则在编译Nginx时使用–without-http_x_x禁用掉

  • http_access_module :接受或拒绝来自指定客户端地址的请求
  • http_auth_basic_module :通过使用HTTP基本认证协议验证用户名和密码来限制对资源的访问
  • http_autoindex_module :处理以正斜杠(/)结尾的请求并生成目录列表
  • htt_browser_module :创建值取决于User-Agent请求头的值的变量
  • http_charset_module :将指定字符集添加到Content-Type响应头,可以将数据从一个字符集转换到另一个
  • http_empty_gif_module :发射单像透明的GIF
  • http_fastcgi_module :将请求传递给FastCGI服务器
  • http_geo_module :使用取决于客户端IP地址的值创建变量
  • http_gzip_module :使用gzip模块将传输的数据减少一半或者更多需要zlib库来构建和运行此模块
  • http_limit_conn_module :限制每个定义密钥的连接数量,特别是单个IP地址的连接数量
  • http_req_module :限制每个定义密钥的请求处理速率,特别是来自单个地址的请求的处理速率
  • http_map_module :创建爱你值取决于其它变量值的变量
  • http_proxy_module :将HTTP请求传递给另一台服务器
  • http_memcached_module :将请求传递给另一台服务器
  • http_referer_module :在Referer头中阻止具有无效值的请求
  • http_rewrite_module :HTTP服务器重定向请求并更改请求所使用的URL模块(地址重写),pcre库需要构建和运行该模块
  • http_scgi_module :将请求传递给SCGI服务器
  • http_ssi_module:处理通过它的相应中的SSI(服务端包含)命令
  • http_split_clients_module :创建一个适合A/B测试,也成为_split变量testing
  • http_upstream_hash_module :启用通用哈希负载方法
  • http_upstream_ip_module :启用Ip哈希负载平衡方法
  • http_upstream_keepalive_module :启用保持连接
  • http_least_conn_module :启用最少连接负载平衡方法
  • http_upstream_zone_module :启用共享内存区域
  • http_userid_module :设置适合客户识别的Cookie
  • http_uwsgi_module :将请求传递给uwsgi服务器

未默认建立的模块

  • –with-cpp_test_module :测试头文件的C++兼容性
  • –with-debug :启用条用日志
  • –with-file-aio :启用异步I/O
  • –with-google_perftools_module :允许使用Google Performance工具库
  • –with-http_addition_module :在响应之前和之后添加文本
  • –with-http_auth_request_module :根据子请求的结果实现客户端授权
  • –with-http_dav_module :使用WebDAV协议启用文件管理自动化以支持PUT、DELETE方法
  • –with-http_degradation_module :当内存大小超过定义的值时允许返回错误
  • –with-http_gzip_static_module:允许使用.gz文件扩展名而不是常规文件发送预压缩文件
  • –with-http_image_filter_module :启用ngx_http_image_filter_module支持,传输JPEG/GIF/PNG图片的一个过滤器,默认不启用,需要装gd库
  • –with-http_stub_status_module :启用状态统计模块(获取nginx自上次启动以来的工作状态),zabbix监控nginx访问量、请求数必备模块
  • –with-http_sub_module :通过将另一个指定的字符串替换为另一个字符串来修改响应
  • –with-http_v2_module :启用HTTP/2的支持
  • –with-ipv6 :启用Ipv6支持
  • –with-mail:启用邮件代理功能
  • –with-mail_sll_module :为邮件代理服务器提供对SSL/TLS协议的支持,需要SSL库 openssl库
  • –with-stream:启用TCP和UDP代理功能
  • –with-threads:使Nginx能够使用线程池
  • –with-http_flv_module : 为Flash视频(FLV)文件提供伪流服务器端支持,启用该模块,提供寻求内存使用基于时间的偏移量文件
  • –with-http_realip_module:后台Nginx服务器记录原始客户端的IP地址,更多知识点击“传送门
  • –with-http_ssl_module:开启gx_http_ssl_module以支持SSL/TLS

静态链接模块

内置于Nginx OSS中的大多数模块都是静态链接的:它们在编译时内置于NGINX OSS中,并静态链接到NGINX二进制文件。只有通过重新编译NGINX才能禁用这些模块
格式如下:

--add-module=path :添加静态模块path来指定静态模块路径

动态链接模块

Nginx模块也可以编译为共享对象(*.so文件),然后在运行时动态加载到Nginx OSS中要使用动态加载的第三方模块编译Nginx OSS,需按照以下格式:

--add-dynamic-module=path :path指定动态模块路径,动态模块是以.so结尾的文件

Nginx配置文件优化

Nginx.conf主配置文件结构

main block:主配置段,也即全局配置段;
event {
        ...
       }:事件驱动相关的配置;
http {
    ...
}:http/https 协议相关的配置段;
mail {
    ...
}
stream {
    ...
}

main block:主配置文件段,又称全局配置段,在该段的配置会应用到整个Nginx服务器内
http:http字段内的配置会应用到所有主机上
mail:邮件功能段
stream:四层代理功能段


全局配置段

main block:主配置段,也即全局配置段;
event {
        ...
      }:事件驱动相关的配置;

1.运行用户组配置

user  nginx nginx;
定义Nginx的worker进程运行的用户和用户组,Nginx的Master进程以root启动

2.nginx进程数设置

worker_processes  number | auto;
worker进程的数量;应该等于或小于当前主机的cpu的物理核心数。auto选项为自动填充nginx进程数量,auto会根据CPU核心数量来定义进程数量

worker_cpu_affinity auto | cpumask;
nginx进程绑定CPU核心参数:

auto用法:
worker_cpu_affinity auto;
auto代表根据Nginx进程数worker_processes自动绑定CPU个数,假如Nginx设置的进程数为8个,就会自动绑定8颗CPU核心,如果设置的进程数多于核心数,auto也只是会绑定系统CPU的个数。

cpumask用法:
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
cpumask是根据cpu核心的掩码来绑定的每颗CPU,假设我们有8颗CPU核心那就是8个零,CPU的开始个数是从0-7来计算。
第0颗CPU掩码是:00000001
第1颗CPU掩码是:00000010
第2颗CPU掩码是:00000100
以此类推...
假如我们这台设备上还有其它应用或者进程需要用到CPU,我们可以为Nginx绑定4颗CPU核心
绑定4颗CPU核心可以这样写来绑定前四颗CPU:
worker_cpu_affinity 00000001 00000010 00000100 00001000
当然也可以绑定后四颗CPU或者绑定8颗CPU中的任意四个,比较灵活

worker_priority number;
指定worker进程的nice值,设定worker进程的优先级,值为 [-20,19]
Linux系统中,优先级高的进程会占用更多的系统资源,这里配置的是进程的静态优先级,默认每个应用CPU的优先级都为0,取值范围-20到+19,-20级别最高。因此可以把这个值设置小一点,但不建议比内核进程的值低(通常为-5)
ps axo comm,pid,psr,ni | grep nginx
nginx            8787   1   0
nginx            9323   0   0
nginx            9324   1   0
可以看到nginx的1个主进程和两个子进程的优先级都为0,我下面将nginx使用cpu的优先级调整为-5,重启nginx应用后再次查看CPU优先级
worker_priority -5;
ps axo comm,pid,psr,ni | grep nginx
nginx            8787   1   0
nginx           12709   0  -5
nginx           12710   1  -5
可以看到已经变为了-5

3.日志和PID位置

error_log logs/error.log warn;
pid run/nginx.pid;
error_log:nginx日志路径及错误日志的日志级别,日志级别有 debug | info | notice | warn | error | crit | alert | emerg
pid:定义pid文件存放路径

4.Nginx进程最大打开文件数

worker_rlimit_nofile 65535;
指定Nginx的worker进程所能够打开的最大文件数,此值建议设置为nginx运行用户使用ulimit -n的系统文件打开数一致,这是因为Nginx调度时分配请求到进程并不是那么均衡,此值要大于等于进程数 worker_processes * worker_connections 的乘积,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误,

5.事件驱动events相关配置

events {
    use epoll;
    worker_connections  8192;
    multi_accept on;
    accept_mutex on;
}

use epoll;
参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]
epoll模型是Linux内核2.6以上版本中的高性能网络I/O模型,Linux建议epoll,如果Nginx跑在FreeBSD上面,那就建议选用kqueue模型。更多网络I/O模型知识,请移步 IO模型详解:

worker_connections  8192;
单个Nginx进程最大连接数,Nginx的最大连接数=worker_connections * worker_processes
Nginx单个进程最大连接数根据硬件资源调整,需要业务量较大,那就尽量大,但要注意别把CPU跑到太高,也要注意后端应用的压力,否分会返回504、502等

multi_accept on;
开启nginx批量建立新连接设置

accept_mutex on | off;
Nginx处理新的连接请求的方法,on指由各个worker轮流处理新请求,Off指每个新请求的到达都会通知(唤醒)所有的worker进程,但
只有一个进程可获得连接,造成“惊群”,影响性能,默认on

HTTP配置段

http {
    ...
}:http/https 协议相关的配置段;

1.资源类型表

include       mime.types;
资源类型对应表,对应表在 nginx/conf/mime.types,这个文件中保存了很多页面类型

default_type application/octet-stream;
默认资源类型,如果访问nginx的资源类型在 mime.types 类型表中不存在,nginx则认为请求是这里设定的默认类型。

下图中我们访问资源可以看到nginx返回的资源类型格式为 mime.types中定义的 test/html 格式
img
这里可以看到返回资源类型格式为 image/gif 格式
img
如果访问的格式在 mime.types 中不存在则会返回 application/octet-stream; 格式

2.字符编码

charset utf-8;
指定nginx字符编码

3.Nginx版本隐藏

server_tokens on | off;
nginx默认不隐藏版本信息,这对外来说比较危险
on 开启nginx版本信息
off 关闭nginx版本信息

4.网络连接配置

sendfile on | off;
开启高效文件传输模式,sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime

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

tcp_nopush on | off;
当 sendfile 为 on的情况下,开启此参数才会生效,当sendfile为 off 时,将延迟发送较小的数据报文,合并多个较小请求数据报文后再发送,默认为 on 不延迟发送。

tcp_nodelay on;
不延迟发送较小的数据报文,在keepalived模式才能使用此参数。

keepalive_timeout  65s;
nginx长连接保持时间,设置为0表示nginx服务器处理完请求后立刻断开与客户端的连接,默认为65s;

keepalive_requests 100;
保持长连接的会话数量,默认为100个;

keepalive_disable none | browser ...;
禁用与行为不端的浏览器保持连接,意思为你想禁用某种浏览器使用长链接的时候可以在此写入浏览器的名称,默认为 keepalive_disable msie6

send_timeout 65s; 
设置将响应传输到客户端的超时时间,超时仅在两个连续的写操作之间设置,而不用于传输整个响应。如果客户端在此时间内未收到任何信息,则连接将关闭

types_hash_max_size 2048;
types_hash_max_size影响散列表的冲突率。types_hash_max_size越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快。types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升,单位是项或者条目  

reset_timedout_connection on;
开启超时连接复用功能, 服务器在客户端停止发送应答之后关闭连接;允许server在client停止响应以后关闭连接,释放分配给该连接的内存。当有大并发需求时,建议打开。

5.Nginx缓存配置

client_body_buffer_size 128k;
用于接收客户端请求报文的body部分的缓冲区大小;默认为16k;请求报文body超出此大小时,其将暂存到磁盘上由client_body_temp_path指令所指定的位置,nginx开启了上传功能,并且在往nginx服务器上传文件时在请求报文中才有body。一般为博客等2.0站点,我们在上传文章时,需要开启此功能。

client_body_temp_path temp [level1 [level2 [level3]]]
设定用于存储客户端请求报文的body部分的临时存储路径及子目录结构和数量;
例如:
client_body_temp_path /usr/local/nginx/client_body_temp/ 2 1 1 
1:表示用一位16进制数字表示一级子目录;0-f  2表示256个一级子目录(共有256个一级子目录)
2:表示用2位16进程数字表示二级子目录:00-ff 每个一级子目录下有16个二级子目录(共有256*16个二级子目录)
2:表示用2位16进程数字表示三级子目录:00-ff 每个二级子目录下有16个三级子目录(共有256*16*16个三级子目录)

client_body_timeout 30s;
定义读取客户端请求body的超时时间,超时仅针对两个连续的读操作之间的一段时间设置,而不针对整个请求体的传输。如果客户端在这段时间内没有传输任何内容,则请求将使用408(请求超时)错误终止。

client_max_body_size 10m;
指定允许通过Nginx上传文件的大小

client_header_buffer_size 4096k;
客户端请求头部的缓冲区大小,可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。 

large_client_header_buffers 4 128k;
客户请求头部缓冲区大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。

client_header_timeout 30s;
客户端头部超时时间,如果客户端在这段时间内没有传输整个报头,Nginx则主动关闭连接后返回408错误。

server_names_hash_bucket_size 128;
服务器名字的hash表大小;保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小

6.对客户端限制相关配置

limit_rate rate;
限制响应给客户端的传输速率,单位是bytes/second,0表示无限制;
                        
limit_except method ... { ... }
除来使用limit_except指定的方法之外的方法进行限制
例如:
只允许192.168.168.1.0/24网段访问请求,但是GET方法排除在外(不接受限制),安全限制访问逻辑,一般只对外开放 GET POST 方法,像 DELETE请求方法是禁止的
limit_except GET {
        allow 192.168.1.0/24;
        deny  all;
}

7.文件操作优化配置

aio on | off | threads[=pool];
是否启用文件系统的aio功能;
    
directio size | off;
在Linux主机启用O_DIRECT标记,此处意味文件大于等于给定的大小时使用,例如directio 4m;

open_file_cache max=65535 inactive=60s;
此参数来为Nginx的打开文件数做缓存,默认未启用,max值指定缓存数量,因为我们在全局配置中指定了Nginx的最大打开数为65535,所以在此的max值也最好一至,"inactive=60s"是指60秒后缓存过的文件没有被访问则被删除
nginx可以缓存以下三种信息:
            (1) 文件的描述符、文件大小和最近一次的修改时间;
            (2) 打开的目录结构;
            (3) 没有找到的或者没有权限访问的文件的相关信息;

open_file_cache_valid 30s;
缓存项有效性的检查频率;默认为60s,主要检查缓存有效信息

open_file_cache_min_uses 1;
open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除

open_file_cache_errors on;
是否打开文件错误信息

8.压缩功能配置

gzip on;
启用gzip压缩输出

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

gzip_buffers 16 64K;
支持实现压缩功能时为其配置的缓冲区数量及每个缓存区的大小

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

gzip_comp_level 6;
设置响应的gzip压缩级别,可接受的值在1到9之间

gzip_types text/plain application/x-javascript text/css application/xml application/javascript;
压缩过滤器,仅对此处设定的文件格式类型启用压缩功能

gzip_vary on;
开启对vary header支持

gzip_proxied any;
gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any …
nginx作为代理服务器接收到从被代理服务器发送的响应报文后,在何种条件下启用压缩功能的;off:对代理的请求不启用
no-cache, no-store,private:表示从被代理服务器收到的响应报文首部的Cache-Control的值为此三者中任何一个,则启用压缩功能

underscores_in_headers on;
在客户端请求头字段中启用下划线;off代表关闭下滑线;禁用下划线时,名称包含下划线的请求头字段将被标记为无效,并受ignore_invalid_headers指令的约束

9.location配置
关于location正则匹配请看站内其文章,这里讲解location中的参数配置

location / {
    root    /data/nginx/html;
    index index.html index.htm index.php;
}

root html;
指定nginx的网页目录,如果匹配到了此location,那么将会到定义root的目录中寻找资源。

index index.html index.htm index.php
指定nginx的网页默认资源,如果匹配到了此location,那么访问请求首先会找 index.html 文件,如果index.html文

Nginx Location正则匹配及优先级

在一个server中location配置段可存在多个,用于实现从url到文件系统的路径映射;nginx会根据用户请求的uri来检查定义的所有location,并找出一个最佳匹配,而后应用其配置。

官方文档地址:http://nginx.org/en/docs/http/ngx_http_core_module.html#location

基本语法如下:

location [ = | ~ | ~* | ~ ] uri { … }
=:对URI的右半部分做精确匹配,区分字符大小写;
~:对URI的左半部分做匹配检查,不区分字符大小写;
~:对URI做正则表达式模式匹配,区分字符大小写;
~*:对URI做正则表达式模式匹配,不区分字符大小写;

1.location 语法如下

Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default:    —
Context:    server, location

2.官方示例

#精确匹配(区分字符大小写)
location = / {
    [ configuration A ]
}

#通用匹配
location / {
    [ configuration B ]
}

#路径匹配
location /documents/ {
    [ configuration C ]
}

#左侧开头匹配(^~ 不区分大小写)
location ^~ /images/ {
    [ configuration D ]
}

#右侧结尾匹配(~* 不区分大小写)
location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

假如上面location的域名是 k8sops.cn,那么访问如下几种情况会匹配到哪个location?

  1. 访问地址 https://k8sops.cn/ (地址匹配 A 和 B,但是会访问到 A 上,因为精确匹配优先级最高)
  2. 访问地址 https://k8sops.cn/index.html (地址只匹配B,所以访问到B上)
  3. 访问地址 https://k8sops.cn/documents/document.html (地址匹配 B 和 C,因为C的匹配长度和相似度最高,所以匹配到C上)
  4. 访问地址 https://k8sops.cn/images/1.gif (地址匹配 B|D|E,最后会被匹配到 D 上,因为 ~ 的优先级仅次于 = 号)
  5. 访问地址 https://k8sops.cn/documents/1.jpg (地址匹配 B C E,最后会陪匹配到 E 上,因为 ~* 优先级要高于 /)

location在一次访问中只会使用一次,访问请求进来后会根据location优先级检查匹配,优先级最高的获得请求匹配。

Location 案例

1.通用及路径匹配

server {
        listen       80;
        server_name k8sops.cn;

#通用匹配
        location / {
            return 400;
        }

#路径匹配
        location /k8sops {
            return 401;
        }

#精确匹配
        location = /abcops {
            return 402;
        }

#正则匹配区分大小写
        location ~ /docker {
            return 403;
        }
}

2.以xx开头或以xx结尾

server {
        listen       80;
        server_name k8sops.cn;

#以kubernetes开头区分大小写
#访问地址: http://k8sops.cn/kubernetes
        location ^~ /kubernetes {
            return 401;
        }

#以.php结尾区分大小写
#访问地址:http://k8sops.cn/index.php
        location ~ \.php$ {
            root /data/nginx/html;
            index index.php;
        }

#以.jps结尾区分大小写
#访问地址:http://k8sops.cn/index.jsp
        location ~ \.jsp$ {
            root /data/nginx/html;
            index index.jsp;
        }

#以多个.xxx结尾区分大小写
#访问地址:http://k8sops.cn/image.(gif|png|jpg|jpeg|svg|ico)
        location ~ \.(gif|png|jpg|jpeg|svg|ico)$ {
             root /data/nginx/html;
        }
}

Location优先级

多个location优先级,匹配优先级顺序:=, ~, ~/~*,不带符号;

1.根路径匹配优先级比较
访问地址: http://k8sops.cn/kubernetes

server {
        listen       80;
        server_name k8sops.cn;

        location / {                                优先级最低
            return 401;
        }

        location /kubernetes {                      优先级中等
            return 402;
        }

        location ~ ^/kubernetes {                   优先级最高
            return 403;
        }
}

2.正则优先级匹配
访问地址:http://k8sops.cn/kubernetes/devops

server {
        listen       80;
        server_name k8sops.cn;

#优先级最低
        location / {
            return 401;
        }

#优先级最高,nginx按照顺序从上往下匹配, 路径到这里匹配成功后就会再往下面匹配
        location ~ /kubernetes {                    
            return 402;
        }

#优先级同第二个location,因为位置在第二个location下面,所以在第二个location匹配成功后,就不会在匹配此location
        location ~ ^/kubernetes {                   
            return 403;
        }

#优先级与上面两个一样高,只是此location位置在下面,上面的location匹配成功后,就不会在往下匹配
        location ~ ^/kubernetes/devops {            
            return 405;
        }
}

3.正则与精准匹配
访问地址:http://k8sops.cn/kubernetes
访问地址:http://k8sops.cn/kubernetes/devops

server {
        listen       80;
        server_name k8sops.cn;

        location ~ ^/kubernetes/devops {
            return 401;
        }

        location ~ /kubernetes {
            return 402;
        }

        location ~ ^/kubernetes {
            return 403;
        }

#访问地址为 http://k8sops.cn/kubernetes 时,此location优先级最高
        location = /kubernetes {            
            return 405;
        }

#访问地址为 http://k8sops.cn/kubernetes/devops 时,此location优先级最高
        location = /kubernetes/devops {
            return 406;
        }
}

优先级结论

  1. 精准匹配 —> 正则匹配 —> 通用匹配
  2. 正则多次命中,选择第一个命中的location,后面不在匹配
  3. 通用多个命中,选择匹配度最高的location

Nginx Root 和 Alias 配置区别

Nginx location中可以定义root网站目录及alias也是网站目录参数,两个参数区别如下:

  • root:给定的路径对应于location中的/uri/左侧的/
    例如:客户端请求 http://k8sops.cn/k8sops/ 时,对应服务器的 /usr/local/nginx/html/k8sops/index.html
  • alias:给定的路径对应于location中的/uri/右侧的/
    例如:客户端请求 http://k8sops.cn/devops/ 时,对应服务器的 /usr/local/nginx/html/index.html

案例

1.修改配置

server {
        listen       80;
        server_name k8sops.cn;

        location  /k8sops {
            root html;                  #需要访问 html/k8sops/index.html
            index index.html;
        }

        location  /devops {
            alias html;                 #访问网站根目录 index.html
            index index.html;
        }
}

2.添加网站文件

pwd
/usr/local/nginx/html

cat index.html
<center> <h1>Welcome to Devops Alias!</h1> </center>

cat k8sops/index.html
<center> <h1>Welcome to K8sops Root!</h1> </center>

3.测试访问

curl http://k8sops.cn/k8sops/
<center> <h1>Welcome to K8sops Root!</h1> </center>


curl http://k8sops.cn/devops/
<center> <h1>Welcome to Devops Alias!</h1> </center>

4.总结
root 指定的目录为网站根目录,locaiton 中的路径需要在根目录中存在,当使用root时,nginx会先寻找根目录下location指定的目录,然后是网页文件。
Alias 指定的目录也为网站根目录,location 中的路径不需要在根目录中存在,当使用 alias 时,nginx会直接在根目录下寻找网页文件。

Nginx 自签名Https证书配置

  • Nginx默认不支持https,支持的是http的80端口
  • 在nginx编译的时候需要编译 --with-http_ssl_module 模块来支持https,而且需要安装依赖包 openssl openssl-devel 来支持ssl
  • https需要证书和私钥,获得证书和私钥的途径可以分为两类,在域名注册商备案后进行申请证书和私钥,而本章要讲解的是使用openssl来生成证书和私钥

自签名https证书实战

1.创建带密码的私钥

mkdir /usr/local/nginx/ssl
cd /usr/local/nginx/ssl/
openssl genrsa -des3 -out server.key 4096                   #4096为私钥长度
Generating RSA private key, 4096 bit long modulus
........................................................................................................++
.................++
e is 65537 (0x10001)
Enter pass phrase for server.key:                           #输入自定义密码(随意)
Verifying - Enter pass phrase for server.key:               #确认输入的密码

2.私钥去除密码
带密码的私钥在https上不能使用,所以需要移除密码

cp -rf server.key server.key.org                            #复制一份密钥
openssl rsa -in server.key.org -out server.key              #将复制过的密钥覆盖掉原来的密钥并且去除密码
Enter pass phrase for server.key.org:                       #输入刚才私钥的密码
writing RSA key

3.创建证书请求文件
使用私钥创建出证书请求文件

openssl req -new -key server.key -out server.csr

Country Name (2 letter code) [XX]:CN                                    #输入国家简称
State or Province Name (full name) []:shanghai                          #输入地区省份
Locality Name (eg, city) [Default City]:shanghai                        #输入所在城市
Organization Name (eg, company) [Default Company Ltd]:k8sops            #输入组织名称
Organizational Unit Name (eg, section) []:k8sops                        #输入组织单元名称
Common Name (eg, your name or your server's hostname) []:k8sops         #输入主机名
Email Address []:                                                       #邮箱忽略
    
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:                                                #密码忽略
An optional company name []:                                            #公司名称忽略

4.生成证书

openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt         #3650为有效期
Signature ok
subject=/C=CN/ST=shanghai/L=shanghai/O=k8sops/OU=k8sops/CN=k8sops
Getting Private key

5.文件介绍

server.crt          #证书
server.csr
server.key          #私钥
server.key.org

配置Https

server {
        listen  80;
        server_name k8sops.cn;
        return 301 https://$server_name$request_uri;                #跳转ssl
}

server {
        listen  443 ssl;                                            #这里要加ssl,不然不是加密传输
        server_name k8sops.cn;
        ssl_certificate /usr/local/nginx/ssl/server.crt;            
        ssl_certificate_key /usr/local/nginx/ssl/server.key;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers  ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;
        access_log /usr/local/nginx/logs/access.log main;
        location  / {
            root html;
            index index.html;
        }
}

测试访问

访问 http://k8sops.cn 会自动跳转至 https://k8sops.cn
注:自签名证书不受浏览器信任

Nginx 之 ngx_http_access_module 访问控制模块(针对客户端地址)

Nginx通过 ngx_http_access_module 模块允许限制对某些客户端地址的访问
限制源地址访问的功能

  1. 设置IP白名单,只允许写入到白名单的IP地址访问Nginx
  2. 设置IP黑名单,写入黑名单的IP都不允许访问Nginx

**ngx_http_access_module模块官方文档:**http://nginx.org/en/docs/http/ngx_http_access_module.html

限制源地址需要注意

  1. 如果源地址是动态公网地址或者拨号网络,不建议使用IP限制
  2. 如果Nginx前面放的有 F5 或者 LVS 等代理服务器,可以让F5或者LVS服务器将客户端真实地址与请求一同转发至Nginx后再做IP限制

参数介绍

#allow 参数语法
Syntax: allow address | all;
Default:    —
Context:    http, server, location, limit_except

#allow 参数语法
Syntax: deny address | all;
Default:    —
Context:    http, server, location, limit_except

#案例
location / {
    deny  192.168.1.1;                      #拒绝192.168.1.1主机访问
    allow 192.168.1.0/24;                   #允许192.168.1.0/24网段访问,但是排除掉了此网段中的192.168.1.1主机
    allow 10.1.1.0/16;                      #允许10.1.1.0/16网段访问
    allow 2001:0db8::/32;                   #允许ipv6地址 2001:0db8::/32 访问
    deny  all;                              #其它所有地址都拒绝
}

Nginx服务器上的所有虚拟主机限制源地址

将限制加到http中对所有server生效
假如我们nginx服务器上有三台虚拟主机,这三台虚拟主机都需要禁止67.203.239.191地址和192.168.23.0/24网段,其它都允许访问。

vim /usr/local/nginx/conf/nginx.conf        #可以在主配置文件http配置段中加入以下
    deny 67.203.239.191;
    deny 192.168.23.0/24;
    allow all;

或者在nginx.conf配置文件中通过 include 参数来指定位置,如下:

#在nginx.conf http 配置段中加入  include /usr/local/nginx/conf/access_limit.conf;

#创建此配置文件
vim /usr/local/nginx/conf/access_limit.conf
deny 67.203.239.191;
deny 192.168.23.0/24;
allow all;

完成操作后,重启nginx即可

Nginx服务器上的单个虚拟主机限制源地址

将限制加入server中只对当前server生效
假如我们nginx服务器上面还是有三台虚拟主机,我们想让 k8sops.cn 这台虚拟主机只能允许192.168.31.0/24网段访问,拒绝其它所有地址。
找到本地虚拟主机的配置文件,加入以下内容;

server {
        listen  80;
        server_name k8sops.cn;
        
        allow 192.168.31.0/24;    
        deny all;
        
        location  / {
            root html;
            index index.html;
        }
        
        location /k8sops {
            alias html;
            index index.html;
        }
}

Nginx服务器上的单个location限制源地址

将限制加入location中只对当前location生效
nginx服务器需要添加一个连接,只允许本地访问,拒绝其它所有地址

        location /ngx_status {
            stub_status on;
            allow 127.0.0.1;
            deny all;
        }

Nginx 之 ngx_http_auth_basic_module 身份验证模块

Nginx使用 ngx_http_auth_basic_module 模块使用“ HTTP基本身份验证”协议验证用户名和密码来限制对资源的访问

ngx_http_auth_basic_module模块官方文档: http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html

参数介绍

#auth_basic语法
Syntax: auth_basic string | off;
Default:    auth_basic off;
Context:    http, server, location, limit_except

#auth_basic_user_file语法
Syntax: auth_basic_user_file file;
Default:    —
Context:    http, server, location, limit_except

#案例:
location / {
    auth_basic           "closed site";             #认证命名(自定义)
    auth_basic_user_file conf/htpasswd;             #认证密码文件
}

Nginx服务器上的所有虚拟主机身份认证

将认证加到http中对所有server生效

安装httpd-tools工具
yum install httpd-tools.x86_64 -y

使用htpasswd命令来创建账户,首次创建用户需要加-bc参数
htpasswd -bc /usr/local/nginx/conf/htpasswd nginx_user1 3edc#EDC        #创建用户nginx_user1,密码"3edc#EDC"
Adding password for user nginx_user1

修改账户文件属性为Nginx进程所属用户,密码文件改为600是为了安全性
chown -Rf nginx.nginx /usr/local/nginx/conf/htpasswd
chmod 600 /usr/local/nginx/conf/htpasswd 

将以下配置加入nginx.conf主配置文件中的http配置段中以启用全站身份认证

vim /usr/local/nginx/conf/nginx.conf
auth_basic "User Authentication";
auth_basic_user_file /usr/local/nginx/conf/htpasswd;

测试访问
img
img

Nginx服务器上的单个虚拟主机身份认证

将认证加到server中对当前server生效

安装httpd-tools工具
yum install httpd-tools.x86_64 -y

使用htpasswd命令来创建账户,首次创建用户需要加-bc参数
htpasswd -bc /usr/local/nginx/conf/htpasswd nginx_user1 3edc#EDC        #创建用户nginx_user1,密码"3edc#EDC"
Adding password for user nginx_user1

修改账户文件属性为Nginx进程所属用户,密码文件改为600是为了安全性
chown -Rf nginx.nginx /usr/local/nginx/conf/htpasswd
chmod 600 /usr/local/nginx/conf/htpasswd 

将以下配置加入虚拟主机配置文件中的server配置段中以启用当前虚拟主机身份认证

vim /usr/local/nginx/conf/conf.d/vhost.conf
server {
        listen  80;
        server_name k8sops.cn;
        return 301 https://$server_name$request_uri;
}

server {
        listen  443 ssl;
        server_name k8sops.cn;
        ssl_certificate /usr/local/nginx/ssl/server.crt;
        ssl_certificate_key /usr/local/nginx/ssl/server.key;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers  ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;
        access_log /usr/local/nginx/logs/access.log main;

        allow 192.168.31.0/24;
        deny all;

#加入以下配置
        auth_basic "User Authentication";       
        auth_basic_user_file /usr/local/nginx/conf/htpasswd;

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

        location /k8sops {
            alias html;
            index index.html;
        }

        location /ngx_status {
            stub_status on;
            allow 127.0.0.1;
            deny all;
        }
}

测试访问
img
img

Nginx服务器上的单个location身份认证

将认证加到location中对当前location生效

安装httpd-tools工具
yum install httpd-tools.x86_64 -y

使用htpasswd命令来创建账户,首次创建用户需要加-bc参数
htpasswd -bc /usr/local/nginx/conf/htpasswd nginx_user1 3edc#EDC        #创建用户nginx_user1,密码"3edc#EDC"
Adding password for user nginx_user1

修改账户文件属性为Nginx进程所属用户,密码文件改为600是为了安全性
chown -Rf nginx.nginx /usr/local/nginx/conf/htpasswd
chmod 600 /usr/local/nginx/conf/htpasswd 

将以下配置加入虚拟主机配置文件中的location配置段中以启用当前location身份认证

erver {
        listen  80;
        server_name k8sops.cn;
        return 301 https://$server_name$request_uri;
}

server {
        listen  443 ssl;
        server_name k8sops.cn;
        ssl_certificate /usr/local/nginx/ssl/server.crt;
        ssl_certificate_key /usr/local/nginx/ssl/server.key;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers  ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;
        access_log /usr/local/nginx/logs/access.log main;

        allow 192.168.31.0/24;
        deny all;

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

        location /k8sops {
            alias html;
            index index.html;
        }

        location /ngx_status {
            auth_basic "User Authentication";                           #将认证配置加到location中
            auth_basic_user_file /usr/local/nginx/conf/htpasswd;
            stub_status on;
        }
}

测试访问
img

Ngxin 之 ngx_http_gzip_module 模块

ngx_http_gzip_module模块是一个过滤器,它使用“gzip”方法压缩响应数据。这通常有助于将传输数据的大小减少一半甚至更多。
**ngx_http_gzip_module压缩模块官方文档:**http://nginx.org/en/docs/http/ngx_http_gzip_module.html

gzip on | off;
是否启用gzip压缩输出

gzip_min_length 1k;
最小压缩文件大小为1k,小于1k的数据则不压缩,默认为20字节

gzip_buffers number size;
指定压缩时为其配置的缓冲区数量以及单个缓冲区大小。默认情况下,缓冲区大小等于一个内存页大小

gzip_http_version 1.1;
支队http1.1版本进行压缩,如果为客户端http版本为1.0,则不压缩,默认1.1
 
gzip_comp_level 6;
设置响应的gzip压缩级别,可接受的值在1到9之间,(1为最快压缩,压缩比最低)(9为最慢压缩,压缩比最高)默认为1

gzip_types text/plain application/x-javascript text/css application/xml application/javascript;
压缩过滤器,仅对此处设定的文件格式类型启用压缩功能

gzip_vary on;
开启对vary header支持

gzip_proxied any;
gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any …
nginx作为代理服务器接收到从被代理服务器发送的响应报文后,在何种条件下启用压缩功能的;
off:对代理的请求不启用
any:所有代理都压缩
no-cache, no-store,private:表示从被代理服务器收到的响应报文首部的Cache-Control的值为此三者中任何一个,则启用压缩功能

案例:

gzip on;
gzip_min_length 1k;
gzip_buffers 16 8K;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain application/x-javascript text/css application/xml application/javascript;
gzip_vary on;
gzip_proxied any;

Nginx 之 ngx_http_rewrite_module 重定向模块

**ngx_http_rewrite_module模块官方文档:**http://nginx.org/en/docs/http/ngx_http_rewrite_module.html
Nginx跳转重定向使用 ngx_http_rewrite_module 模块,该模块用于使用PCRE正则表达式更改请求URI,返回重定向以及有条件地选择配置。

rewrite指令

rewrite指令介绍
指令语法: rewrite regex replacement [flag];
使用位置 server, location, if

regex:
我们自定义URI的内容去匹配用户请求的URI
replacement:
自定义内容去替换掉regex

rewrite指令将用户请求的 URI 基于 regex 所描述的模式进行查找,查找到后将其替换为 replacement 指定的新的URI;
注意:如果在同一级别中(同一server中或者同一个级别的location中)存在多个rewrite,那么nginx将会把用户的URI从上而下进行检查;例如我们在server配置段中有5个rewrite,用户的URI在匹配到第3个rewrite时匹配成功,那么nginx默认将会进行一轮新的替换检查,直到个rewrite匹配完后才返回结果为客户端,因此,rewrite默认含有循环机制。

[flag]:
flag所表示的标志位用与控制上面循环的机制,以下四个参数为flag指令所支持的参数
last:
重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环(默认的flag);
break:
重写完成后停止对当前URI在当前location中后续的其它重写操作,直接跳转到rewrite配置之后的配置块进行其它配置(跳出循环)结束循环;
redirect:
重写完成后以临时重定向(302)方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;不能以http://或https://开头;
permanent:
重写完成后以永久重定向(301)方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;


http跳转https:
匹配以任何名称开头,然后将其永久重定向到 https://$server_name$server_name为nginx内置变量,$1为后项引用,引用前面 .* 中的所有内容,$request_uri:为nginx内置变量,表示用户请求的uri

server {
rewrite ^/.*$ https://$server_name/$1 permanent;
rewrite ^/(.*)$ https://$server_name/$request_uri permanent;
...
}

跟路径跳转
匹配跟路径以 k8sops 开头,然后将其重定向到跟路径 /source/ 下,匹配成功后跳出循环

location /k8sops/ {
    rewrite ^/k8sops/(.*)$ /source/$1 break;
    root /usr/local/nginx/html;
}

匹配路径以 k8sops 和 source 开头,然后将其重定向到其它 https://abcops.cn/web/nginx 下,

location ~* ^/(k8sops|source) {
    rewrite ^/(k8sops|source)/(.*)$ https://abcops.cn/web/nginx/$request_uri;
}
$request_uri也可以写为$2

跳转其它域名文件
将一个文件重定向至另外一个域名上的文件

location = /shop/source/class.js {
    rewrite ^/shop/source/class.js https://abcops.cn/shoping/application.js;
}

rewrite日志

Syntax: rewrite_log on | off;
Default:    
rewrite_log off;
Context:    http, server, location, if

默认rewrite日志是关闭掉的,如果想要开启rewrite日志,则在配置中添加 rewrite_log on; 配置

return指令

return指令介绍
指令语法:
1)return code [text];
2)return code URL;
3)return URL;
使用位置:server, location, if

if指令

if指令介绍
指令语法: if (condition) { … }
使用位置: server, location
if用来引入一个新的配置上下文;条件满足时,执行配置块中的配置指令

condition
condition为if判断的条件,nginx中if支持的判断条件如下:

比较操作符:
==:相等比较;
!=:不等比较;
~:模式匹配,区分字符大小写;
~:模式匹配,不区分字符大小写;
!~:模式不匹配,区分字符大小写;
!~
:模式不匹配,不区分字符大小写;
文件及目录存在性判断:
-e, !-e
-f, !-f
-d, !-d
-x, !-x

set自定义变量

指令语法: set $variable value;
使用位置: server, location, if

Nginx通过ngx_http_referer_module模块进行防盗链简单配置

为什么需要防盗链?

  1. 放置爬虫直接来抓取图片
  2. 防盗链需要根据referer来判断

日志格式

配置防盗链需要日志格式中包含 $http_referer$http_user_agent
** h t t p r e f e r e : ∗ ∗ 抓 取 客 户 端 上 一 个 网 址 , 例 如 : 客 户 端 是 通 过 w w w . b a i d u . c o m 来 的 h t t p s : / / k 8 s o p s . c n , 那 么 客 户 端 上 一 个 网 址 就 是 [ w w w . b a i d u . c o m 。 ] ( h t t p : / / w w w . b a i d u . c o m 。 ) ∗ ∗ http_refere:**抓取客户端上一个网址,例如:客户端是通过www.baidu.com来的 https://k8sops.cn,那么客户端上一个网址就是 [www.baidu.com。](http://www.baidu.com。) ** httpreferewww.baidu.comhttps://k8sops.cn[www.baidu.com](http://www.baidu.com)http_user_agent:**抓取客户端访问站点的途径,例如客户端是通过 chrome firefox 等浏览器访问或者使用 curl wget python 等工具访问。

我的日志格式如下:

 log_format  main  '$remote_addr" "$remote_user" "$time_iso8601" "$request"'
                   ' "$status" "$body_bytes_sent" "$connection" "$connection_requests" "$http_referer"'
                   ' "$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio" "$request_time"'
                   ' "$upstream_addr" "$upstream_response_time" "$upstream_status" "$http_host"';
 access_log  logs/access.log  main;

防盗链配置

       location ~ \.(png|jpg|jpeg|svg|ico|gif)$ {
           if ($http_referer !~ 'k8sops.cn') {
               return 403;
               break;
           }
           if ($http_user_agent ~ 'wget|curl|python') {
               return 403;
           }
       }

配置说明:
如果访问结尾为 .png .jpg .jpeg .svg .ico .gif 格式的文件将进行以下两次if判断
if ($http_referer !~ 'k8sops.cn') 判断日志中的 $http_referer 值是否不包含了 k8sops.cn,如果不包含 k8sops.cn 则证明此访问不是通过 k8sops.cn 网站来进行访问的,则返回 403 给拒绝掉,如果发现 $http_referer 值中包含了 k8sops.cn 则 break 跳出这个判断,开始进行下面一个判断。

if ($http_user_agent ~ 'wget|curl|python') 判断日志中 $http_user_agent 值是否是 wget curl python方式来访问的 k8sops.cn,如果是以此方式,则证明不是通过浏览器访问,那么将返回 403 给拒绝掉。

以上方式只能防御简单的爬虫,以下给出破解上方两种破解的方法:

1.伪装客户端上次地址:$http_referer
curl 127.0.0.1/k8sops.png --referer "k8sops.cn"
通过curl加 --referer 方式来破解第一个判断条件:
curl 127.0.0.1/k8sops.cn 访问本机地址,后面跟上 k8sops.cn 的图片路径,使用 --referer 指定域名 "k8sops.cn" 以达到伪装效果

2.伪装客户端使用的浏览器 $http_user_agent
curl https://k8sops.cn/k8sops.jpg --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
通过--user-agent来伪装一个浏览器以达到伪装目的

Nginx 之 ngx_http_autoindex_module 目录下载模块

Nginx使用 ngx_http_autoindex_module 模块来支持文件的下载,模块处理以 (‘/’) 结尾为请求,并生成目录列表。

参数介绍

#是否开启或禁用目录列表(是否开启目录索引)开启后会把目录下的所有文件列出
Syntax: autoindex on | off;
Default:    autoindex off;
Context:    http, server, location

#对于HTML格式,指定目录中的文件大小是否显示为字节
Syntax: autoindex_exact_size on | off;
Default:    autoindex_exact_size on;
Context:    http, server, location

#设置目录列表的格式
Syntax: autoindex_format html | xml | json | jsonp;
Default:    autoindex_format html;
Context:    http, server, location
This directive appeared in version 1.7.9.

#对于HTML目录列表格式,指定目录列表中的时间是否显示本地时区,如果为off则显示UTC时区
Syntax: autoindex_localtime on | off;
Default:    autoindex_localtime off;
Context:    http, server, location

配置案例

ngx_http_autoindex_module模块中的参数可以用作 http配置段、则全站启用下载模式;server配置段、当前server启用下载模式,当然最多使用的还是在location中,只对当前目录连接使用下载模式。

        location ^~ /download {
            root html;
            autoindex on;
            autoindex_exact_size off;
            autoindex_format html;
            autoindex_localtime on;
        }

img

Nginx 之 ngx_http_log_module 日志模块

**ngx_http_log_module日志模块官方文档:**http://nginx.org/en/docs/http/ngx_http_log_module.html

Nginx日志格式

1.log_format

Syntax: log_format name [escape=default|json|none] string ...;
Default: log_format combined "...";
Context:    http

日志格式可以为 escape|json|none|string等,适用于http配置段

2.日志变量
常用的日志变量如下

$remote_addr
$remote_addr表示记录客户端IP

$remote_user
用来记录客户端用户名称,有些页面需要Basic模块认证登录,此字段就是用来记录登录的用户名称

$time_iso8601
记录请求时间,这种方式比较直观,还有一种方式记录请求时间 $time_local

$request
记录客户端请求方法、请求的url、请求的协议

$status
记录响应状态码

$body_bytes_sent
记录响应的body的大小

$connection
连接序列号

$connection_requests
通过连接发出的当前请求数

$http_referer
表示来源url,从哪个地址跳到的当前页面,表示请求的referer连接,可用于防盗链

$http_user_agent
记录请求的客户端类型,比如浏览器名称、型号等

$http_x_forwarded_for
记录代理IP,如果nginx前面还有一层代理设备,那么此变量将记录nginx上层的代理服务器地址

$gzip_ratio
记录此次请求获得的压缩率

$request_time
记录本地服务器的响应时间

$upstream_addr
记录上游服务器的IP地址和端口

$upstream_response_time
记录上游服务器的响应时间

$upstream_status
记录上游服务器返回的状态码

$http_host
记录客户端访问的域名或者地址

关于Nginx更多内置变量见:http://nginx.org/en/docs/varindex.html

3.日志路径、格式、缓冲区相关配置

Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default: access_log logs/access.log combined;
Context: http, server, location, if in location, limit_except

access_log path:设置日志路径,可输出多个日志路径
format:指定格式,与 log_format 指定的格式一致
buffer=size:默认日志是直接写入磁盘,如果指定了了buffer大小,那么将启用缓冲区,日志将现写入缓冲区后在落到磁盘。
gzip[=level]:如果启用gzip参数,那么在日志写入文件之前,缓冲区的数据将被压缩后写入文件,压缩级别为1-9,(1为压缩时间较快,压缩比最低,9为压缩时间最慢,压缩比最高)。默认情况下,缓冲区大小等于64K字节,压缩级别设置为1。由于数据是在块中压缩的,所以日志文件可以在任何时候由“zcat”解压或读取。
[flush=time]:刷新时间

4.日志缓存区相关的元数据信息

Syntax:   open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
          open_log_file_cache off;
Default:    open_log_file_cache off;
Context:    http, server, location

open_log_file_cache off:关闭缓存日志文件相关的元数据信息
open_log_file_cache:开启缓存日志文件相关的元数据信息
max=N:缓存的最大文件描述符数量
[inactive=time]:非活动时长
[min_uses=N]:在inactive指定的时长内访问大于等于此值方可被当作活动项
[valid=time]:验正缓存中各缓存项是否为活动项的时间间隔;

总结:在非活动时长inactive参数指定的时间内,如果使用次数小于min_users值,nginx就会把它标注为非活动项进行删除,间隔valid参数指定的时间检查一次

Nginx日志模块 main 格式

log_format  main  '$remote_addr" "$remote_user" "$time_iso8601" "$request"'
                  ' "$status" "$body_bytes_sent" "$connection" "$connection_requests" "$http_referer"'
                  ' "$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio" "$request_time"'
                  ' "$upstream_addr" "$upstream_response_time" "$upstream_status" "$http_host"';
access_log  logs/access.log  main;

log_format main | json 
指定日志格式,可选为 main 和 json两种格式,日志格式可以包含公用变量,以及仅在写入日志时存在的变量,main格式为默认选项。

main 格式日志如下:

139.226.64.83" "-" "2020-03-20T18:00:19+08:00" "GET /crm/back-stage/img/icon/favicon.ico HTTP/1.1" "200" "16958" "658771" "13" "http://k8sops.cn/crm/console/login" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36" "-" "-" "0.005" "172.19.54.88:8081" "0.004" "200" "k8sops.cn"

Nginx日志模块 json 格式

log_format json '{"@timestamp":"$time_iso8601",'
                 '"remote_ip":"$remote_addr",' 
                 '"login_user":"$remote_user",'
                 '"request":"$request",'
                 '"status_code":"$status",' 
                 '"body_bytes":"$body_bytes_sent",' 
                 '"conn_number":"$connection",'
                 '"requests_number":"$connection_requests",'
                 '"referer_url":"$http_referer",'
                 '"agent":"$http_user_agent",' 
                 '"proxy_ip":"$http_x_forwarded_for",'
                 '"gzip_ratio":"$gzip_ratio",'
                 '"local_request_time":"$request_time",' 
                 '"upstream_addr":"$upstream_addr",'
                 '"upstream_response_time": "$upstream_response_time",'
                 '"upstream_status_code":"$upstream_status",'
                 '"http_host":"$http_host"}';
access_log  logs/access.log  json;

"@timestamp":"$time_iso8601"
时间json,@timestamp为键,$time_iso8601为值

日志格式变量意思与 main 一致

json格式日志如下:

{"@timestamp":"2020-03-20T17:57:23+08:00","remote_ip":"116.236.73.132","login_user":"-","request":"GET /crm/console/translog/detail?id=2120 HTTP/1.1","status_code":"200","body_bytes":"5182","conn_number":"658646","requests_number":"2","referer_url":"http://k8sops.cn/crm/console/translog/list","agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko","proxy_ip":"-","gzip_ratio":"-","local_request_time":"0.015","upstream_addr":"172.19.54.88:8081","upstream_response_time": "0.016","upstream_status_code":"200","http_host":"k8sops.cn"}

nginx之ngx_http_limit_req_module流量控制模块

Nginx流控采用ngx_http_limit_req_module模块,该模块用于限制每个IP的请求速率,该模块使用漏桶算法实现。
官方模块地址:ngx_http_limit_req_module

官方示例配置

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    ...
    server {
        ...
        location /search/ {
            limit_req zone=one burst=5;
        }

流控模块指令

语法;limit_req zone=name [burst=number] [nodelay | delay=number];
位置:http, , server,location

基本用法示例

http {
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
  server {
    location /search/ {
        limit_req zone=one;
    }
  }
}

指令解析;

  1. **limit_req_zone:**该指令为限制流量速率参数。
  2. **limit_req:**该指令为引用流量速率参数,来引用(limit_req_zone)参数。
  3. ** b i n a r y r e m o t e a d d r : ∗ ∗ 该 参 数 为 k e y , 表 示 通 过 ‘ binary_remote_addr:**该参数为key,表示通过` binaryremoteaddrkeybinary_remote_addr变量来限制, b i n a r y r e m o t e a d d r ‘ 相 比 于 ‘ binary_remote_addr`相比于` binaryremoteaddrremote_addr`变量少占用了10个byte内存空间。
  4. zone::该参数用于定义存储每个IP地址状态以及被限制请求URL访问频率的内存区域名称,保存在内存共享区域的信息,意味着可以在Nginx的worker进程之间共享。定义分为两个部分:通过zone=keyword标识区域的名字,以及冒号后面跟区域大小。16000个IP地址的状态信息,大约需要1MB,所以示例中区域可以存储160000个IP地址。
  5. **rate:**定义最大请求速率,在上面示例中,速率不能超过每秒5个request,Nginx实际上以毫秒粒度来跟踪请求,所以速率限制相当于每200毫秒1个请求,1000毫秒5个请求。rate选项的速率配置是针对于单个客户端IP地址每秒最多能够产生多少个请求,并不是Nginx自身一秒就只能够处理5个请求。
  6. **limit_req zone=one:**location中的这段用来引用limit_req_zone参数中指定的zone内存共享区域名称。引用后就对当前location进行limit_req_zone规则限制,如果limit_req参数在server中,那么当前这个虚拟主机下的location都将被引用限制。

当Nginx内存共享区域one存储空间不足时,将会删除旧的条目,如果释放的空间仍不够容纳新记录,Nginx将会返回 503状态码(Service Temporarily Unavailable)。另外,为了防止内存被耗尽,Nginx每次创建新条目时,最多删除两条60秒内未使用的条目。

处理突发

如果我们在1秒内收到了10个请求,那么Nginx将会把后面的5个请求全部返回503,因为我们上面配置的Nginx每秒最多就只能处理5个请求,可这并不是我们想要的结果,相反地,我们希望缓冲任何超额的请求,然后及时地处理它们。那么我们就需要在limit_req指令中使用burst参数。
如下:

location /search/ {
    limit_req zone=one burst=20;
}

burst参数定义了超出zone指定速率的情况下(示例中的one区域,速率限制在每秒5个请求,或每200毫秒一个请求),客户端还能发起多少请求。上一个请求200毫秒内到达的请求将会被放入队列,我们将队列大小设置为20。

这意味着,如果从一个给定IP地址发送21个请求,Nginx会立即将第一个请求发送到上游服务器群,然后将余下20个请求放在队列中。然后每200毫秒转发一个排队的请求,只有当传入请求使队列中排队的请求数超过20时,Nginx才会向客户端返回503。

无延迟排队

burst参数将会产生一个队列做为缓冲区,但加上该配置后站点看起来很慢。在上面示例中,队列中的第20个包需要等待4秒才能被转发,此时给客户端的响应可能不再有用。要解决这个情况,可以在burst参数后添加nodelay参数:

location /search/ {
    limit_req zone=one burst=20 nodelay;
}

使用nodelay参数,Nginx仍将根据burst参数分配队列中的位置,并应用已配置的速率限制,而不是清理队列中等待转发的请求。相反地,当一个请求到达“太早”时,只要在队列中能分配位置,Nginx将立即转发这个请求。将队列中的该位置标记为”taken”(占据),并且不会被释放以供另一个请求使用,直到一段时间后才会被释放。

假如队列中有20个空位,从给定的IP地址同时发出21个请求同时到达,Nginx将会立即处理这21个请求,并且标记队列中占据20个位置,然后假设200毫秒释放一个位置。如果是25个请求同时到达,Nginx将会立即处理第一个请求,然后将接下来的20个放入队列,并标记队列中占据20个位置,最后4个请求将被返回503状态码。无论再多请求同时到达,只要队列中的20个位置全部被标记为已占据,那么后来的请求将都被返回503。

流控实践

1.Nginx配置

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
  server {
    location / {
        limit_req zone=one burst=20 nodelay;
        root   html;
        index  index.html index.htm;
    }
  }
}

上面定义每秒处理5个请求,平均每200毫秒处理1个请求,队列中可存储20个请求

2.通过ab压测来检验结果
下面来进行压测,并发21个请求,并查看处理情况

ab -n 21 -c 21 'http://localhost:80/'
...
Concurrency Level:      21                              #并发级别为21个
Time taken for tests:   0.006 seconds                   #整个测试持续时间,单位为秒
Complete requests:      21                              #完成了21个请求
Failed requests:        0                               #失败的请求数为0
Write errors:           0                               #失败的写请求数为0
...

如上我们测试并发21个请求,Nginx将正常完成,其中会先处理第一个请求,其次将另外20个请求放入队列中,第一个请求处理后,将开始处理队列中的请求。

进行压测并发25个请求

ab -n 25 -c 25 'http://localhost:80/'
...
Concurrency Level:      25                              #并发级别为21个
Time taken for tests:   0.008 seconds                   #整个测试持续时间,单位为秒
Complete requests:      25                              #完成了25个请求
Failed requests:        4                               #失败的请求数为4
   (Connect: 0, Receive: 0, Length: 4, Exceptions: 0)
Write errors:           0
...

如上,测试25个并发请求,Nginx处理完成21个,剩下4个将返回503拒绝处理

3.查看日志
如下四个请求都被Nginx access日志返回503状态码和error日志记录超过zone内存共享区域大小被丢弃的请求

tail -f logs/access.log
127.0.0.1 - - [27/Jul/2020:13:59:13 +0800] "GET / HTTP/1.0" 503 541 "-" "ApacheBench/2.3"
127.0.0.1 - - [27/Jul/2020:13:59:13 +0800] "GET / HTTP/1.0" 503 541 "-" "ApacheBench/2.3"
127.0.0.1 - - [27/Jul/2020:13:59:13 +0800] "GET / HTTP/1.0" 503 541 "-" "ApacheBench/2.3"
127.0.0.1 - - [27/Jul/2020:13:59:13 +0800] "GET / HTTP/1.0" 503 541 "-" "ApacheBench/2.3"
tail -f logs/error.log
2020/07/27 13:59:13 [error] 32327#32327: *20275 limiting requests, excess: 20.985 by zone "one", client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.0", host: "localhost"
2020/07/27 13:59:13 [error] 32327#32327: *20276 limiting requests, excess: 20.985 by zone "one", client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.0", host: "localhost"
2020/07/27 13:59:13 [error] 32327#32327: *20277 limiting requests, excess: 20.985 by zone "one", client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.0", host: "localhost"
2020/07/27 13:59:13 [error] 32327#32327: *20278 limiting requests, excess: 20.985 by zone "one", client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.0", host: "localhost"

error日志段解析:

  1. limiting requests:表明日志条目记录的是被“流量限制”请求
  2. excess – 每毫秒超过对应“流量限制”配置的请求数量
  3. zone – 定义实施“流量限制”的区域
  4. client – 发起请求的客户端IP地址
  5. server – 服务器IP地址或主机名
  6. request – 客户端发起的实际HTTP请求
  7. host – HTTP报头中host的值

默认情况下,Nginx以error级别来记录被拒绝的请求,如上面示例中的[error]所示(Ngin以较低级别记录延时请求,一般是info级别)。如要更改Nginx的日志记录级别,需要使用limit_req_log_level指令。这里,我们将被拒绝请求的日志记录级别设置为warn:

默认情况下,Nginx将返回503来告知被拒绝的请求,如上access日志所示,如果需要修改503为其它状态码可通过limit_req_status指令。

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
  server {
    location / {
        limit_req zone=one burst=20 nodelay;
        limit_req_log_level warn;
        limit_req_status 403;
        root   html;
        index  index.html index.htm;
    }
  }
}

再次压测并查看日志级别及状态码

ab -n 25 -c 25 'http://localhost:80/'
tail -f logs/access.log
127.0.0.1 - - [27/Jul/2020:14:17:27 +0800] "GET / HTTP/1.0" 403 159 "-" "ApacheBench/2.3"
127.0.0.1 - - [27/Jul/2020:14:17:27 +0800] "GET / HTTP/1.0" 403 159 "-" "ApacheBench/2.3"
127.0.0.1 - - [27/Jul/2020:14:17:27 +0800] "GET / HTTP/1.0" 403 159 "-" "ApacheBench/2.3"
127.0.0.1 - - [27/Jul/2020:14:17:27 +0800] "GET / HTTP/1.0" 403 159 "-" "ApacheBench/2.3"

Nginx 之 ngx_http_upstream_module 模块(负载均衡)

Nginx通过ngx_http_upstream_module模块用于定义可以由proxy_pass、fastcgi_pass、uwsgi_pass、scgi_pass和memcached_pass指令引用的服务器组。

官方实例

官方实例通过 upstream 来定义一个服务器组,组名称叫做 backend ,组内包含了五台节点,然后通过 proxy_pass 模块将客户端请求转发给 upstream 定义的服务器组(通过组名称转发)。

    upstream backend {
        server backend1.example.com       weight=5;
        server backend2.example.com:8080;
        server unix:/tmp/backend3;
        server backup1.example.com:8080   backup;
        server backup2.example.com:8080   backup;
    }
    server {
        location / {
            proxy_pass http://backend;
        }
    }

upstream指令语法格式

upstream

Syntax:   upstream name { ... }
Context:    http

定义一组服务器,服务器可以监听不同的端口。此外,监听TCP和unix域套接字的服务器可以混合使用。
例如:

    upstream backend {
        server backend1.example.com weight=5;
        server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;
        server unix:/tmp/backend3;
        server backup1.example.com  backup;
    }

默认情况下,backend定义的后端服务器以加权轮询的方式分布,被称为wrr,相当于weight=1。

server指令语法格式

1.server
server用来定义服务器的地址和其他参数,地址可以指定为带可选端口的域名或IP地址,也可以指定为“unix:”前缀后的unix域套接字路径。如果没有指定端口,则使用端口80。解析为多个IP地址的域名同时定义多个服务器。

    Syntax: server address [parameters];
    Default:    —
    Context:    upstream

2.weight
weight为权重,默认情况下weight为1,weight越大,nginx将请求调度到此后端服务器则越多,适用于后端服务器性能不一致的情况。

weight=number

3.max_conns
当前的服务器的最大并发连接数,限制到代理服务器的最大同时活动连接数。默认值为0,表示没有限制。

max_conns=number

4.max_fails
如果访问后端服务器失败,max_fails参数可以指定访问失败的最大次数;如果超出了指定次数,则将此后端服务器标记为不可用

max_fails=number

5.fail_timeout
每次访问后端服务器的超时时间,如果连续 max_fails 定义次数,每次超时时间 fail_timeout 则将服务器标记为不可用

fail_timeout=time

6.backup
将服务器标记为“备用”,即所有服务器均不可用时此服务器才启用。
该参数不能与 ip_hash、hash key、random算法一起使用。

backup  

7.down
将后端服务器标记为不可用,当后端服务器出问题时,可以使用此参数来标记节点为不可用

down

server指令实例
以下为server指令中常用的配置参数

    upstream backend {
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=5 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080 backup;
            server 192.168.31.244:8080 down;
    }

负载算法

1.least_conn
least_conn为最少连接算法,在这种方法中,考虑到服务器的权重,将请求传递给活动连接数量最少的服务器。如果有多个这样的服务器,则依次使用加权循环平衡。

    upstream backend {
            least_conn;
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=6 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080 backup;
            server 192.168.31.244:8080 down;
    }

2.least_time
least_time将请求传递给平均响应时间和活动连接数量较少的服务器,同时考虑到服务器的权重。如果有多个这样的服务器,则依次使用加权循环平衡。
如果指定了报头参数,则使用接收响应报头的时间。如果指定了last_byte参数,则使用接收完整响应的时间。
这种算法只在 NGINX PLUS 中才有的模式(付费版NGINX)

    Syntax: least_time header | last_byte [inflight];
    Default:    —
    Context:    upstream
    upstream backend {
            least_time header;
            #least_time last_byte;
            #least_time header inflight;
            #least_time last_byte inflight;
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=6 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080 backup;
            server 192.168.31.244:8080 down;
    }

3.ip_hash
在 IP Hash 模式下,NGINX 会根据发送请求的 IP 地址的 hash 值来决定将这个请求转发给哪个后端服务实例。被 hash 的 IP 地址要么是 IPv4 地址的前三个 16 进制数或者是整个 IPv6 地址。使用这个模式的负载均衡模式可以保证来自同一个 IP 的请求被转发到同一个服务实例上,可以解决session的问题,但是ip_hash会造成负载不均,假如两个不同地址连接到了两个不同服务器,如果有一个地址发出的请求很多,而另一个地址发出的请求很少,则会造成负载不均。除非该服务器不可用,如果不可用,客户机请求将被传递到另一个服务器。

    upstream backend {
            ip_hash;
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=6 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080;
            server 192.168.31.244:8080 down;
    }

4.hash key [consistent]
自定义hash的两种用法

  1. hash key 是nginx自带的负载均衡,key可以是文本、变量及其组合,hash后面跟什么就绑定什么来做hash保持。
  2. hash key consistent后面多了一个consistent 这个关键词会使用一种新的 hash 算法,被称为为一致性 hash 算法,一致性hash算法使用ketama,该方法确保在向组中添加或从组中删除服务器时,只有少数几个密钥将被重新映射到不同的服务器,这有助于为缓存服务器实现更高的缓存命中率。关于更多一致性hash算法请参考 https://blog.youkuaiyun.com/publicv/article/details/104732046
#hash key 通过 NGINX 内置变量 $remote_addr 进行会话保持,如果用$remote_addr的话就与ip_hash算法功能一致了
    upstream backend {
            hash $remote_addr;
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=6 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080;
            server 192.168.31.244:8080 down;
    }
#hash key 通过 NGINX 内置变量 $request_uri 进行会话保持,根据每次请求的URI地址,hash后访问到固定服务器节点,如果URI发生改变就可能负载到别的后端服务器,这种模式后端服务器为缓存时比较好
    upstream backend {
            hash $request_uri;
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=6 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080;
            server 192.168.31.244:8080 down;
    }
#hash key consistent 这种hash一致性算法使用了ketama,算法上比以上复杂一些,也是根据每次请求的URI地址进行hash
    upstream backend {
            hash $request_uri consistent;
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=6 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080;
            server 192.168.31.244:8080 down;
    }

其它参数

1.keepalive
keepalive参数设置到保存在每个工作进程缓存中的上游服务器的最大空闲保持连接数,当超过此数目时,最近最少使用的连接将被关闭。
keepalive指令并没有限制nginx工作进程可以打开的到上游服务器的连接总数。连接参数应该设置为足够小的数字,以便上游服务器也可以处理新的传入连接。

    upstream backend {
            hash $request_uri consistent;
            keepalive 30;
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=6 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080;
            server 192.168.31.244:8080 down;
    }

2.keepalive_requests
设置为每个keepalive连接提供最大的请求数,超过最大请求数量之后,连接关闭。
为了释放每个连接的内存分配,需要周期性地关闭连接,因此,使用过高的最大请求数可能会导致过多的内存使用,不建议这样做。

    upstream backend {
            hash $request_uri consistent;
            keepalive 30;
            keepalive_requests 300;
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=6 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080;
            server 192.168.31.244:8080 down;
    }

3.keepalive_timeout
设置一个超时,在此期间,到上游服务器的空闲keepalive连接将保持打开状态,如果超出了该时间,则断开与后端服务器的空闲连接。

    upstream backend {
            hash $request_uri consistent;
            keepalive 30;
            keepalive_requests 300;
            keepalive_timeout 60s;
            server 192.168.31.240:8080 weight=3 max_conns=300 max_fails=3 fail_timeout=10s;
            server 192.168.31.241:8080 weight=3 max_conns=500 max_fails=3 fail_timeout=10s;
            server 192.168.31.242:8080 weight=6 max_conns=800 max_fails=3 fail_timeout=10s;
            server 192.168.31.243:8080;
            server 192.168.31.244:8080 down;
    }

Nginx 之 ngx_http_proxy_module 代理模块

Nginx的ngx_http_proxy_module模块允许将请求传递到另一个服务器,俗称为代理模块。

实例配置

    location / {
        proxy_pass       http://localhost:8000;
        proxy_set_header Host      $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

proxy_pass指令

指令语法

    Syntax: proxy_pass URL;
    Context:    location, if in location, limit_except

proxy_pass 设置代理服务器的协议和地址以及位置应映射到的可选URI,可以指定http或者https协议,该地址可以指定为域名或者IP地址和附加端口。

例如:

            location  / {
                 proxy_pass http://192.168.31.242;
            }
            
            location / {
                proxy_pass https://k8sops.cn;
            }

注意

  1. proxy_pass 地址后面不加路径时,其会将用户请求的uri传递给后端主机。
  2. proxy_pass 地址后面的路径是一个uri时,其会将location的uri转换为proxy_pass的uri。
  3. 如果location定义其uri时使用了正则表达式的模式,或在if语句或limt_execept中使用proxy_pass指令,则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加代理到的服务的之后。

实例一
客户端请求的URI是什么就会到proxy_pass指定地址后补充什么

    server {
            listen 80;
            server_name devops.cn;
            access_log /usr/local/nginx/logs/access.log main;
            location / {
                proxy_pass https://k8sops.cn;
            }
    }

访问地址http://devops.cn/category/devops/gitlab/,nginx会把用户请求的URI /category/devops/gitlab/补充到 proxy_pass 指定域名的后面

img

实例二

    server {
            listen 80;
            server_name devops.cn;
            access_log /usr/local/nginx/logs/access.log main;
    #/category/web表示客户端访问地址中包含此路径则转发至k8sops.cn,然后将客户端访问的URI补充到k8sops.cn后
            location /category/web {
                proxy_pass https://k8sops.cn;
            }
    #/category/ops表示客户单访问地址中包含此路径则转发至k8sops.cn,然后将客户端访问的URI转换为/category/devops
            location /category/ops {
                proxy_pass https://k8sops.cn/category/devops;
            }
    }

访问http://devops.cn/category/web/则会跳转到https://k8sops.cn/category/web/

img

访问http://devops.cn/category/ops/实际则会跳转到http://devops.cn/category/devops/

img

实例三
如果location定义其uri时使用了正则表达式的模式,或在if语句或limt_execept中使用proxy_pass指令;
则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加代理到的服务的之后。

#错误示范
#当location使用了正则表达式之后,proxy_pass 地址后面不允许加URI,否则Nginx自检失败
            location ~* ^/labs {
                proxy_pass https://k8sops.cn/bubble;    
            }
#正确示范
#location使用了正则表达式之后,proxy_pass 地址后面不允许加URI,用户请求的URI则补充到地址后,则为 https://k8sops.cn/labs
            location ~* ^/labs {
                proxy_pass https://k8sops.cn;           
            }

Nginx 之 ngx_http_fastcgi_module 代理模块

Nginx通过ngx_http_fastcgi_module模块允许将请求传递给FastCGI服务器,一般我们常见通过FastCGI协议通信的应用就是PHP。

官方实例

    location / {
        fastcgi_pass  localhost:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
        fastcgi_param QUERY_STRING    $query_string;
        fastcgi_param REQUEST_METHOD  $request_method;
        fastcgi_param CONTENT_TYPE    $content_type;
        fastcgi_param CONTENT_LENGTH  $content_length;
    }

FastCGI语法介绍

设置一个FastCGI服务器的地址,地址可以指定为一个域名或IP地址,以及一个端口
1.fastcgi_pass

    Syntax: fastcgi_pass address;
    Default:    —
    Context:    location, if in location

例如:

#指定域名或者IP地址及域名
fastcgi_pass localhost:9000;
#或指定一个unix域套接字路径
fastcgi_pass unix:/tmp/fastcgi.socket;
#如果你有多台PHP服务器,需要通过FastCGI协议来进行通信,你可以使用upstream模块来包含多台PHP服务器,然后使用FastCGI协议进行转发

2.fastcgi_index
fastcgi_index与平常location中的index一致,指定主页文件名,当通过fastcgi协议访问到后端服务器时,首先会解析我们指定的文件名称。

    Syntax: fastcgi_index name;
    Default:    —
    Context:    http, server, location

3.fastcgi_param
设置应该传递给FastCGI服务器的参数,该值可以包含文本,变量及其组合,当且仅当在当前级别上没有定义fastcgi_param指令时,这些指令从上一级继承。使用fastcgi_param来定义传递给后端服务器什么参数,我个人理解为与Nginx中的proxy_set_header模块作用一样,只是fastcgi_param是通过fastcgi协议进行传输。

    Syntax: fastcgi_param parameter value [if_not_empty];
    Default:    —
    Context:    http, server, location

fastcgi_param的语法与proxy_set_header指令还不太一样,proxy_set_header指令可以自定文本然后指定Nginx内置变量再将文本得到的值传递给后端服务器,而fastcgi_param则是有固定的文本和指定的Nginx内置变量,这些可用文本和变量放在nginx家目录下的conf/fastcgi_param文件中。
例如,以下是将Nginx内置变量$query_string传递给QUERY_STRING来完成将连接状态信息向后端进行传递

fastcgi_param QUERY_STRING $query_string;

[root@jdyun_blogs nginx]# cat conf/fastcgi_params
#QUERY_STRING参数用于传递请求参数到后端服务器
fastcgi_param  QUERY_STRING       $query_string;
#以下三个参数用于POST请求脚本所支持的配置
fastcgi_param  REQUEST_METHOD     $request_method;      #传递请求方法
fastcgi_param  CONTENT_TYPE       $content_type;        #连接类型
fastcgi_param  CONTENT_LENGTH     $content_length;      #连接长度
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name; #传递给后端服务器的脚本名称
fastcgi_param  REQUEST_URI        $request_uri;         #请求的URI
fastcgi_param  DOCUMENT_URI       $document_uri;        #网站目录的URI
fastcgi_param  DOCUMENT_ROOT      $document_root;       #网站目录
fastcgi_param  SERVER_PROTOCOL    $server_protocol;     #从Nginx服务器通过fastcgi传递到后端服务器的协议
fastcgi_param  REQUEST_SCHEME     $scheme;              #调度
fastcgi_param  HTTPS              $https if_not_empty;  #如果指令是用if_not_empty (1.1.11)指定的,那么只有当它的值不为空时,才会把这个参数传递给服务器:
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version; #Nginx版本
fastcgi_param  REMOTE_ADDR        $remote_addr;         #远程客户端地址
fastcgi_param  REMOTE_PORT        $remote_port;         #远程客户端端口
fastcgi_param  SERVER_ADDR        $server_addr;         #服务器地址
fastcgi_param  SERVER_PORT        $server_port;         #服务器端口
fastcgi_param  SERVER_NAME        $server_name;         #服务器名称
#PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;                  #如果PHP是用--enable-force-cgi-redirect配置参数构建的,那么REDIRECT_STATUS参数的值也应该是“200”:

我们在默认使用中,会将以上参数全部开启的,例如

include         fastcgi_params;

但是除了以上配置,我们还需要指定一个SCRIPT_FILENAME参数,这个是fastcgi_param文件中没有的

fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;

SCRIPT_FILENAME参数用于确定脚本名
/usr/local/nginx/html用于指定网站目录,(PHP代码项目所在的目录)
$fastcgi_script_name变量值包含了网站目录下的所有文件,只是用于变量获取。

比如我们访问了 https://k8sops.cn/admin/login.php 那么我们网站的根目录就是我们上面指定的 /usr/local/nginx/html,而 $fastcgi_script_name 获取的就是 admin/login.php,这样就组成了一段完整的URI,将这段完整的URI赋值给 SCRIPT_FILENAME

4.fastcgi_keep_conn
默认情况下,FastCGI服务器将在发送响应后立即关闭连接。但是,当这个指令被设置为值on时,nginx将指示FastCGI服务器保持连接打开。

fastcgi_keep_conn on | off;

案例配置

我们平常使用中使用以下配置足以满足需求

    location / {
        root /usr/local/nginx/html;
        fastcgi_index   index.php;
        fastcgi_pass    127.0.0.1:9000;
        include         fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
    }

以上的 /usr/local/nginx/html也可以使用$document_root变量去自动获取,改写为如下

    location / {
        root /usr/local/nginx/html;
        fastcgi_index   index.php;
        fastcgi_pass    127.0.0.1:9000;
        include         fastcgi_params;
        fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    }

如果你想做到动静分离,那么就让.php文件让php处理,其它的像静态的图片以及静态的页面交给Nginx处理则配置如下

    location ~* \.php$ {        #以 .php 结尾的文件通过fastcgi协议转发给后端服务器处理
        root /usr/local/nginx/html;
        fastcgi_index   index.php;
        fastcgi_pass    127.0.0.1:9000;
        include         fastcgi_params;
        fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    }
    
    location / {                #如果以上没有匹配到 .php 结尾的文件,则在此由Nginx处理
        root /usr/local/nginx/html;
        index  index.html index.htm;
    }

stcgi_param REQUEST_SCHEME $scheme; #调度
fastcgi_param HTTPS KaTeX parse error: Expected 'EOF', got '#' at position 22: …if_not_empty; #̲如果指令是用if_not_em…nginx_version; #Nginx版本
fastcgi_param REMOTE_ADDR $remote_addr; #远程客户端地址
fastcgi_param REMOTE_PORT $remote_port; #远程客户端端口
fastcgi_param SERVER_ADDR $server_addr; #服务器地址
fastcgi_param SERVER_PORT $server_port; #服务器端口
fastcgi_param SERVER_NAME $server_name; #服务器名称
#PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200; #如果PHP是用–enable-force-cgi-redirect配置参数构建的,那么REDIRECT_STATUS参数的值也应该是“200”:


我们在默认使用中,会将以上参数全部开启的,例如

```bash
include         fastcgi_params;

但是除了以上配置,我们还需要指定一个SCRIPT_FILENAME参数,这个是fastcgi_param文件中没有的

fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;

SCRIPT_FILENAME参数用于确定脚本名
/usr/local/nginx/html用于指定网站目录,(PHP代码项目所在的目录)
$fastcgi_script_name变量值包含了网站目录下的所有文件,只是用于变量获取。

比如我们访问了 https://k8sops.cn/admin/login.php 那么我们网站的根目录就是我们上面指定的 /usr/local/nginx/html,而 $fastcgi_script_name 获取的就是 admin/login.php,这样就组成了一段完整的URI,将这段完整的URI赋值给 SCRIPT_FILENAME

4.fastcgi_keep_conn
默认情况下,FastCGI服务器将在发送响应后立即关闭连接。但是,当这个指令被设置为值on时,nginx将指示FastCGI服务器保持连接打开。

fastcgi_keep_conn on | off;

案例配置

我们平常使用中使用以下配置足以满足需求

    location / {
        root /usr/local/nginx/html;
        fastcgi_index   index.php;
        fastcgi_pass    127.0.0.1:9000;
        include         fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
    }

以上的 /usr/local/nginx/html也可以使用$document_root变量去自动获取,改写为如下

    location / {
        root /usr/local/nginx/html;
        fastcgi_index   index.php;
        fastcgi_pass    127.0.0.1:9000;
        include         fastcgi_params;
        fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    }

如果你想做到动静分离,那么就让.php文件让php处理,其它的像静态的图片以及静态的页面交给Nginx处理则配置如下

    location ~* \.php$ {        #以 .php 结尾的文件通过fastcgi协议转发给后端服务器处理
        root /usr/local/nginx/html;
        fastcgi_index   index.php;
        fastcgi_pass    127.0.0.1:9000;
        include         fastcgi_params;
        fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    }
    
    location / {                #如果以上没有匹配到 .php 结尾的文件,则在此由Nginx处理
        root /usr/local/nginx/html;
        index  index.html index.htm;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值