Nginx简介
Nginx(发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师IgorSysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler(俄文:Рамблер)使用。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页伺服器中表现较好.目前中国大陆使用nginx网站用户有:新浪、网易、腾讯,另外知名的微网志Plurk也使用nginx
nginx可以作为一个反向代理服务器,用户请求经过它(其实这里用户请求到这里已经终止),判断静态页面或动态页面后再送往后方相应的服务器(nginx要另外启用一个进程到后方服务器取内容),服务器得到请求,响应,返回给nginx,nginx会重新封装首部,缓存后再返回给客户端(nginx又重新启用一个进程发送结果给客户端了)。
所以Nginx的实际并发能力,要除以2,因为它既要处理用户的请求,又要重新构建新的请求。它在反向代理的情况下,处理能力是有限的。
注意:这里的缓存,是把url做hash,存储为key,因为hash可以保证唯一并且长度很小。响应的内容存储为value
Nginx安装
详细过程参考http://dengxi.blog.51cto.com/4804263/1710472
Nginx的配置文件
配置文件位于 /etc/nginx/nginx.conf
1、配置文件的结构
....
events
{
....
}
http
{
....
server
{
location{}
....
}
server
{
location {}
....
}
}
2、正常运行的必备配置
(1)、user username [groupname];
指定运行worker进程的用户和组
例:user nginx nginx;
(2)、pid /path/to/pidfile_name;
指定nginx的pid文件
(3)、worker_rlimit_nofile #;
指定一个worker进程所能够打开的最大文件句柄数;要等于或略大于worker_connections的值,因为还要打开其他文件
例: worker_rlimit_nofile 51200;
(4)、worker_rlimit_sigpending #;
设定每个用户能够发往worker进程的信号的数量;
(5)、events {
use epoll;
worker_connections 51200;
}
使用的网络I/O模型,Linux系统推荐采用epoll模型,FreeBSD系统推荐采用kqueue模型
3、优化性能相关的配置
(1)、worker_processes 6;此项很关键!
worker进程的个数,通常其数值应该为CPU的物理核心数减一
(2)、worker_cpu affinity cpumask ...; 此项很关键!
例:
worker_processes6; 初始产生的worker进程个数,6个进程,把6个进程分别绑定在以下任意一个内核上(例如CPU一共有8个内
核,nginx的进程只运行在这6个上面)
worker_cpu_affinity00000001 00000010 00000100 00001000 00010000 00100000
(3)、ssl_engine device;
ssl硬件加速器,由于https链接所消耗的资源比http大得多,可能要多消耗5、6倍,所以有专门处理ssl的硬件设备
(4)、timer_resolution t; 此项很关键!
每次内核事件调用返回时,都会使用gettimeofday()来更新nginx缓存时钟,time_resolution用于定义每隔多久才会
由gettimeofday()更新一次。因为每次调用返回都更新的话太消耗资源。不过目前x86-64系统上,gettimeofday()花费时间已经很
小,可以忽略
(5)、worker_priority nice;
用于定义worker的优先级,-20至19,这项对系统性能提升很大,但值不要太小了。此项很关键
4、事件相关
(1)、accept_mutex [on|off] 默认打开
是否打开Nginx的负载均衡锁,此锁能够让多个worker进程轮流的、序列化地与新的客户端建立连接。而通常一个worker进程的负
载达到其上限的7/8,master就尽可能不再将请求调度至此worker
(2)、lock_file /path/to/lock_file;
(3)、accept_mutex_delay #ms; 默认500ms
accept锁模式中,一个worker进程为取得accept锁的等待时长。如果某worker进程在某次视图取得锁时失败了,至少要等待#ms才
能再一次请求锁。详细看“Nginx的accept_mutex配置分析”
(4)、multi_accept on |off 默认off
是否允许一次性响应多个用户请求。当一批用户请求进来时,是否让一个worker响应所有请求。允许的话效率有提高
(5)、use [epoll|rtsig|select|poll]
定义使用的事件模型,建议让nginx自动选择。Linux一般会选poll
(6)、 worker_connections #;
每个worker能够并发响应最大请求数。但要注意,系统每处理一个请求就要消耗一个套接字文件。做反向代理的时候要把
worker_rlimit_nofile的值X2。
5、用于调试的配置
用于调试、定位问题,只在调试nginx时使用:
(1)、daemon [on|off]
是否让nginx运行在后台:默认为on,调试时可以设置为off,使得所有信息直接输出控制台、屏幕
(2)、master_process on|off
是否以master/worker模式运行nginx,默认on;调试时可以设置off,只运行一个worker进程。
(3)、error_log/path/to/error_log level; 默认error级别
错误日志文件及级别。调试可使用debug级别.但要求编译时必须--with-debug 启用debug功能
6、虚拟主机的配置
使用虚拟机来配置站点,每个虚拟主机使用一个server{}段,非虚拟主机的配置或公共配置,需要定义在server{}之外,http{}之内
(1)基于IP及端口的虚拟主机
一段server{...}就是一个虚拟主机,要基于端口,只要把端口改为相应的即可
http
{
#第一个虚拟主机
server
{
#监听的ip和端口
listen 192.168.61.141:80;
#主机名称
server_name 192.168.61.141;
#访问日志文件存放路径
access_log logs/server1.access.log combined;
location/
{
#默认首页文件,顺序从左到右
index index.html index.htm;
#HTML网页文件的存放目录
root /web/server1;
}
}
#第二个虚拟主机
server
{
#监听的ip和端口
listen 192.168.61.141:80;
#主机名称
server_name 192.168.61.141;
#访问日志文件存放路径
access_log logs/server2.access.log combined;
location/
{
#默认首页文件,顺序从左到右
index index.html index.htm;
#HTML网页文件的存放目录
root /web/server2;
}
}
}
(2)基于域名的虚拟主机
注意写法*.a.com 除www.a.com之外的所有*.a.com二级域名的访问都由它来处理
http
{
#第一个虚拟主机
server
{
#监听的ip和端口
listen 80;
#主机名称
server_name www.a.com *.a.com;
#访问日志文件存放路径
access_log logs/server1.access.log combined;
location/
{
#默认首页文件,顺序从左到右
index index.html index.htm;
#HTML网页文件的存放目录
root /web/server1;
}
}
#第二个虚拟主机
server
{
#监听的ip和端口
listen 80;
#主机名称
server_name www.b.com *.b.com;
#访问日志文件存放路径
access_log logs/server2.access.log combined;
location/
{
#默认首页文件,顺序从左到右
index index.html index.htm;
#HTML网页文件的存放目录
root /web/server2
}
}
}
(3)参数详细说明
(a)、listen
listen地址[:端口]
常用参数
default_server:定义此server为http中默认的server.如果所有的server都没有使用listen参数,那么第一个server即为默认
server
rcvbuf=size:接受缓冲大小
sndbuf=size:发送缓冲大小
ssl:是否https 服务
(b)、server_name
设定主机名,可以跟多个。名称中可以使用通配符和正则表达式。当nginx收到一个请求时,会取出其首部的server的值,跟众
多server_name进行比较,方式:
(1)先做精确匹配 www.dx.com
(2)左侧通配符匹配 *.dx.com
(3)右侧通配符匹配 www.*
(4)正则表达式匹配 ~^.*\.dx\.com$
(c)、server_name_hash_bucket_size 有32|64|128
为了实现快速主机查找,nginx使用hash表来保存主机名
(d)、location [=|~|~*|^~] uri { ... }
location @name { ... }
功能:允许根据用户请求的URI来匹配指定的各location以进行访问配置;匹配到时,将被location块中的配置所处理
=:精确匹配
~:正则表达式模式匹配,匹配时区分字符大小写
~*:正则表达式模式匹配,匹配时忽略字符大小写
^~:只需要前半部分与uri匹配即可,左侧匹配,不检查正则表达式
匹配优先级:
字符字面量最精确匹配、正则表达式检索(由多个时,由第一个匹配到的所处理),按字符字面量
(e)、文件路径定义
1、root path
设置web资源路径,用于指定请求的根文档目录,从跟开始匹配
root:root/URI
2、alias path
指定路径别名,只能用于location中,从最后一个/开始匹配
alias:alias/
3、index file....
定义默认页面,可以跟多个值。自左向右匹配
4、error_page code ... [=[response]] uri
当对于某个请求发回错误时,如果匹配上了error_page指令中设定的code,则从定向至新的新URI中错误重定向
5、try_files path1 [path2...] uri;
自左向右尝试读取由path所指定路径,在第一找到即停止并返回,如果所有path均不存在,则返回最后一个uri
例:
location~* ^/document/(.*)${
root/www/htdocs
try_files$uri /docu/$1 /temp.html
}
http://www.wangfeng7399.com/documents/a.html
http://www.wangfeng7399.com/docu/a.html
http://www.wangfeng7399.com/temp.html
7、网络连接相关的设置
(1)、keepalive_timeouttime;
保持连接的超时时长,默认为65s
(2)、keepalive_requests n
在一次长连接上允许承载的最大请求数
(3)、keepalive_disable[msie6|safari |none]
对指定的浏览器禁止使用长连接
(4)、tcp_nodelay on|off
对keepalive连接是否使用tcp_nodelay选项
(5)、client_header_timeouttime
读取http请求首部的超时时长
(6)、client_body_timeouttime
读取http请求包体的超时时间
(7)、save_timeout time
发送响应的超时时长
8、对客户端请求的限制
(1)、limit_except method...{ ... }
指定范围之外的其他方法的访问控制,只能用于location中
(2)、client_max_body_size 20m
客户端http请求包体的最大值,常用于限定客户端所能够请求的最大包体。根据请求首部中的Content-Length来检查,以避免无
用的传输。
例如:
网站上限定了用户最大上传文件为1G,如果不设置这个参数做限制,那么当用户已经上传了1G后,网站程序才能发现不能给它上
传了,已经浪费了前面的时间和资源了。这里可以提前从heart头部读取到要传送的文件的大小,提前拒绝不必要的上传!
(3)、client_max_body_buffer_size 256k
请求包体内存缓存区大小,为什么这个值这么小呢?可以想象一下如果有10000个并发会占用多少内存?所以,如果超过这个大
小会存在client_body_temp_path 磁盘上
(4)、limit_rate speed
限制客户端每秒传输的字节数,默认为0,表示没有限制
(5)、limit_rate_after time
nginx向客户端发送响应报文时,如果时长超过了此处指定的时长,则后续的发送过程开始限速
例如:一个下载网站,很多用户在下载,当传送了一定时间,占用了不少带宽,为避免对其他用户的影响,开始根据limit_rate
限速了
9、对客户端请求的特殊处理
(1)、ignore_invalid_headerson|off
是否忽略不合法的http首部,默认为on,off意味着请求首部中出现不合规的首部将拒绝响应,只能用于server和http
(2)、log_not_found on|off
用户访问的文件不存在时,是否将其记录到错误日志中
(3)、resolver address:
指定nginx使用的dns服务器地址
(4)、resolve timeout
指定DNS解析超时时长,默认为30s
(5)、server_tokens on|off
是否在错误页面中显示nginx的版本号,为了安全,一般都要关闭
10、文件操作的优化
(1)、sendfile on|off
是否启用sendfile功能
(2)、aio on|off
是否启用aio功能
(3)、open_file_cache man=N[incative=time]|off
是否打开文件缓存功能
max:用于缓存条目的最大值,允许打开的缓存条目最大数,当满两类以后将根据LRU(最小最少连接数)算法进行置换
inactive:某缓存条目在指定时长内没有被访问过时,将自动被删除;通常默认为60s
缓存的信息包括:
文件句柄、文件大小和上次修改时间
已经打开的目录结构
没有找到或没有访问权限的信息
(4)、open_file_cache_errorson|off
是否缓存文件找不到或没有权限访问等相关信息
(5)、open_file_cache_validtime
多长时间检查一次缓存中的条目是否超出非活动时长,默认为60s
(6)、open_file_cache_min_use#
在inactive指定的时长内被访问超过此处指定的次数时,才不会被删除
(7)、open_log_file_cachemax=1000 inactive=20s min_uses=1 valid=1m;
打开日志缓存,最大条目1000条,非活动时间20秒,最少使用1次,有效时间1分钟
11、http核心模块的内置变量:
$uri:当前请求的uri,不带参数
$request_uri:请求的uri,带完整参数
$host:http请求报文中host首部;如果请求中没有host首部,则以处理此请求的主机的主机名代替
$hostname:nginx服务运行所在主机的主机名
$remote_addr:客户端IP
$remote_port:客户端port
$remote_user:使用用户认证时客户端用户输入的用户名
$request_filename:用户请求中的URI经过本地root或alias转换后映射的本地的文件路径
$request_method:请求方法
$server_addr:服务器地址
$server_name:服务器名称
$server_port:服务器端口
$server_protocol:服务器向客户端发送响应时的协议,如http/1.1,http/1.0
$scheme:在请求中使用的scheme 映射协议本身的协议
$http_HEADER:匹配请求报文中指定的HEADER,$http_host匹配请求报文中的host首部
$sent_http_HEADER:匹配响应报文中指定的HERDER,例如$http_content_type匹配相应报文中的content-type首部
$document_root:当前请求映射到的root配置
12、URL rewrite
nginx通过ngx_http_rewrite_module模块支持url重写、支持if条件判断,但不支持else。
该模块需要PCRE支持,应在编译 nginx 时指定PCRE源码目录
(a)、nginx rewrite指令执行顺序:
(1)、执行server块的rewrite指令(这里的块指的是server关键字后{}包围的区域,其它xx块类似)
(2)、执行location匹配
(3)、执行选定的location中的rewrite指令
如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件
如果循环超过10次,则返回500 Internal ServerError错误
(b)、break指令
语法:break;
默认值:无
作用域:server,location,if
停止执行当前虚拟主机的后续rewrite指令集
break指令实例:
if ($slow) {
limit_rate 10k;
break;
}
(c)、if指令
语法:if(condition){...}
默认值:无
作用域:server,location
对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行。
if条件(conditon)可以是如下任何内容:
一个变量名;false如果这个变量是空字符串或者以0开始的字符串;
使用= ,!= 比较的一个变量和字符串
是用~, ~*与正则表达式匹配的变量,如果这个正则表达式中包含},;则整个表达式需要用" 或' 包围
使用-f ,!-f 检查一个文件是否存在
使用-d, !-d 检查一个目录是否存在
使用-e ,!-e 检查一个文件、目录、符号链接是否存在
使用-x , !-x 检查一个文件是否可执行
if指令实例
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_cookie ~*"id=([^;]+)(?:;|$)") {
set $id $1;
}
if ($request_method = POST) {
return 405;
}
if ($slow) {
limit_rate 10k;
}
if ($invalid_referer) {
return 403;
}
(d)、return指令
语法:
return code;
return code URL;
return URL;
默认值:无
作用域:server,location,if
l 停止处理并返回指定状态码(code)给客户端。
l 非标准状态码444表示关闭连接且不给客户端发响应头。
l 从0.8.42版本起,return 支持响应URL重定向(对于301,302,303,307),或者文本响应(对于其他状态码).
l 对于文本或者URL重定向可以包含变量
(e)、rewrite指令
语法:rewrite regexreplacement [flag];
默认值:无
作用域:server,location,if
l 如果一个URI匹配指定的正则表达式regex,URI就按照replacement重写。
l rewrite按配置文件中出现的顺序执行。flags标志可以停止继续处理。
l 如果replacement以"http://"或"https://"开始,将不再继续处理,这个重定向将返回给客户端。
flag可以是如下参数
last 停止处理后续rewrite指令集,然后对当前重写的新URI在rewrite指令集上重新查找。
break 停止处理后续rewrite指令集,并不在重新查找,但是当前location内剩余非rewrite语句和location外的的
非rewrite语句可以执行。
redirect 如果replacement不是以http:// 或https://开始,返回302临时重定向
permant 返回301永久重定向
最终完整的重定向URL包括请求scheme(http://,https://等),请求的server_name_in_redirect和 port_in_redirec三部分
,说白了也就是http协议 域名 端口三部分组成。
rewrite实例
server {
...
rewrite ^(/download/.*)/media/(.*)..*$$1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)..*$$1/mp3/$2.ra last;
return 403;
...
}
如果这些rewrite放到“/download/” location如下所示, 那么应使用break而不是last , 使用last将循环10次匹配,然后返回
500错误:
location /download/ {
rewrite ^(/download/.*)/media/(.*)..*$$1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)..*$$1/mp3/$2.ra break;
return 403;
}
如果客户端使用IE浏览器,则重定向到/nginx-ie目录下
if ($http_user_agent~ MSIE) {
rewrite ^(.*)$ /nginx-ie/$1 break;
}
禁止访问多个目录:
location ~^/(cron|templates)/ {
deny all;
break;
}
禁止访问以/data开头的文件:
location ~ ^/data {
deny all;
break;
}
禁止访问.sh、.flv、.mp4为文件名后缀的URL地址:
location ~.*\.(sh|flv|mp4)?$ {
return 403;
}
注意:
(1)、在写URI地址的时候,留意.是否要转义字符操作,测试过暂时不用,但老师是写的。
(2)、如果正则表达regex式中包含“}”或“;”, 那么整个表达式需要用双引号或单引号包围.
(3)、如果被替换的URI中含有参数(即类似/app/test.php?id=5之类的URI),默认情况下参数id=5会自动附加到替换串上,如
果不想自动附带后面的参数,可以在replacement后加一个问号。如下,我们加了一个自定义的参数user=$1,然后在结尾
处放了一个问号?,把原请的参数去掉。
例:
rewrite ^/users/(.*)$/show?user=$1? last;
rewrite ^/test(.*)$http://www.test.com/home? permanent; 结果是http://www.test.com/home
(f)、rewrite_log指令
语法:rewrite_log on|off;
默认值:rewrite_log off;
作用域:http,server,location,if
开启或关闭以notice级别打印rewrite处理日志到error log文件。
例:
rewrite_log on;
error_loglogs/xxx.error.log notice;
n 打开rewrite on
n 把error log的级别调整到 notice
转载于:https://blog.51cto.com/dengxi/1747860