nginx学习笔记
目录
7.1 worker_processes number | auto 15
7.4 worker_rlimit_nofile number 16
9.1 worker_connections number 17
12.5 error_page code ... [=[response]] uri 22
13.1 keepalive_timeout timeout [header_timeout] 24
13.2 keepalive_requests number 24
13.3 keepalive_disable none | browser 25
13.5 client_body_buffer_size size 25
14.2 limit_except method ... { ... } 26
15.1 aio on | off | threads[=pool] 26
15.4 open_file_cache_valid time 27
15.5 open_file_cache_min_uses number 27
15.6 open_file_cache_errors on | off 27
十七 ngx_http_auth_basic_module 28
十八 ngx_http_stub_status_module 29
19.1 log_format name string 30
20.1 rewrite regex replacement 31
20.4 if (condition) { ... } 34
21.5 gzip_buffers number size 36
二十二 ngx_http_fastcgi_module 37
22.3 fastcgi_param parameter value 38
22.6 fastcgi_cache zone | off 41
22.7 fastcgi_cache_key string 41
22.8 fastcgi_cache_methods GET | HEAD | POST 41
22.9 fastcgi_cache_min_uses number 41
22.10 fastcgi_cache_valid [code ...] time 41
22.12 fastcgi_keep_conn on | off 43
二十四 ngx_http_referer_module(防盗链) 46
25.10 proxy_hide_header field 51
25.11 proxy_connect_timeout 51
26.2 expires [modifined] time 53
二十七 ngx_http_upstream_module 53
一 简介
Nginx ("engine x") 是一个高性能的HTTP和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler(俄文:Рамблер)使用。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、新浪、网易、腾讯等。
Nginx的官方站点Nginx.org
定义:
NGINX is a free, open-source, high-performance HTTP server and reverse proxy, as well as an
IMAP/POP3 proxy server. C10K(10K Connections).
Nginx在较大负载下对内存的消耗很小。Nginx的出现主要是为了解决c10K问题的;
C10K:一万个并发连接;
而httpd基于prefork的最大并发连接数是256个;基于httpd的内部所实现的IO处理机制叫select,而select本身所支持的最大并发能力是1024个;
1.1 Nginx的负载均衡
能够在反代时把对同一个服务的请求发往多台后端主机上,并且在发往多个后端主机时还能够完成类似于基于用户指定的业务模型适用的调度方法进行。
Nginx不光可以反代http,还可以反代mysql,和其他tcp协议的服务;
1.2 http协议
URL:shceme://username:password@host:port/path;params?query#frag
params 参数
query 查询
frag 片段
http事务主要由请求和响应报文组成:
request:请求
<method> <URL> <VERSION>
请求方法 版本号
HEADERS
<body>
reponse:响应
<VERSION> <STATUS> <REASON-PHRASE>
版本 状态 原因短语
HEADERS
头部
<body>
Method: GET/HEAD/POST, PUT/DELETE, TRACES, OPTIONS
请求方法
GET/HEAD 是最为安全的方法,也是可缓存的方法;
POST:用于提交表单;
Status Code:
1xx:
2xx:成功类响应码,200表示正常响应;
3xx:重定向类的响应码,301, 302, 304
301:请求的资源的URL指向的资源已经被删除,但是响应报文中通过首部location
指明了资源现在所处的位置;
302:指明请求的资源现在所处的临时的新位置;
304:客户端发出了条件式请求,但是服务器上的资源未发生改变;
4xx:客户端错误,403,404
401:需要输入账号和密码认证通过方能访问目标;
403:请求被禁止;
404:服务器无法找到客户端所请求的资源;
499:服务器端处理时间过长;
5xx:服务器端错误,502
500:服务器内部错误;
502:代理服务器从后端服务器收到了一条伪响应
1.3 httpd MPM
prefork:进程模型,两级结构,主进程master负责生成子进程,每个子进程负责响应一个请求;加载、分析并配置应用;
worker:线程模型,三级结构,主进程master负责生成子进程,每个子进程负责生成多个线程,每个线程响应一个请求;
event:主进程master负责生成子进程,每个子进程直接响应多个请求;
二 I/O模型
类型:
阻塞型、非阻塞型、复用型、信号驱动型、异步
每一次的I/O大体都需要两步:
第一步:内核将磁盘中的数据加载至内核内存
第二步:将数据从内核内存复制到进程内存;
两台服务器之间的通信多数情况下是进程间的通信;所以web服务器也就是客户端的浏览器进程与
服务端的进程之间所进行的通信;
对于单台主机来讲,整个过程分成了两个阶段,因为客户端所请求的资源在服务器端被加载之前应
该位于磁盘之上的;任何磁盘上的资源要想能够被进程访问,只能够向内核发起系统调用来实现,因为
只有内核才有权限访问硬件;意味着任何一个进程在收到用户请求之后,要想能够加载并响应该请求,
先分析用户所请求的URL在本地是否存在,第一步,该进程要向内核发起系统调用请求,内核接收调用
请求之后要帮忙将该数据拿给进程;但是对于内核而言它也是程序,它所能够访问的数据也必须在内存
中,所有数据只有在内存中才能被使用;
进程内存空间和对应的内核内存空间是分割开来的,内核所使用的的内存是处于保护模式的,绝不
允许进程任意访问,该内存就被称为内核空间;
每一个进程都有自己的线性地址空间。也就意味着进程和进程之间互相是隔离的;何为线性地址空
间,就是内核给进程所实际需要的内存空间,但是假装告诉线程,他自己有很大的内存空间;
内核收到请求后就需要从自己的内存空间中把数据复制到进程的地址空间,这样进程才能访问;但
问题是内核空间中可能并没有该数据,所以只能通过硬盘的驱动程序去把对应的数据项首先加载至内核
内存,然后该数据从内核内存再复制到用户空间的进程内存中,进程再将数据打包成响应报文发送给客
户端;
因此这整个步骤才组成了一次完整的I/O;
同步/异步:
关注消息通知机制;
消息通知:
同步:调用完以后需要等待对方返回消息;
异步:被调用者通过状态、通知或回调机制通知调用者被调用者的运行状态;
阻塞/非阻塞:
关注调用者在等待结果返回之前所处的状态;
阻塞:blocking,调用结果返回之前,调用者被挂起;
非阻塞:nonblocking,调用结果返回之前,调用者不会被挂起;
I/O的工作模型:
由调用者发起请求。被调用者要及时返回结果给调用者,这个返回结果的时长分为两阶段,第一
阶段是等待数据的过程,第二阶段是等待数据复制的过程;其实第二阶段将数据从内核内存复制到进
程内存中的过程才是真正I/O发生的过程;
一般来说,当调用者发出请求后,内核就收到请求了,但是内核自己得准备对应的数据。
所谓同步,就是当真正的调用请求发出来后,无论是第一阶段还是在第二阶段,该调用者都是被挂
起的,而且一定是处于睡眠状态的,
一次IO请求,都会由两阶段组成:
第一步:等待数据,即数据从磁盘到内核内存;
第二步:复制数据,即数据内核内存到进程内存;
所谓阻塞型I/O,是指,整个过程是同步的,自调用请求发出开始,他要等待数据从磁盘到内核内
存,还要等待数据从内核内存到进程内存,在此之前,什么事都干不了,所以叫阻塞型I/O;
所谓非阻塞型I/O,仅是指第一阶段是非阻塞的,当发出调用请求之后,第一阶段调用者是没有被
阻塞的,只有第二阶段,数据真正从内核内存到进程内存时,进程才会被阻塞;
在第一阶段,进程在干什么呢?此时进程是在盲等待;
复用型IO调用:
让一个进程可以在进程阻塞之后让进程监控多路I/O,而不止监控一个,所以对一个主进程来讲,
本来是一个进程发起I/O调用请求之后,只能盯着一个I/O,后来为了避免进程只能阻塞在单个I/O,
开发了一个内核级的系统调用,每一个进程发I/O调用请求时,不再直接向内核中的I/O进行请求,而
这种内核中新开发出来的能同时让一个进程阻塞以后帮助其输出多路I/O的请求机制就叫做I/O复用机
制;
这个复用型I/O使得让进程阻塞之后,不让进程阻塞在I/O上,而是阻塞在内核中的复用型I/O上。
复用型I/O的调用有两种:
select():最多允许一次调用1024个事件;
poll():无上限;
event-driven:
epoll(Linux):libevent
Kqueue(BSD):
Solaris:/dev/poll
三 Nginx的程序架构
Load configuration launch works non-stop upgrade: 装载配置,启动work进程,非阻塞升级,也就是将Nginx从较低版本升级到较高版本时,不用将Nginx停止就可以做到,在此过程中用户是感知不到的。
而各work进程的工作模式首先是客户端基于http/https提供服务,能够将用户的请求基于http反代至后端的web server,也可以基于fastcgi反代至application server,也可以基于Memcache反代至memcached;
面向客户端,统一使用一个接口输出即http。而对于后端,则有可能有n中输出方式。
除此之外,nginx在反代时还有缓存功能proxy cache,nginx还有两个进程,cache loader和Cache manager,一个用来装载内存,另一个用来管理缓存中的缓存对象的;
Nginx可以同时处理多个用户请求,每个进程同时处理多个用户请求时基于kevent(忙等待)/epoll/select机制;
master/worker
一个master进程:
负载加载配置文件、管理worker进程、平滑升级
一个或多个worker进程
处理并响应用户请求
缓存相关的进程:
cache loader:载入缓存对象
cache manager:管理缓存对象
3.1 Nginx的特性
异步、事件驱动和非阻塞
并发请求处理:通过kevent/epoll/select这三种机制,建议使用epoll模型;
文件IO:支持高级IO sendfile,异步,mmap(内存映射)
Sendfile:当用户请求到达内核时,由内核基于监听的套接字文件将其送到用户空间的Nginx 或http进程上,nginx发现分析用户请求的资源以后,接下来就需要将资源通过I/O请求将数据从磁盘上读到内核内存,再复制到进程内存,然后进程构建响应报文,发送报文时要通过网卡转发,而只有内核才有权限去调用网卡,因此还要需要通过内核向网卡发送系统调用,将报文送回内核,内核将报文扔到网卡的发送队列上;
Sendfile就是支持数据加载完成之后,在内核级直接封装响应报文,响应给客户端;
内存映射:数据首先到达内核内存,再由内核内存复制到进程内存;第一步是数据的装载,第二步是数据的复制,而数据的复制过程尽管是内存到内存,时间很短,但是该过必然在消耗时间,如果将数据直接由内核内存把磁盘空间的数据映射到内存中来,并把内存直接拿给进程来使用,直接把磁盘映射成进程内存,由进程直接拿来用,这就叫内存映射机制。
nginx高度模块块:高度模块化,但其模块早期不支持DSO(动态装卸载)机制;近期版本支持动态装载和卸载;
模块分类:
核心模块:core module
标准模块:nginx自带模块
Standard HTTP modules:标准的http协议相关的模块;
Optional HTTP modules:可选模块;
Mail modules
Stream modules:新近版本才拥有的功能;可以基于TCP协议负载用户的各类请求;
3rd party modules:第三方模块;
https://www.nginx.com/resources/wiki/modules/ nginx第三方模块地址;
nginx的模块比较独特,是一种流水线工作模型,当一个用户请求到达时先被核心模块所装载,随后任何一个功能是否被用到,有可能是取决于配置文件中的定义的,在配置文件当中定义了某一个用户请求到底是基于何种响应方式响应时,不同的配置所依赖的模块不同;一旦定义好后,nginx是逐个调用模块;第一级处理完交给第二级,依次类推来完成请求处理;
3.2 nginx的功用
1、静态的web资源服务器;nginx已经被证明足够稳定,通常被拿来当做图片服务器
使用;也可以作为缓存服务器使用;
2、结合FastCGI/uwSGI/SCGI等协议反代动态资源请求;
可以在前端放一台nginx主机,它能够基于http协议接收用户请求,但是最终确能够把用户请求或fastCGI的请求转交给后端的某一个application server;由application server加载资源和处理完请求后,静态数据流再由nginx返回给客户端;任何的动态资源必须得有后端服务器处理,处理包含程序的处理过程,没准还需要加载数据库中的数据,那这个过程会使得性能进一步被降低,而nginx可以将动态资源的执行结果的数据流直接在nginx主机上给缓存下来,可以将动态的处理结果缓存下来,所以第二个用户请求时,压根就不用交由后端服务器去处理,直接由nginx返回用户结果,这时候性能提升就很快了;
但是很有可能通过缓存得到的资源不是最新的,所以对于那些动态生成以后对用户区别不大或者是变化不大的内容就可以缓存下来,更重要的是我们会有很多动态资源,在这些动态资源里面我们可能只有一部分不同,大多数动态资源都是一样的,至少说对同一个用户的多次请求应该是一样的,因此缓存下来能够极大的提升其响应能力的;站在这个角度来讲,nginx既能反代,又能缓存;
3、http/https协议的反向代理;
前端是一台nginx,接收用户请求时是http协议,但是它把用户请求直接通过httpd协议反代给工作在一台主机之上的httpd了,而httpd又跟php相结合,形成了amp结构;这就形成了一个lnamp;
4、imap4/pop3协议的反向代理;
5、tcp/udp协议的反代(传输层);
四 nginx的安装配置
4.1 官方的预制包
http://nginx.org/packages/centos/7/x86_64/RPMS/
http://nginx.org/en/linux_packages.html
4.2 编译安装
4.2.1 安装编译环境
yum groupinstall "Development Tools" "Server Platform Development" –y
yum install pcre-devel openssl-devel zlib-devel –y ;这三个模块对nginx来讲是最为重要的,因为他们是基本功能的提供,支持url rate,支持https,支持数据报文压缩时的传送;
4.2.2 添加系统用户
useradd -r nginx
4.2.3 编译前的准备
一定要进入到nginx 解压包目录下执行以下命令;
./configure --prefix=/usr/local/nginx
--sbin-path=/usr/local/nginx/sbin/nginx
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--pid-path=/var/run/nginx.pid
--lock-path=/var/run/nginx.lock
--user=nginx
--group=nginx
--with-http_ssl_module(表示支持https主机)
--with-http_v2_module (表示支持http2.0版本的协议)
--with-http_dav_module (表示支持分布式版本协作模块)
--with-http_stub_status_module (内建的状态输出模块)
--with-threads
--with-file-aio
--prefix=默认安装目录
--sbin-path=主程序路径
--modules-path=模块文件的路径
--conf-path=主配置文件目录,也就是.conf文件位置;
--error-log-path=错误日志存放路径;
--http-log-path=访问日志文件路径;
--lock-path=锁文件存放路径;
--pid-path=pid文件存放路径;
--user=运行linux程序以哪个用户的身份运行;
--group=以哪个组运行;
--with-http_ssl_module:支持https主机
--with-http_v2_module:http1.10支持http2.0版本的协议;
--with-http_dav_module:分布式版本协作模块
--with-http_stub_status_module:内建的状态输出模块
--with-select_module=启用select模块
--without-select_module=禁用select模块
--with-threads=启用线程池的功能
--with-file-aio=文件异步I/O功能;
4.2.4 开始编译及安装
make && make install
4.2.5 添加nginx环境变量
vim /etc/profile.d/nginx.sh
export PATH=/usr/local/nginx/sbin:$PATH
重读配置文件让环境变量生效:
. /etc/profile.d/nginx.sh
编译安装时,直接输入nginx就可以启动nginx服务;
Nginx的网页文件路径默认在:(编译安装)/usr/local/nginx/或(yum安装)/usr/share/nginx/html
五 nginx配置文件组成
主配置文件:nginx.conf
include conf.d/*.conf
astcgi, uwsgi,scgi等协议相关的配置文件
mime.types:支持的mime类型
Nginx的自带指令:
nginx -t nginx修改完配置文件后可以进行语法检查;
-s 重载配置文件;
eg: Nginx -s reload
5.1 主配置文件的配置指令
directive value [value2 ...];
多个指令的值用空格分开,每个指令结束后用封号(;)结尾;
注意:
(1) 指令必须以分号结尾,否则为语法错误;
(2) 支持使用配置变量;
内建变量:由Nginx模块引入,可直接引用;
自定义变量:由用户使用set命令定义;
定义变量:set variable_name value;
引用变量:$variable_name
5.2 主配置文件结构
/etc/nginx/nginx.conf
main block:主配置段,也即全局配置段;
worker_processes 定义几个work进程;
事件驱动相关的配置段;
events {
... 用来定义每进程并发响应多少个请求;
}
http/https协议相关的配置段
http {
...
}
邮件协议相关的配置段
mail {
...
}
TCP/UDP等协议相关的配置段
stream {
...
}
5.3 http协议相关的配置结构
http {
...
...如果多个server需要用到共同的配置,则放在server之外,http之内,各server的公共配置;
server {
... 每个server用于定义一个虚拟主机;
}
server {
...
server_name
root
alias 定义路径别名
location [OPERATOR] URL {
...
if CONDITION {支持条件判断;
...
}
}
}
}
main全局配置段常见的配置指令:
分类:
正常运行必备的配置
优化性能相关的配置
用于调试及定位问题相关的配置
事件驱动相关的配置
六 正常运行必备的配置模块
http://nginx.org/en/docs/ :nignx各模块介绍
6.1 user
定于nginx运行的用户
Syntax: user user [group];定义nginx运行配置
Default: user nobody nobody;默认以nobody的身份运行;
Context: main 只能配置在main配置段;
Defines user and group credentials used by worker processes. If group is omitted, a group whose name equals that of user is used.
定义工作流程所使用的用户和组凭据。如果省略了组,则使用一组名称等于用户的组。
http://nginx.org/en/docs/ngx_core_module.html#user
6.2 pid
pid /PATH/TO/PID_FILE; 进程的id号存放位置
指定存储nginx主进程进程号码的文件路径;
http://nginx.org/en/docs/ngx_core_module.html#pid
6.3 daemon
是否运行为守护进程
6.4 include file | mask
指明包含进来的其它配置文件片断;
直接指明哪个目录下,以通配符的方式指明任何配置文件;可以用在任何位置,通常放在main当中;
http://nginx.org/en/docs/ngx_core_module.html#include
6.5 load_module file
指明要装载的动态模块;
6.6 thread_pool
定义线程池名称
池中的线程数量和队列的最大长度,nginx可以通过线程池来控制主机的并发连接数;
七 性能优化相关的配置
7.1 worker_processes number | auto
worker进程的数量;通常应该为当前主机的cpu的物理核心数;对于nginx来讲应该尽可能的小于或等于主机CPU的物理核心数;
使用命令lscpu查看cpu的核心数信息;
当nginx启动之后,可以用ps aux看到nginx起了多少个进程;
Nginx的最大特点就是单进程能够响应多个请求;
http://nginx.org/en/docs/ngx_core_module.html#worker_processes
实例:
当work_processes 2;时
从上图可以看出一个master进程发起了两个worker进程;
7.2 Work进程与CPU的姻亲关系
worker_cpu_affinity cpumask ...;
worker_cpu_affinity auto [cpumask];
将work进程绑定在指定的CPU上也可以自动绑定;
CPU MASK:CPU掩码
00000001:0号CPU
00000010:1号CPU
... ...
实例:
vim nginx.conf
表示将work进程绑定在第一号和第二号CPU上;其他CPU就不再用了;
对其进行压力测试:
yum install httpd-tools –y
ab –n 30000 –c 20 http://192.168.100.9/index.html
当cpu和work进程不绑定的时候,当请求进来之后,cpu的核心会来回切换以处理work进程,但是当cpu和work进程绑定之后,当请求进来之后,cpu的其中一个核心就会只处理这一个请求,而不是在多个请求之间来回切换,从而提高了nginx的并发响应能力;
7.3 worker_priority number
指定worker进程的nice值,设定worker进程优先级;[-20,20]
主要作用在于进程能够被优先调度至CPU,默认为0;
数字越小,优先级越高;
示例:
Vim nginx.conf
#worker_cpu_affinity auto;
worker_priority -5;
检查语法错误,重载服务;
执行命令:
Watch -n1 'ps axo pid,comm,psr | grep nginx'
查看结果;
7.4 worker_rlimit_nofile number
用于设定worker进程所能够打开的文件数量上限;
每一个连接都需要被服务器端回复一个套接字文件;
至少得有20000文件;所以该设定至关重要;
八 调试、定位问题
8.1 daemon on|off
是否以守护进程方式运行nignx;
如果不想以守护进程的方式运行,那么nginx的进程就运行在前台了;
8.2 master_process on|off
Context:main
是否以master/worker模型运行nginx;默认为on; Off通常只为管理员所设定;
8.3 error_log file [level]
Context:main http mail stream server location,定义的配置段越小,越能够覆盖外部的配置;
定义错误日志的日志级别
九 事件驱动相关的配置
events {
...必须放在该配置段中;
}
9.1 worker_connections number
每个worker进程所能够打开的最大并发连接数数量;
worker_processes * worker_connections=nginx的最大并发连接数;
(work进程的数量)
9.2 use method
指明并发连接请求的处理方法;
默认值:
use epoll;
一般不需要修改,如果被修改成了select,则并发连接性能会急剧下降;
9.3 accept_mutex on | off
建议使用on;默认为off;
Mutex:互斥锁,用于保证某一个资源在某一个时刻只能被一个进程所使用;
处理新的连接请求的方法;on意味着由各worker轮流处理新请求,Off
意味着每个新请求的到达都会通知所有的worker进程;
十http协议的相关配置
http {
... ...公共配置段;
server {
...
server_name
root
location [OPERATOR] /uri/ {
...
}
}
server {
...
}
}
server的公共配置,可以放在公共配置段,让各server都使用,如果说一个server当中,单独定义的,只对当前一个server有效,更重要的是,在公共段配置了,也可以在server当中指定,这就意味着对于一个server而言我只会用自己的配置段,而不会用公共配置段;
十一 与套接字相关的配置
11.1 server { ... }
配置一个虚拟主机:
server {
listen address[:PORT]|PORT;监听的地址和端口;
server_name SERVER_NAME;
root /PATH/TO/DOCUMENT_ROOT; 指明文档根目录;
}
http://nginx.org/en/docs/http/ngx_http_core_module.html#server
实例:在根下创建/testdir/www1 www2并且分别在www1和www2下面建立测试页面;
nginx –t 检查语法错误
nginx –s reload 重载nginx服务
11.2 listen
listen PORT | address[:port] | unix:/PATH/TO/SOCKET_FILE
三种语法格式;
listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size]
default_server 默认虚拟主机,只能有一个默认虚拟主机;如果存在多个虚拟主机,不加default_server当我们访问一个不存在的虚拟主机时,默认将是第一个;
ssl 表示当端口为443时使用,如果没有给端口,加上ssl,则默认为443,表示此端口必须通过ssl来提供服务;
http2/spdy 表示使用http2.0版本的协议或使用spdy协议;
backlog=number 后援队列的长度;假如监听的端口上连接已满,再来一个新的连接就需要排队了,backlog就是指明排队后的队列长度;
rcvbuf=size 接收缓冲的大小;
sndbuf=size 发送缓冲的大小;
11.3 server_name name ...
Context:server 只能放在server中;
指明虚拟主机的主机名称;
①后可跟多个由空白字符分隔的字符串;
②支持*通配任意长度的任意字符;
示例:server_name *.magedu.com
③支持~起始的字符做正则表达式模式匹配;server_name ~^wwwd+.magedu.com$
匹配机制:
(1) 首先是字符串精确匹配;
(2) 左侧*通配符;
(3) 右侧*通配符;
(4) 正则表达式;
优先级:精确匹配最高,正则表达式最低;
11.4 tcp_nodelay on | off
建议on,以提高用户体验;
主要在keepalived模式下的连接是否启用TCP_NODELAY选项;
on:绝不允许用户请求延迟发送;
off:启用将多个小包打包为一个大包发送的功能;
任何数据报文在发送之前,得先3次握手,完成之后得4次断开,但是如果某一次用户所请求的资源非常小,tcp都得3次握手4次断开,有点浪费带宽;
而tcp_nodelay可以在keepalive模型下,当用户请求一个资源的时候,而该资源又较小的时候,它不会拿着这个资源立即响应给客户端,而是等客户端请求下一个报文,把多个资源合起来打包成一个进行发送;
11.5 sendfile on | off
是否启用sendfile功能;
在内核级别直接封装用户请求的资源,响应给客户端;这个可以为on,以优化nginx;
十二 定义路径相关的配置
12.1 root path
设置web资源路径映射;用于指明用户请求的url所对应的本地文件系统上的文档所在目录路径;可用的位置:http, server, location, if in location;
12.2 location
格式一 location [ = | ~ | ~* | ^~ ] uri { ... }
格式二 location @name { ... }
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,并找出一个最佳匹配,而后应用其配置;
=:对URI做精确匹配;例如, http://www.magedu.com/, http://www.magedu.com/index.html
location = / {
...
}
所以上面的/能匹配http://www.magedu.com/,而不会匹配http://www.magedu.com/index.html,这就是精确匹配,多一个字符都不行;
~:对URI做正则表达式模式匹配,区分字符大小写;
~*:对URI做正则表达式模式匹配,不区分字符大小写;
^~:对URI的左半部分做匹配检查,不区分字符大小写;
不带符号:匹配起始于此uri的所有的url;因此通常位于实现为某个uri提供默认配置的;
匹配优先级:= > ^~ > ~/~* > 不带符号;
root /vhosts/www/htdocs/
http://www.magedu.com/index.html --> /vhosts/www/htdocs/index.html
这里的root就表示,对于网站站点来讲,将/vhosts/www/htdocs/该路径当根了;
server {
root /vhosts/www/htdocs/
我们直接在server中定义一个root /vhosts/www/htdocs/,它所带来的意义在一定程度上相当于我们在server中定义了一个location /,
location / {
/vhosts/www/htdocs/
}
表示我们要将server虚拟主机的location "/"这个url,它其实所指定的文档是以/vhosts/www/htdocs/为根的,所以将root直接写在server中,有点类似于将root写在location中;
location / {
root /vhosts/www/htdocs/
意味着加粗的两个根之间是直接做映射的;
}
}
所以两种形式的意义是相同的,但是所不同的是,location /中定义root,这种方式我们可以在当中定义额外的控制法则,比如说基于ip的访问控制;
假如我们只想对/vhosts/www/htdocs/admin/中,只想对admin中的资源做认证,而不是对root做认证,而是只对admin做,在location中定义时只能写成:
server {
root /vhosts/www/htdocs/
location /admin/ {
root /vhosts/www/htdocs/ 如果在这不定义root;
}
那么这里的localtion就相当于/vhosts/www/htdocs/下的admin目录;
示例:
当配置文件中的默认路径是/usr/share/nginx/html时,在浏览器中访问192.168.100.6/admin时,nginx会报错,因为在/usr/share/nginx/html下没有admin这个目录,需要在/usr/share/nginx/html下新建一个admin目录在admin目录下定义一个index.html主页才能访问,那么这个admin目录也可以单独拿出来重新定义路径;
此时,当定义完location /admin/时,/testdir/www/html是没有被创建的,这时候访问也是报错的,查看错误日志,则发现,请求的路径是/testdir/www/html/admin/index.html;
所以在/testdir/www/html/创建admin目录,在admin目录中创建index.html则就可以正常访问了;
但是,别名就不一样了;
当定义成别名以后,访问192.168.100.6/admin,就表示访问/testdir/www/html/;
12.3 alias path
定义路径别名,文档映射的另一种机制;仅能用于location上下文;
注意:location中使用root指令和alias指令的意义不同;
(a) root,给定的路径对应于location中的/uri/左侧的/;
(b) alias,给定的路径对应于location中的/uri/右侧的/;
12.4 index file
定义默认主页
可用位置:http, server, location;
http://nginx.org/en/docs/http/ngx_http_index_module.html
12.5 error_page code ... [=[response]] uri
Context:http, server ,lication ,if in location
Defines the URI that will be shown for the specified errors.
自定义响应给用户的URI页面资源
如果在当前位置当中没有定义error_page,它将从上一级进行继承,以此类推,但是只要自己有,就不再被继承;
我们可以为指定的错误响应码定义响应给用户的uri页面资源;
http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
实例:
在 /error/error_page下创建自己的404.html
在浏览器中访问一个不存在的页面;然后就会跳转到该页面;
此时我们通过浏览器的检测工具发现它的状态码也确实是404,但是如果我们就希望用户看到的是200的状态码该如何配置呢?
这就达到了修改状态码的目的;
十三 定义客户端请求的相关配置
13.1 keepalive_timeout timeout [header_timeout]
设定保持连接的超时时长,0表示禁止长连接;默认为75s;
http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout
13.2 keepalive_requests number
在一次长连接上所允许请求的资源的最大数量,默认为100;
13.3 keepalive_disable none | browser
对哪种浏览器禁用长连接;
13.4 send_timeout time
向客户端发送响应报文的超时时长,此处,是指两次写操作之间的间隔时长;
设定向客户端发送响应报文的超时时长,这个超时时长是在nginx端设定两次写操作之间的时长的,而不是给客户端发送报文的时长。(什么意思呢?在保持连接的基础上客户端连续请求了两个资源,服务端发完第一个资源就该发第二个资源了,第一个资源发送的时候需要向套接字发送rite请求,第二个也是一样的道理,这两次rite请求之间的时长是作为send_timeout时长的;)如果在这个指定时间内客户端没有接收数据的话,那么连接关闭;
http://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout
nginx在将来做反向代理时需要一手托两家,如果不考虑它代理的话那它就是一个web服务器,那么在做web服务器怎么去响应用户请求呢?在nginx中可以定义多个server,每一个server用来处理一类用户请求,当客户端与nginx服务器彼此间建立了连接,并完成数据传送时,要考虑一些问题,比如这个连接建立需要一段时间,那要是一直建立不成功怎么办呢?或者是当客户端发出了请求,服务端也收到了请求,于是服务端开始处理请求之后,把响应报文给客户端发送,但是由于客户端的带宽太小,发送了半天也没发送完,这时候nginx服务器一直要等待客户端将数据全部接收完成,这会非常消耗nginx宝贵的连接资源。因此,客户端与服务端在建立连接时,我们要明白这几个问题,首先每一次的请求和响应他其实都有好几个阶段,先是连接建立,接着是服务端从客户端接收请求,紧接着服务端发送响应,在收发请求响应报文时,客户端应该有发送缓冲,服务端应该有接收缓冲,这时候我们就可以修改跟连接时长相关的数据;不过多数情况下默认配置就能保证我们的日常需要,只有在极端场景下我们才需要修改此值,比如说服务器在非常繁忙的情况下,向客户端发送响应请求,半天发不出去,这也许是服务端太繁忙,这时候我们就可以将超时时长调整得大一点;
13.5 client_body_buffer_size size
用于接收客户端请求报文的body部分的缓冲区大小;默认为16k;超出此大小时,其将被暂存到磁盘上的由client_body_temp_path指令所定义的位置;
客户端所请求的body部分,在服务端接收下来完成之前,服务端是没办法做处理的,而任何数据在网上传输时,都是流式化的,整个报文是一点一点发送的,因此对与我服务端来讲,需要一点一点接收,直到接收完成合并成原始数据,所以为了能够将这些数据一并接下来进行处理,服务端对客户端的连接线程得开一个专门的用于存储请求报文的body部分的缓存空间,但是如果服务器接收put的方法,连接现在成千上万,每一个连接都得有body部分,那得多少内存才能够用,所以有必要的话,需要将body部分放在磁盘上,因为内存不够用了;这时候就需要开启磁盘空间来充当body部分的缓冲区来使用;
13.6 client_body_temp_path
client_body_temp_path path [level1 [level2 [level3]]]
设定用于存储客户端请求报文的body部分的临时存储路径及子目录结构和数量;
Level其实是16进制的数字;这16进制的数字既能表示level,又能自左而右如果有3个16进制数字,对应的level上有数字,就表示有这一级,没有,就表示没有这一级;
client_body_temp_path path /var/tmp/client_body 1 2 2
/var/tmp/client_body:表示临时文件的路径;这里面的文件怎么管理呢?有一级子目录16个,第一个2表示:每个一级子目录下有256个二级子目录,一共有16*256个二级子目录;第二个2表示:又有256个三级子目录;共有16*256*256个三级子目录;
十四 对客户端进行限制的相关配置
14.1 limit_rate rate
限制响应给客户端的传输速率,单位是bytes/second,0表示无限制;
14.2 limit_except method ... { ... }
限制对指定的请求方法之外的其它方法的使用客户端;
limit_except GET {
allow 192.168.1.0/32;
deny all;
}
除了GET之外的其他方法,仅允许192.168.1.0/32网络中的主机访问;deny all表示拒绝其他主机;
十五 文件操作优化的配置
15.1 aio on | off | threads[=pool]
表示aio功能是启用/关闭/指明在哪一个线程池当中允许使用;
aio表示为异步IO模型;
15.2 directio size | off
O_DIRECT flag表示直接IO机制;
例如directio 4m;
开启使用直接IO机制功能以后可以直接实现将对应的数据发往磁盘时能够立即存储在磁盘上,或者读取文件时也一样,能够立即读取;
在nginx中配置directio有什么作用呢?默认是off的,如果启用表示开启O_direct flag功能;在Mac OS中使用F_NOCACHE flag(表示没有缓存机制)直接同步磁盘,发往进程内存;一旦我们启用这种directio功能以后,我们可以基于指定的大小或大于等于这个指定的值来判断是否启用directio功能;小于该值,则不启用directio功能;directio 4m表示从磁盘上加载文件时,只有大于4m的文件我们才启用directio功能,从磁盘上读来以后,由内核直接发往进程内存;
15.3 open_file_cache off
open_file_cache max=N [inactive=time];
nginx可以缓存以下三种信息:
(1) 缓存文件的描述符、文件大小和最近一次的修改时间;
(2) 缓存打开的目录结构;
(3) 没有找到的或者没有权限访问的文件的相关信息;好处就是将来当用户请求到某一个url对
应一个文件时,我们在缓存中就能够知道该文件到底有没有权限访问;
max=N:可缓存的缓存项上限,取决于我们的内存空间;达到上限后会使用LRU算法(最近最少使用算法)实现缓存管理;
inactive=time:缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于 open_file_cache_min_users指令所指定的次数的缓存项即为非活动项;
15.4 open_file_cache_valid time
缓存项有效性的检查频率;默认为60s;检查缓存项是否过期,若过期则被移除;
15.5 open_file_cache_min_uses number
在open_file_cache指令的inactive参数指定的时长内,至少应该被命中多少次方可被归类为活动项;
15.6 open_file_cache_errors on | off
是否缓存查找时发生错误的文件一类的信息;
十六 ngx_http_access_module
ngx_http_access_module模块
实现基于ip的访问控制功能
16.1 allow address
allow address | CIDR | unix: | all;
16.2 deny address
deny address | CIDR | unix: | all;
CIDR:无类型域间选路;
http, server, location, limit_except(除了)
http://nginx.org/en/docs/http/ngx_http_access_module.html
十七 ngx_http_auth_basic_module
ngx_http_auth_basic_module模块
现基于用户的访问控制,使用basic机制进行用户认证;
17.1 auth_basic
auth_basic string | off; 给定提示信息;
17.2 auth_basic_user_file
auth_basic_user_file file; 指明用户账户密码文件路径;
location /admin/ {
alias /webapps/app1/data/;
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.ngxpasswd;
}
若要使用htpasswd,则需要安装httpd-tools;
十八 ngx_http_stub_status_module
ngx_http_stub_status_module模块
用于输出nginx的基本状态信息;
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106
Active connections: 活动状态的连接数;
accepts:已经接受的客户端请求的总数;
handled:已经处理完成的客户端请求的总数;
requests:客户端发来的总的请求数;
Reading:处于读取客户端请求报文首部的连接的连接数;
Writing:处于向客户端发送响应报文过程中的连接数;
Waiting:处于等待客户端发出请求的空闲连接数;
配置示例:
location /basic_status {
stub_status;
}
如果basic_status的日志不想被记录,则:
http://nginx.org/en/docs/http/ngx_http_stub_status_module.html
十九 ngx_http_log_module
ngx_http_log_module模块
he ngx_http_log_module module writes request logs in the specified format.
以指定格式来记录用户的访问请求;
19.1 log_format name string
string可以使用nginx核心模块及其它模块内嵌的变量;
nginx的内建变量:
$remote_addr:客户端地址
$remote_user:远程客户端的用户
$time_local:本地时间
$request:远端客户端请求时的原始请求的URL;
$status:响应的状态码;
$bytes_sent 所发送的客户端的响应的报文的字节数;
$http_referer:从哪个页面跳转而来
$http_user_agent:客户端的浏览器类型;
$gzip_ratio:记录压缩级别
在nginx.conf主配置文件中有定义;可做参考;
http://nginx.org/en/docs/http/ngx_http_log_module.html
19.2 access_log path
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
表示访问日志的文件路径在什么地方
path:日志路径;
format:日志格式
access_log off;关闭日志功能
访问日志文件路径,格式及相关的缓冲的配置;
buffer=size 缓冲大小
flush=time:每隔多长时间把缓存中的数据写到磁盘中去;
19.3 open_log_file_cache
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
缓存各日志文件相关的元数据信息;而不是日志文件内容;
max:缓存的最大文件描述符数量;
min_users:在inactive指定的时长内访问大于等于此值方可被当作活动项;
inactive:非活动时长;
valid:验正缓存中各缓存项是否为活动项的时间间隔;
二十 ngx_http_rewrite_module
ngx_http_rewrite_module模块:
The ngx_http_rewrite_module module is used to change request URI using PCRE regular expressions, return redirects, and conditionally select configurations.
将用户请求的URI基于PCRE的正则表达式引擎重写以后返回一个重定向的结果;并且能够基于条件来选择配置;
将用户请求的URI基于regex(正则表达式)所描述的模式进行检查,而后完成替换;
20.1 rewrite regex replacement
rewrite regex replacement [flag]
将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI;
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,因此,隐含有循环机制;[flag]所表示的标志位用于控制此循环机制;
如果replacement是以http://或https://开头,则替换结果会直接以重定向返回给客户端;
301:永久重定向;
302:临时重定向;
示例:
例如之前比较火的bbs,人们访问的时候都是1.1.1.1/bbs;但是bbs逐步被放弃,而改成了forum,那么人们已经习惯的bbs,当网民访问bbs的时候发现访问不了了,那么为了在用户不改变使用习惯的情况下仍然能用bbs访问forum的内容,则需要rewrite设置;这时候用户访问bbs是没有感知的,实际是到了forum;
假如说bbs之前的内容都到了forum下,而网民又访问的是bbs所以配置如下;
示例二:将rewrite放在location下;
^/bbs/(.*)$ /forum/$1:以bbs开头,后面跟任意内容,并以它结尾,然后替换成/forum/$1;$1表示:之前匹配的的是什么,在/forum/下就引用什么;
[flag]:
last:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环;
break:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环;
示例:
当一个location中有多个rewrite时,会逐一去匹配替换;为了测试效果人为配置一个死循环;
这个时候,break的作用就有了;
也可以这么跳转:
此时,访问/bbs/就会跳转到www.baidu.com;
状态是302临时重定向;
redirect:重写完成后,以临时重定向方式,直接返回重写后生成的新URI给客户端,由客户端重新发起请求;不能以http://或https://开头;返回状态响应码302;
当我们不跟任何参数的时候默认是last,此时的处理循环机制是在nginx内部实现的,跟客户端浏览器没有任何关系
而当加了redirect参数后:
之前不加redirect时,在浏览器中是看不见forum的,但是当加了redirect后就能看见forum了,这是因为,这个重定向的跳转是由浏览器自己完成的,而不是nginx完成的;
permanent:重写完成后,以永久重定向方式,直接返回重写后,生成的新URI给客户端,由客户端重新发起请求;返回状态响应码301;
该重定向也是由客户端浏览器发起的;
20.2 return 返回
return code [text];
return code URL;
return URL;
直接停止处理机制,并返回给客户端一个响应码;
如果我们重写完成之后,用户依然没有得到相应的资源,就直接返回用户状态码403;并终止后续请求;
20.3 rewrite_log
rewrite_log on | off
是否开启重写日志;
20.4 if (condition) { ... }
if (condition) { ... }
引入一个新的配置上下文 ;条件满足时,执行配置块中的配置指令;
可用于:server, location;
condition:
比较操作符:
== 等于
!= 不等于
~:模式匹配,区分字符大小写;
~*:模式匹配,不区分字符大小写;
!~:模式不匹配,区分字符大小写;
!~*:模式不匹配,不区分字符大小写;
文件及目录存在性判断:
-e, !-e 文件是否存在
-f, !-f 是否为普通文件
-d, !-d 存在是否为目录
-x, !-x 存在是否可执行
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if
20.5 set $variable value
set $variable value;
用户自定义变量 ;
二十一ngx_http_gzip_module
The ngx_http_gzip_module module is a filter that compresses responses using the "gzip" method. This often helps to reduce the size of transmitted data by half or even more.
过滤出可以压缩的内容然后进行压缩;
21.1 gzip on | off
Enables or disables gzipping of responses.是否启用对响应报文的压缩功能;
21.2 gzip_comp_level level
gzip_comp_level level;压缩级别
Sets a gzip compression level of a response. Acceptable values are in the range from 1 to 9.
有效取值范围是1-9;
21.3 gzip_disable regex
gzip_disable regex ...;对哪些浏览器关闭gzip功能;
Disables gzipping of responses for requests with "User-Agent" header fields matching any of the specified regular expressions.
用户的请求报文中User-Agent首部的值被此处正则表达式模式匹配时将对其禁用压缩功能;
21.4 gzip_min_length
gzip_min_length length;
启用压缩功能的响应报文大小阈值;
21.5 gzip_buffers number size
gzip_buffers number size;
支持实现压缩功能时为其配置的缓冲区数量及每个缓存区的大小;
21.6 gzip_proxied
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的
值为此三者中任何一个,则启用压缩功能;
21.7 gzip_types
gzip_types mime-type ...;
压缩过滤器,仅对此处设定的MIME类型的内容启用压缩功能;
21.8 gzip_vary
gzip_vary on
插入一个响应报文的首部;
示例:
cat /etc/nginx/mime.types 查看可以压缩哪些资源;
复制一个较大的文件将后缀修改为能让压缩的.html结尾的文档;并加入读权限;
然后用浏览器测试;显示已经开启了压缩功能;但是不知道为什么gzip_vary on的效果没出来;
加上gzip_vary on的效果就是上面小图中的样子,不知道是不是我的谷歌浏览器的问题,死活出不来这个效果;
测试禁止谷歌浏览器开启压缩功能;
不好意思,这个功能也没有实现,配置检查了也没有问题,但是就是无法看到禁止Chrome浏览器的压缩效果;
二十二 ngx_http_fastcgi_module
fastcgi_module是为了实现nginx与PHP-fpm服务器结合的一个模块;
The ngx_http_fastcgi_module module allows passing requests to a FastCGI server.
用户的请求http请求到达nginx之后,当nginx收到请求以后把那些资源类型为php的则发送给后端的php-fpm主机,当php-fpm收到请求之后,需要把url映射为本地的文件系统资源,把该资源加载至fpm的某一个进程上,在本地完成运行,将运行后的结果返回给前端的nginx,再由nginx返回给用户。如果php-fpm需要跟mysql进行交互完成数据管理的话,它还需要基于mysql协议跟后端的mysql存储完成交互;
22.1 fastcgi_pass
fastcgi_pass address;
将fastcgi的请求代理至后端主机
address为fastcgi server的地址; location, if in location;
22.2 fastcgi_index
fastcgi_index name;
fastcgi默认的主页资源;
22.3 fastcgi_param parameter value
fastcgi_param parameter value [if_not_empty];
Sets a parameter that should be passed to the FastCGI server. The value can contain text, variables, and their combination.
就是将前端连接中的某些变量的值传递给后端服务器的变量;传递给后端的某个服务器的变量的值可以是字符串也可以是某个有值变量,或者是二者的组合;
22.4 lnmp配置示例
(1)安装所需软件
yum install nginx php-fpm php-mysql mysql-server(CentOS 7装mariadb-server) php-gd php-mbstring php-mcrypt –y
(2)启动nginx服务,确保80端口开启;启动mysql数据库服务,确保3306端口开启;
(3)编辑/etc/php-fpm.d/www.conf文件,修改属主、属组;
(4)创建/var/lib/php/session并将session目录的属主属组修改为nginx;
mkdir -p /var/lib/php/session
chown -R /var/lib/php/session
(5)启动php-fpm服务,确保9000端口被监听;
CentOS 6:service php-fpm start
CentOS 7:systemctl start php-fpm.service
(6)在/usr/share/nginx/html路径下添加index.php的测试页
(7)编辑/etc/nginx/conf.d/default.conf
(8)对nginx进行语法检查,然后重载nginx,建议关闭iptables,或者允许9000和3306端口的访问;在浏览器中测试;
配置示例2:通过/pm_status和/ping来获取fpm server状态信息;
(1)vim /etc/nginx/conf.d/default.conf
(2)vim /etc/php-fpm.d/www.conf,取消如下图所示两行的注释;
(3)在浏览器中测试,会返回一个pong的结果;
但是我的pm_status的效果一直出不来;
错误日志
这部分配置在学习视频的第五个视频的开头;
22.5 fastcgi_cache_path
fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
nginx作为一个反代服务器,它还有另外一个功能,对于我们的fastcgi的内容向后端代理时,直接启用缓存功能;
当用户请求到达nginx时,nginx再将用户请求发送到后端fastcgi,fastcgi经过处理后再将报文传递给nginx,由nginx返回给用户结果,那么如果nginx将该结果缓存下来呢?那么用户下次再访问的时候,由nginx直接将结果返回给用户,这样速度就快多了,但是如果后端数据发生了变化呢?所以,我们可以定义哪些数据可以缓存,哪些数据不可以缓存,缓存多长时间,这些都是可以自定义的;
定义fastcgi的缓存;缓存位置为磁盘上的文件系统,由path所指定路径来定义;
levels=levels:缓存目录的层级数量,以及每一级的目录数量;levels=ONE:TWO:THREE
leves=1:2:2
任何缓存服务器它的缓存内容的组织格式都是键值数据,以哈希格式存放的,键称为元数据,值称之为数据,nginx组织缓存的方式是每一个缓存的内容就是由键值对组成的;md5sum 计算文件的哈希值;
Key/value:
Key(键):URL
Value(值):url路径的内容
keys_zone=name:size
k/v映射的内存空间的名称及大小
inactive=time
非活动时长
max_size=size
磁盘上用于缓存数据的缓存空间上限
22.6 fastcgi_cache zone | off
fastcgi_cache zone | off;
调用指定的缓存空间来缓存数据;http, server, location
22.7 fastcgi_cache_key string
fastcgi_cache_key string
定义用作缓存项的key的字符串;通常是uri做变量;
string:是我们定义的cache的名称;
22.8 fastcgi_cache_methods GET | HEAD | POST
fastcgi_cache_methods GET | HEAD | POST ...;
为哪些请求方法使用缓存;
22.9 fastcgi_cache_min_uses number
fastcgi_cache_min_uses number;
缓存空间中的缓存项在inactive定义的非活动时间内至少要被访问到此处所指定的次数方可被认作活动项;
22.10 fastcgi_cache_valid [code ...] time
fastcgi_cache_valid [code ...] time;
不同的响应码各自的缓存时长;
22.11 nginx缓存配置示例
http {
...
fastcgi_cache_path /var/cache/nginx/fastcgi_cache levels=1:2:1 keys_zone=fcgi:20m inactive=120s;
... 定义内存空间20m 非活动期限
server {
...
location ~* .php$ {
...
fastcgi_cache fcgi;
fastcgi_cache_key $request_uri; #用户请求报文的uri;
fastcgi_cache_valid 200 302 10m; #200和302缓存10min;
fastcgi_cache_valid 301 1h; #301缓存1h;
fastcgi_cache_valid any 1m; #其他状态码缓存1min;
...
}
...
}
...
}
chown –R nginx:nginx /var/cache/nginx/fastcgi_cache/
ab –c 100 –n 2000 http://10.1.0.67/pma/index.php
手动登录一下pma,多刷新几次;
tree /var/cache/nginx/fastcgi_cache/ 查看是否生成缓存;如果有多级目录产生,则证明缓存成功;
当再次压力测试的时候可能会好很多;
(1)为了测试需要。可以安装MySQL的图形化管理工具phpMyAdmin-4.4.14.1-all-languages.zip,
Unzip解压后将其配置文件cp到/usr/share/nginx/html路径下,并改名为pma。
安装php-mbstring。
进入pma目录复制 config.sample.inc.php并改名为config.inc.php,然后编辑config.inc.php,
在上图划红框的位置添加几个随机数。
在浏览器中测试:
也可以部署freeradius服务,安装它的web管理界面,此次试验就是以freeradius为例部署的freeradius认证系统;
其他的软件也可以,只要是php写的软件就成;也可以缓存图片、文本等这类静态资源;
(2)在nginx.conf配置文件中,在http上下文中定义缓存路径、缓存级别、内存空间的名称和大小以及非活动时长;
(3)对以.php结尾的数据定义缓存;
(4)定义fastcgi_cache的属主属组为nginx;
chown –R nginx:nginx /var/cache/nginx/fastcgi_cache/
(5)另外再找一台客户端,登陆一下freeradius,然后多刷新几次,或者在客户端上进行压力测试;
ab –c 100 –n 2000 http://192.168.100.9:8080/radius/index.php
(6)查看是否在/var/cache/nginx/fastcgi_cache/目录下生成了多级目录和缓存项;
如上图所示,不但生成了多级目录而且也有缓存项生成;
22.12 fastcgi_keep_conn on | off
By default, a FastCGI server will close a connection right after sending the response. However, when this directive is set to the value on, nginx will instruct a FastCGI server to keep connections open.
on 表示使用长连接
off 表示使用短连接
nginx在反代用户请求至fastcgi server时,是一手托两家的;nginx一方面要维持客户端一侧的连接,一方面还要维持fpm侧的连接,nginx在没有缓存的情况下,要维持每一个客户端的请求,要有两个套接字文件,nginx一般面向客户端一侧是ip地址加80端口;那么连接向后端的fpm也是有套接字文件的,此时nginx是作为客户端主机,fpm是作为服务端主机的;假如现在用户有3万个请求,那么nginx要同时将这3万请求代理至后端的fpm,也就意味着这时候nginx作为客户端而言要开3万个随机端口,这对nginx来说压力非常大。如果我们要使用保持连接的话,一个连接上可以发n个请求;所以我们并不需要前端有3万个请求时,后端就要建立3万个连接,因为一个连接就可以承载n个请求;这时候我们打开长连接,能极大的减少端口占用量;所以一般对后端来讲我们向后端开启保持连接是很有必要的;
二十三 ngx_http_ssl_module模块
1、 ssl on | off; 是否启用ssl功能
Enables the HTTPS protocol for the given virtual server.
2、ssl_certificate file;
当前虚拟主机使用PEM格式的证书文件;
3、ssl_certificate_key file;
当前虚拟主机上与其证书匹配的私钥文件;
4、ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
支持ssl协议版本,默认为后三个;
5、ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
builtin[:size]:使用OpenSSL内建的缓存,此缓存为每worker进程私有;
[shared:name:size]:在各worker之间使用一个共享的缓存;
6、ssl_session_timeout time;
定义ssl的缓存时长;客户端一侧的连接可以复用ssl session cache中缓存的ssl参数的有效时长;默认5min;
23.1 ssl配置示例
(1)生成证书文件,并放在指定的目录。生成方法,自行百度;
(2)配置/etc/nginx/conf.d/ssl.conf
(3)将证书导入浏览器进行测试;
(4)将http重定向至https,因为用户在访问网站的时候并不知道是http还是https,用户会默认是http,所以要将http重定向到https,让用户在访问http的时候跳转到https;并且互联网上默认的是80端口,而我的web服务是8080端口,这样也可以用户在访问80端口的时候跳转到8080;
二十四 ngx_http_referer_module(防盗链)
The ngx_http_referer_module module is used to block access to a site for requests with invalid values in the "Referer" header field.
如果引用不是我们所定义的合法引用范围之内的,决不允许;说白了就是防盗链;
用walid_referers来定义允许哪些是合法引用,如果请求报文中referer为none(空)/blocked(有referer首部,但没有合法的值)/ server_names表示如果有值则它的值是以example.com结尾或以example开头;或者是www.example.org或者是来自google的引用,我们都认为是合法的;如果是非法的则返回状态码403;
24.1 valid_referers
valid_referers none | blocked | server_names | string ...;
定义referer首部的合法可用值;
none:请求报文首部没有referer首部;
blocked:请求报文的referer首部没有值;
server_names:参数,其可以有值作为主机名或主机名模式;
arbitrary_string:直接字符串,但可使用*作通配符;
regular expression:被指定的正则表达式模式匹配到的字符串;要使用~打头,例如 ~.*.magedu.com;
24.2 防盗链配置示例
那么如何测试防盗链是否生效呢?
curl -k -e "http://www.baidu.com" https://192.168.100.9:8080/radius
表示https是由访问http://www.baidu.com跳转而来;
二十五 ngx_http_proxy_module
25.1 proxy_pass URL
注意:proxy_pass后面的路径不带uri时,其会将location的uri传递给后端主机;
server {
...
server_name HOSTNAME;
location /uri/ {
proxy http://host[:port];
}
...
}
http://HOSTNAME/uri --> http://host/uri
proxy_pass后面的路径是一个uri时,其会将location的uri替换为proxy_pass的uri;
server {
...
server_name HOSTNAME;
location /uri/ {
proxy http://host/new_uri/;
}
...
}
http://HOSTNAME/uri/ --> http://host/new_uri/
如果location定义其uri时使用了正则表达式的模式,则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加代理到的服务的之后;
server {
...
server_name HOSTNAME;
location ~|~* /uri/ {
proxy http://host;
}
...
}
http://HOSTNAME/uri/ --> http://host/uri/;
25.2 反向代理配置示例
(1)根据上图描述部署两台服务器,一台部署nginx,作为反向代理;另一台部署http,作为后端web服务;假设director主机是可以对外提供服务的;后端http主机跟director主机局域网通信;当网民访问10.0.1.6的时候,director主机将请求发送到后端主机,由后端主机响应之后发送给director主机,再由director主机将结果返回给网民;
(2)在后端http主机上配置两个测试页;
vim /var/www/html/index.html
vim /var/www/html/admin/index.html
(3)配置director主机;
vim /etc/nginx/conf.d/default.conf
检查语法错误后重载nginx;
(4)用浏览器测试;
注意:当proxy_pass http://192.168.100.4时,用浏览器访问10.0.1.6:8888/admin时,出现的页面是定义在/var/www/html/admin/index.html中定义的页面;
当proxy_pass http://192.168.100.4/时。用浏览器访问10.0.1.6:8888/admin时,出现的页面是/var/www/html/index.html中的页面;
(5)将符合条件的URL代理至后端服务器;例如将图片代理至后端;
先在后端http主机的/var/www/html下放一个图片;再配置director主机;
vim /etc/nginx/conf.d/default.conf
(6)用浏览器测试
查看后端主机的httpd的log,会发现,请求全部是由192.168.100.9 director这台主机发起的;
25.3 proxy_set_header
proxy_set_header field value;
设定发往后端主机的请求报文的请求首部的值;
Context: http, server, location
对于代理服务器来讲要将请求报文自己封装起来发送给后端主机,在发送给后端主机时可以自己指定请求报文当中有哪个首部,首部名称和首部的值;
Eg:
proxy_set_header X-Real-IP $remote_addr;
面向客户端一侧时,这个真正发出请求的客户端的ip地址;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
配置示例:
之前我们查看httpd的日志发现向后端发起请求的都是director主机发起的,将proxy_set_header模块添加上之后,可以在后端服务器的日志中记录实际的报文发起者,而不再记录director的IP;
vim /etc/nginx/conf.d/default.conf
配置后端httpd服务;
vim /etc/httpd/conf/httpd.conf
重启服务后在浏览器上测试访问后端网页,多刷新几次,并查看后端http的日志;
上图中10.0.1.3这个ip地址就是我实际的客户端请求的地址;
25.4 proxy_cache_path
定义可用于proxy功能的缓存;
Context: http
proxy_cache_path path [levels=levels](缓存级别)
[use_temp_path=on|off] keys_zone(内存中存放URL的哈希值以及与之对应的URL缓存的缓存项的文件的文件名)=name:size
[inactive=time(非活动时长)]
[max_size=size(目录一共用多大的空间来缓存缓存项)]
[manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
25.5 proxy_cache
proxy_cache zone | off;
指明要调用的缓存,或关闭缓存机制;Context: http, server, location
25.6 proxy_cache_key
proxy_cache_key string;
缓存中用于"键"的内容;
键:用户请求的URL的哈希值
值:定义在磁盘路径上的文件
默认值:proxy_cache_key $scheme(协议)$proxy_host(代理服务器)$request_uri;
建议:如果不打算区分协议,和代理服务器,就只是用$request_uri
25.7 proxy_cache_valid
proxy_cache_valid [code ...] time;
定义对特定响应码的响应内容的缓存时长;
定义在http{...}中;(nginx.conf)
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:1:1 keys_zone=pxycache:20m max_size=1g;
/var/cache/nginx/proxy_cache 该路径有可能不存在,属主属组有可能要改成nginx,或者需要重启nginx服务。
定义在需要调用缓存功能的配置段,例如server{...};
若只定义图片缓存,就在location中定义。若要定义整个server,就在server中定义。
proxy_cache pxycache; 表示调用此缓存功能
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 1h; 对于不同的响应码的缓存时长
proxy_cache_valid any 1m; 对其他响应码缓存1min
刷新图片页面,查看/var/cache/nginx/proxy_cache 路径下是否有缓存文件生成。
25.8 proxy_cache_use_stale
proxy_cache_use_stale
若后端服务器宕机,但是缓存内容还有,意味着代理服务器的缓存过期,为了避免用户那里得到无效信息,最好可以允许使用缓存来响应。
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off(关闭此功能) ...;表示当后端服务器在error/timeout等状态下可以将缓存内容响应给客户端;
Determines in which cases a stale cached response can be used when an error occurs during communication with the proxied server.当代理服务器与后端主机通信出现故障时在哪种情况下,我们可以直接用缓存中的缓存项直接响应给客户端。
25.9 proxy_cache_methods
proxy_cache_methods GET | HEAD | POST ...;
If the client request method is listed in this directive then the response will be cached. "GET" and "HEAD" methods are always added to the list, though it is recommended to specify them explicitly. 如果用户发出请求到代理服务器时使用的方法是GET或HEAD,那么系统就接受请求去检查缓存,是否能够被命中。建议使用GET和HEAD。
25.10 proxy_hide_header field
proxy_hide_header field;
By default, nginx does not pass the header fields "Date", "Server", "X-Pad", and "X-Accel-..." from the response of a proxied server to a client. The proxy_hide_header directive sets additional fields that will not be passed.指明要隐藏的header;默认nginx是不传递header的。
25.11 proxy_connect_timeout
proxy_connect_timeout time;
Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds;
定义了用于建立与代理服务器连接超时。需要注意的是,这个超时通常不能超过75秒;
25.12 反向代理缓存配置示例
(1)定义可用于proxy功能的缓存,只能定义于http上下文中;
vim /etc/nginx/nginx.conf
定义缓存路径:/var/cache/nginx/proxy_cache
定义缓存级别:1:1:1
max_size:目录一共用多大空间来缓存缓存项;
keys_zone:定义内存空间;
在/var/cache/nginx/创建proxy_cache目录;
(2)定义在需要调用缓存功能的配置段,例如对图片定义缓存功能;
vim /etc/nginx/conf.d/default.conf
(3)检查nginx的语法是否有错,并重载nginx服务;在浏览器中访问该图片,并多刷新几次;然后查看/var/cache/nginx/proxy_cache目录中是否有多级目录生成并且也有了缓存;
然后通过缓存项中的文件大小跟后端服务器图片的大小做对比,发现大小一样,证明缓存成功了;
也可以用专门的测试工具来测试在缓存之前和缓存之后他们在时间上的差距;
二十六ngx_http_headers_module
The ngx_http_headers_module module allows adding the "Expires" and "Cache-Control" header fields, and arbitrary fields, to a response header.在响应给客户端的响应报文中,去修改指定首部的值或添加自定义首部。
向由代理服务器响应给客户端的响应报文添加自定义首部,或修改指定首部的值;
26.1 add_header name
add_header name value [always];
添加自定义首部;
eg:
add_header X-Via $server_addr(当前nginx自己服务器的地址);向响应报文中添加首部。
add_header X-Accel $server_name; 谁帮忙加速。
26.2 expires [modifined] time
expires [modified] time; 设定响应报文的过期时长。
expires epoch | max | off;
用于定义Expire或Cache-Control首部的值;
二十七 ngx_http_upstream_module
The ngx_http_upstream_module module is used to define groups of servers that can be referenced by the proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, and memcached_pass directives.
将后端服务器定义成服务器组,就可以有前端一直使用的proxy_pass, fastcgi_pass,uwsgi_pass,scgi_pass所调用了。
将服务器归并成组后,可以为该服务器组定义调度方法,从而完成能够将多台服务器在面向前端的代理服务器请求时,可以以负载均衡的方式进行响应。
27.1 upstream
upstream name { ... }
定义后端服务器组,会引入一个新的上下文;
各名称不能同名,最好使用字母。
upstream httpdsrvs {
server ...
server...
...
}
Syntax: check interval=milliseconds [fall=count] [rise=count] [timeout=milliseconds] [default_down=true|false] [type=tcp|http|ssl_hello|mysql|ajp] [port=check_port]
Default: 如果没有配置参数,默认值是:interval=30000 fall=5 rise=2 timeout=1000 default_down=true type=tcp
Context: upstream
- interval:向后端发送的健康检查包的间隔。
- fall(fall_count): 如果连续失败次数达到fall_count,服务器就被认为是down。
- rise(rise_count): 如果连续成功次数达到rise_count,服务器就被认为是up。
- timeout: 后端健康请求的超时时间。
- default_down: 设定初始时服务器的状态,如果是true,就说明默认是down的,如果是false,就是up的。默认值是true,也就是一开始服务器认为是不可用,要等健康检查包达到一定成功次数以后才会被认为是健康的。
- type:健康检查包的类型,现在支持以下多种类型
- tcp:简单的tcp连接,如果连接成功,就说明后端正常。
- ssl_hello:发送一个初始的SSL hello包并接受服务器的SSL hello包。
- http:发送HTTP请求,通过后端的回复包的状态来判断后端是否存活。
- mysql: 向mysql服务器连接,通过接收服务器的greeting包来判断后端是否存活。
- ajp:向后端发送AJP协议的Cping包,通过接收Cpong包来判断后端是否存活。
- port: 指定后端服务器的检查端口。你可以指定不同于真实服务的后端服务器的端口,比如后端提供的是443端口的应用,你可以去检查80端口的状态来判断后端健康状况。默认是0,表示跟后端server提供真实服务的端口一样。该选项出现于Tengine-1.4.0。
27.2 server address
server address [parameters]; 指明服务器地址和参数
在upstream上下文中server成员,以及相关的参数;
Context: upstream
address的表示格式:
unix:/PATH/TO/SOME_SOCK_FILE(套接字文件)但是要确保这个web服务器一定得是当前反代服务器上的web服务才行,因为socket文件只能完成本地通信;
IP[:PORT] port可省略;
HOSTNAME[:PORT]
parameters(参数):
weight=number 权重,默认为1;
max_fails=number 失败尝试最大次数;超出此处指定的次数时,server将被标记为不可用;
能够为各server的健康状态做检测。
fail_timeout=time设置将服务器标记为不可用状态的超时时长;这是一个累计时长,不是单个尝试失败时长;
max_conns 当前的服务器的最大并发连接数;
backup 将服务器标记为"备用",即所有服务器均不可用时此服务器才启用;
down 标记为"不可用";这时候被标记为down的web服务就不会被调用;
27.3 least_conn
least_conn;
最少连接调度算法,当server拥有不同的权重时其为wlc(最少连接);一般取决于后端服务器长连接时才有意义。
27.4 ip_hash
ip_hash;
源地址hash调度方法;
将来自于同一个地址的请求始终发往同一个后端服务器。
27.5 hash key
hash key [consistent(一致性哈希算法)];
基于指定的key的hash表来实现对请求的调度,此处的key可以是直接文本、变量或二者的组合;我们可以根据用户的浏览器来调度,比如用户浏览器是chrom,我们可以做一个哈希算法,将同一个浏览器的请求调度至同一台服务器,而其他浏览器则有可能调度到其他服务器;根据请求报文中所隐含的字串来完成哈希计算,随后实现将某一类的请求都调度之同一台服务器。
作用:将请求分类,同一类请求将发往同一个upstream server;
把对同一个url的请求,不管是来自哪台主机,都将发往upstream server;
If the consistent parameter is specified the ketama consistent hashing method will be used instead.
示例:
hash $request_uri ; 把用户请求的uri做哈希计算,不同的url请求被调度至不同的主机;
hash $remote_addr; 表示将来自于同一个ip地址的请求将始终被发送给同一个后端主机;
27.6 keepalive connections
keepalive connections; 定义反向代理与后端服务器之间的连接。
为每个worker进程保留的空闲的长连接数量;
27.7 负载均衡配置示例
(1)示例图
根据上图所示,准备3台主机,分别部署nginx服务和http服务;
(2)在http上下文中定义服务器组实现基于nginx的负载均衡
vim /etc/nginx/nginx.conf
(3)在/etc/nginx/conf.d/defautl.conf配置文件中定义后端引用;
(4)在后端主机定义测试页,实际情况下两台后端主机所提供的服务内容是一样的,为了体现出效果,则在做测试页的时候将里面的内容做一个区分;
(5)测试效果
这么测试效果明显,好截图保存;也可以用浏览器测试,一直点刷新的时候会发现浏览器内容在不断的切换;
(6)测试权重和最大失败尝试次数;
测试:
(7)测试backup功能
将服务器标记为"备用",即所有服务器均不可用时此服务器才启用;
可以将100.2主机和100.4主机上的http服务关掉,然后再请求资源,当nginx找不到100.2和100.4后会直接将请求发送到备用的100.11主机上;注意:只有当100.2和100.4主机同时down时,备用主机才会生效;
(8)测试hash key
分别在后端主机server1和server2上创建10个名称相同内容不同的网页,用来测试是来自主机1还是主机2;
for i in {0..9}; do echo "test page $i on server 1" > test$i.html;done
for i in {0..9}; do echo "test page $i on server 2" > test$i.html;done
基于uri的哈希:
测试结果:
基于ip地址的哈希
测试结果:
二十八 ngx_stream_core_module
ngx_stream_core_module模块 在nginx1.9.0中才有此功能
模拟反代基于tcp或udp的服务连接,即工作于传输层的反代或调度器;
http://nginx.org/en/docs/stream/ngx_stream_core_module.html
28.1 stream
stream { ... }
定义stream相关的服务;
Context:main
配置示例:
stream模块跟http模块是同等级的,所以需要先将/etc/nginx/conf.d/default.conf配置文件做一个备份,不要以".conf"后缀结尾;删除在conf.d下的其他配置文件。然后将/etc/nginx/nginx.conf配置文件中的http上下文注释掉,只留一个"include /etc/nginx/conf.d/*.conf;"因为还需要nginx.conf文件去conf.d下面去加载文件;这些操作不做在nginx检查语法错误的时候会报错;
然后在/etc/nginx/conf.d下创建ssh.conf文件;
在检查nginx语法错误没有问题后,重载nginx服务;查看nginx是否监听到了22022端口;
然后再重新找一台主机通过ssh –p22022 root@10.0.1.6去连接后端主机;
如上图所示,通过10.0.1.6主机的22022端口连接到了100.2这台后端主机;
如果不指定权重,则默认是轮询的方式,所以当我们退出来再次连接的时候就会连接到100.4这台主机上了;
28.2 listen
listen address:port [ssl] [udp] [proxy_protocol] [backlog=number] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
用来指明server将打算代替监听在哪一个地址或端口上向外提供服务;
思考:
(1) 动态资源存储一组服务器、图片资源存在一组服务器、静态的文本类资源存储在一组服务器;如何分别调度?
(2) 动态资源基于fastcgi或http协议(ap)?
lnamp