Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler(俄文:Рамблер)使用。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:京东、新浪、网易、腾讯、淘宝等。
一、event模型
传统的基于进程和线程的模型在处理并发连接的时候针对每个连接会调用一个独立的进程或线程,并且阻塞在网络或I/O操作上面。根据应用程序的不同,它们对内存和CPU的使用效率非常低。产生一个新的进程或线程需要一个新的运行时环境,包括堆和栈的分配,以及运行时的上下文。因此需要额外的CPU开销来创建这些环境,过多的线程以及上下文切换最终会导致性能的下降。所有这些状况在Apache上都可以见到。因此,这是一个在提供丰富普遍适用的功能特性以及服务器资源优化之间的权衡。
event模型处理时内部不启动线程为每个连接创建独立的处理逻辑,而是内部一个完整的处理逻辑来处理所有或大多数发给它的请求,进程内部基于事件等机制完成请求的处理。好处就是,不用单独找一个独立的处理逻辑,当一个请求如果处理时间需要等待的话比如IO时,仅仅把这个请求在内存空间地方把状态记下来就行了,一旦完成了,通知进程,进程继续暂存的任务就可以了。
二、Nginx软件架构
Nginx的架构如下所示:
Nginx分为Master/Worker两级结构,Master进程负责加载配置文件,创建,绑定并关闭套接字启动子进程,开始、终止保持配置中的worker进程数目;在线升级更新配置,日志文件更替;Worker进程负责处理客户端的请求,提供和性功能,反代,负载均衡等绝大多数功能;缓存加载进程负责检测磁盘上的缓存项并填充Nginx内存数据库。本质上缓存加载进程替Nginx提供一个存储在磁盘上的目录结构中的文件实例。需要使用时,它遍历目录,检查缓存元数据,更新共享内存中的相关条目,准备好一切。退出是一切全部清理。
缓存管理器主要负载缓存过期和失效,Nginx操作的时候驻留在内存中,失败了由Master启动。
Nginx 架构中分为核心模块和第三方模块,核心模块负责维持运行环和在每个请求处理阶段执行执行适当模块代码,第三方模块提供如负载均衡,地址重写的功能,应用功能。Nginx的模块架构允许开发者在无需要改动Nginx核心的情况下扩展web服务器的特性。
Nginx使用量了event模型和异步IO机制,多请求京城处理和对于专门硬件的加速IO过程,加速了向相应处理过程,能够轻松处理数以万计的请求。
三、nginx安装
Nginx位于epel源中,也可以使用官方的YUM 源安装它,目前还有很多它的二次开发版,比较有名的有tengine, OpenResty。
编译安装时,可以依据以下选项:
yum -y groupinstall "Development Tools" "Server Platform Development" yum -y install openssl-devel zlib-devel pcre-devel tar xf nginx.tar.gz ./configure --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --user=nginx --group=nginx --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-debug useradd -r nginx export PATH=/usr/local/nginx/sbin/:$PATH nginx -t # 测试nginx 配置, nginx # 启动nginx nginx -s stop|reload cp /root/nginx-1.8.1/man/nginx.8 /usr/share/man/man8 # 这样日常使用基本就可以了。
主配置文件:/etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf
配置文件结构:
main block:设置全局配置,对其他部分完全有效;
event:事件驱动配置,存在于main block上下文;
http:http协议配置段;
mail:mail协议配置段;
配置命令规范;
directive value1 [value2 ...];
一个简化的配置:
... # main block event{ ... }# 事件配置段 http { ... ;http公用配置 server { ... server_name root alias location /uri/ { } ... } server { ... } }
四、详细配置
全局参数
1.worker_rlimit_nofile #;
指定worker进程能都打开的最大文件描述符数量,影响单个worker进程所能处理的请求数;修改方法见后面的博文
2.worker_processes #;
指定worker进程的个数,应该根据CPU的核心数确定:每个CPU一个worker,为了阻止了线程竞争和锁死应该绑定worker进程到指定CPU上
3.worker_cpu_affinity CPUMASK CPUMASK
绑定worker进程到CPU核心,CPUMASK可以为二进制掩码,
示例:
[[email protected]_143 ~]# lscpu ... CPU(s): 2 On-line CPU(s) list: 0,1
这里设置woker进程数为2,绑定两个worker到两个CPU上,可以用如下方式:
worker_processes 2; worker_cpu_affinity 10 01
此时查看进程可以看到:
# ps axo user,comm,pid,psr|grep nginx root nginx 1607 1 nginx nginx 1867 1 nginx nginx 1868 0
4.worker_priority NICE; 调整进程的nice值;
NICE=[-20,19], 用户空间有限级范围100-139,默认20,可以通过该参宿调整worker进程的优先级;
worker_prority 20
# ps axo user,comm,pid,psr|grep nginx root nginx 1607 1 nginx nginx 1867 1 nginx nginx 1868 0
event 事件参数
5.woker_connections #;
指定单个worker进程所能够相应的最大并发请求数;实际影响了进程的并发量,必须调整。默认1024。
6.accept_mutex [on|off] ;
设置worker进程之间的负载均衡锁;表示用于让多个worker轮流地、序列化地响应新请求;应该打开。
7.lock_file PATH
指定互斥锁的位置。
http 配置
8.server{}
定义新的server上下文,定义于http上下文中,其上下文结构如下:
server { listen PORT; server_name NAME; root /PATH/TO/DOCUMENTROOT; }
多个server可以根据端口,域名,或IP的虚拟主机:
9.listen
listen address[:port] [default_server] [ssl] [backlog=number][rcvbuf=size][sndbuf=size];
listen port [default_server] [ssl] [ssl];
listen unix:path [default_server] [ssl] [ssl];
server参数:
default_server:设置该虚拟主机为默认虚拟主机,默认虚拟主机主要用于基于IP或匹配不到的虚拟主机名访问时,default_server负责响应。
backlog:后援队列长度,等待响应的队列长度。
10.server_name NAME ...;
设定web服务器主机名;名称支持通配符和“~”起始的正则表达式;多个匹配的优先级;
(1) 首先做精确匹配;例如:www.magedu.com
(2) 左侧通配符;例如:*.magedu.com
(3) 右侧通配符,例如:www.magedu.*
(4) 正则表达式,例如:~^.*\.magedu\.com$
(5) default_server
worker_processes 2; worker_cpu_affinity 0010 0001; worker_priority 19; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; server { listen 172.18.29.142:80; server_name www.magedu.com; root /data/webs/v1; location / { index index.html; } } server { listen 172.18.29.142:80; server_name *.magedu.com; root /data/webs/v2; location / { index index.html; } } server { listen 172.18.29.142:80; server_name www.magedu.*; root /data/webs/v3; location / { index index.html; } } server { listen 172.18.29.142:80; server_name ~^.*w.magedu.*; root /data/webs/v4; location / { index index.html; } } server { listen 172.18.29.142:80 default_server ; server_name bbs.magedu.com; root /data/webs/v5; location / { index index.html; } } }
创建root网页资源映射位置:
mkdir /data/webs/v{1..4} # for i in {1..4};do echo "index.html @ server$i" > /data/webs/v$i/index.html ;done ;
修改域名解析:
172.18.29.142 www.magedu.com 172.18.29.142 www.godean.com
此时一次注掉虚拟主机server 1-3,访问http://www.magedu.com/index.html,可以看到各个虚拟主机依次被匹配到;当访问http://www.godean.conf/index.html或用http://172.18.29.142/index.html可以看到"[email protected]",因为该虚拟主机为默认虚拟主机。
11.sendfile on|off;
在内核中直接将报文封装发送给用户,是Nginx的重要特性,这里要开启。
12.tcp_nodelay on|off;
对keepalive模式下的连接是否使用TCP_NODELAY选项;启用该选项时,在keepalive连接中会将小段数据攒到一块在发送,可能会造成小请求的延迟,视情况而定。
路径相关命令
13.root PATH;
可应用于http,server,location上下文中,指定映射到文件系统资源路径;多次指定以最近一次指定为准。
14.location
可用于上下文:server/localtion
允许根据用户请求的URI来匹配定义的各location,匹配到时,此请求将被相应的location块中的配置所处理(如为.txt结尾文件做压缩);简言之,即用于为需要用到专用配置的uri提供特定配置;
server { listen 172.18.29.142:80; server_name www.magedu.com; root /data/webs/v1; index index.html; location / { index index.html; } location /admin { root /data/webs/v1; gzip on; } }
建立对应的资源,就可看到如下图的gzip压缩的显示:
15.alias
用于上下文:localtion,只能用于location配置段,定义路径别名;可以和root比较:
对于两个相似配置:
location /bbs/ { root /web/; } location /bbs/ { alias /web/; }
前者的真实资源文件位置为:/web/bbs/,后者的真实资源文件位置为:/web/
root指令:给定的路径右侧“/”对应于locationURL右侧斜线;
/images/test.jpg --> /data/imgs/images/test.jpg
alias指令:给定的路径右侧“/”对应于locationURL左侧斜线;
/images/test.jpg --> /data/imgs/test.jpg
16.error_page
可用上下文:http,server,location,指定error page 的位置;
error_page 404 /404.html; # 可以定义 ... .... location =/404.html{ root /use/share/nginx/html; }
17.open_file_cache 对打开的文件缓存
open_file_cache off;
open_file_cache max=N [inactive=time];
nginx可以缓存以下三种信息:都是元数据
(1) 文件描述符、文件大小和最近一次的修改时间;
(2) 打开的目录的结构;
(3) 没有找到的或者没有权限操作的文件的相关信息;
max=N表示可缓存的最大条目上限;一旦达到上限,则会使用LRU算法从缓存中删除最近最少使用的缓存项
inactive=time:在此处指定的时长内没有被访问过的缓存项是为非活动缓存项,因此直接删除;
18.open_file_cache_errors on | off;
是否缓存找不到其路径的文件,或没有权限访问的文件相关信息;
19.open_file_cache_valid
open_file_cache_valid time;
每隔多久检查一次缓存中缓存项的有效性;默认为60s;
20.open_file_cache_min_uses
open_file_cache_min_uses number;
在open_file_cache指令inactive参数指定时长內至少命中指定次数,方可归类为非活动项目。
21.allow address
ngx_http_access_module模块的配置(基于IP的访问控制)
实现客户端IP的访问控制
allow address | CIDR | unix: | all;
addrss;IPv4地址
CIDR: 172.18.0.0/16
all:表示所有地址
22、deny address
应用上下文:http, server, location, limit_except
deny address | CIDR | unix: |
23.stub_status
通过指定的uri输出nginx的基本信息(stub status);
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 /status { stub_status on; } # curl http://172.18.29.142/status Active connections: 1 server accepts handled requests 73 73 146 Reading: 0 Writing: 1 Waiting: 0
24.valid_referers
可应用于上下文:server、location,指定合法的引用,合法引用就是跳转之前的页面,该设定可以用来防盗链。
valid_referers none | blocked | server_names | string ...;
none:请求报文不存在referer首部;
blocked:请求报文中存在referer首部,但其没有有效值,或其值非以http://或https://开头;
server_names:其值为一个主机名;
arbitrary string:直接字符串,可以使用*通配符的字符串;
regular expression:以~起始的正则表达式匹配的字符串;
内置变量:$invalid_referer(所有不能符合valid_referer指定定义的引用请求均为不合法引用)
示例:这只除了blocked example.* www.example.org/galleries/ ~\.google\. 以外都是非法引用,不允许其访问。
valid_referers blocked example.* www.example.org/galleries/ ~\.google\.; if ($invalid_referer) { return 403; } location / { root /data/webs/vhost1; index index.html; valid_referers blocked server_names *.example.com; if ($invalid_referer){ return 403; } } # curl http://172.18.29.142/ <html> <head><title>403 Forbidden</title><head> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.0.15</center> </body> </html>
报文的引用者引用变量 $invalid_referer,此时的请求是referer为none,那么返回403。
ngx_http_ssl_module 模块配置
25.ssl [on|off];
应用上下文:http, server
是否启用当前虚拟主机的ssl功能;
26.ssl_certificate file;
应用上下文:http, server
当前虚拟主机使用的PEM格式的证书文件;
ssl_certificate_key file;
应用上下文:http, server
当前虚拟主机使用的PEM格式的私钥文件;
# 自建CA cd /etc/pki/CA openssl genrsa -out private/ca.pem 2048 openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/certs/cacert.pem -days 365 touch {serial,index.txt} echo 01 > serial # 生成认证请求 mkdir /etc/nginx/ssl cd /etc/nginx/ssl openssl genrsa -out ./nginx.priv 2048 openssl req -new -key nginx.privat -out /opt/nginx.csr -days 365 # CA签署证书,并发放证书 openssl ca -in /opt/nginx.csr -out certs/nginx.crt -days 365 # 配置nginx.cinf文件,建立https虚拟主机 server { listen 172.18.29.142:443 ssl ; server_name www.magedu.com; root /data/webs/v2; ssl on; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.priv; location / { } }
The ngx_http_log_module 模块将请求日志按照格式写入日志中
27.access_log path [format [buffer=size [flush=time]] [if=condition]];
access_log path format gzip[=level] [buffer=size] [flush=time] [if=condition];
access_log syslog:server=address[,parameter=value] [format [if=condition]];
access_log off;
设定对http,server,location设置各自的日志位置,如果需要缓存(buffer)那么需要设定刷新到文件的时间。
默认日志格式:access_log logs/access.log combined;
可应用于上下文:http, server, location, if in location, limit_except
access_log /var/log/nginx/access.log combined buffer=5m flush=1h ;
28.log_format name string ...;
log_format name string ...;
默认值:log_format combined "...";
可应用于上下文:http
29.open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
默认:open_log_file_cache off;
可应用于上下文:http, server, location
max:最大缓存条目;
inactive=time:非活动时长;
min_uses:最少使用次数;
valid:验正缓存条目有效性的频率;
open_log_file_cache max=10 inactive=20s min_uses=1 valid=1m;
说明:max为缓存最大条目数,如果达到max数值,那么从中根据LRU算法踢出;inactive为缓存条目多长时间没有达到min_uses的值,那么就踢出;min_uses缓存最少访问次数;valid为文件缓存后查询文件的有效性间隔时长。
ngx_http_rewrite_module模块配置
用户访问通过服务器名称,指定到某个servername,再根据localtion定位映射文件位置,设定location的属性,其中配置rewrite指令。
30.rewrite regex replacement [flag];
可用于上下文:server, location, if
1.把用户请求的URI基于regex做检查,匹配到时将替换为replacement指定的字符串;
2.在同一个location中存在的多个rewrite规则会自上而下逐个被检查(内生的循环机制);可以使用flag控制此循环功能,循环最多10次,否则返回500服务器端错误;
3.如果replacement是以http://或https://开头,则替换结果会直接以重定向方式返回给客户端;
http --> https, domain1.tld --> domain2.tld, uri1 --> uri2, ...
regex:正则表达式,用于匹配用户请求的url;
replacement:重写为的结果;
[flag]:
last:重写完成后停止对当前uri在当前location中的后续其它重写操作,改为对新uri的新一轮处理;
break:重写完成后停止对当前uri在当前location中的后续其它重写操作;
redirect:重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户对新URL进行请求;(302)
permanent:重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户对新URL进行请求;(301)
关于flag的示例:
访问:http://www.magedu.com/index.txt 存在文件: # cat /data/webs/vhost1/index.html index.html # cat /data/webs/vhost1/admin/index.html admin index.html # cat /data/webs/vhost1/admin/index.txt admin index.txt location / { root /data/webs/vhost1; index index.html; rewrite /(.*)\.txt /admin/$1.txt break; rewrite /admin/(.*)\.txt /admin/$1.html; } location /admin { root /data/webs/vhost1; rewrite /admin/(.*)\.txt /$1.html; } 如果break所在位置替换为空,那么请求响应为:admin index.html;如果break所在位置替换为last,那么请求响应为:index.html;如果break所在位置替换为break,那么请求响应为:admin index.txt;
ngx_http_gzip_module模块配置
过滤器,对指定类型的资源压缩传输以节约带宽,但是可能增加CPU负载;
zip on | off;
启用或禁用gzip压缩响应报文;
gzip_comp_level level;
压缩比,1-9,默认为1;
gzip_disable regex ...;
regex是匹配客户端浏览器类型的模式,表示对所有匹配到的浏览器不执行压缩响应;
gzip_min_length length;
触发压缩功能的响应报文的最小长度;
gzip_http_version 1.0 | 1.1;
设定启用压缩功能时,协议的最小版本;
gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;
定义对客户端请求的具有何种请求属性的资源启用压缩功能;如expired则表示对由于使用了expired首部而无法缓存的对象启用压缩功能;
gzip_types mime-type ...;
指明仅对哪些类型的资源执行压缩操作;即压缩过滤器;
示例:
gzip on; gzip_http_version 1.0; gzip_comp_level 6; gzip_disable msie6; gzip_min_length 2; gzip_types text/plain text/css text/xml application/x-javascript application/xml application/json application/java-script;
基础配置就到这里,下篇博文介绍Nginx的反向代理。如有不到的地方,请各位指教。