nginx基本配置
Nginx安装
Nginx最新安装包可以在Nginx官网上下载http://nginx.org/en/download.html,目前最新版本为http://nginx.org/download/nginx-1.12.2.tar.gz。
tar zxvf nginx-1.12.2.tar.gz cd nginx-1.12.2 ./configure --with-http_ssl_module --with-stream #添加ssl和tcp代理模块 make make install #如果已经安装了nginx,则会对其进行更新
Nginx命令
nginx version: nginx/1.12.2 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: conf/nginx.conf) -g directives : set global directives out of configuration file
配置格式
基本的Nginx配置文件由若干部分组成,每一个部分都是通过下列方法定义的
<section> { <directive> <parameters>; }
导入文件
在Nginx的配置文件中,include文件可以在任何地方,以便增强配置文件的可读性,并且能够使得部分配置文件重新使用。使用include文件,要确保被包含的文件自身有正确的Nginx语法,即配置指令和块。
include /opt/local/etc/nginx/vhost/*.conf
location 语法规则
rewrite 语法规则
rewrite <regex> <replacement> <break,last,redirect,permanent>;
关键字 正则 替代内容 flag标记
server中的rewrite:
在server块下,会优先执行rewrite部分,然后才会去匹配location块 。
在server块下,rewrite break和last没什么区别,都会去匹配location,所以没必要用last再发起新的请求,可以留空。
location中的rewrite:
不写last和break - 那么流程就是依次执行这些rewrite
1. break - url重写后,直接使用当前资源,不再执行location里余下的语句,完成本次请求,地址栏url不变
2. last - url重写后,马上发起一个新的请求,再次进入server块,重试location匹配,超过10次匹配不到报500错误,地址栏url不变
3. redirect – 返回302临时重定向,地址栏显示重定向后的url,爬虫不会更新url(因为是临时)
4. permanent – 返回301永久重定向, 地址栏显示重定向后的url,爬虫更新url
root 和 alias 区别
alias的处理结果是:使用alias路径替换location路径
Nginx内置变量
$args : 这个变量等于请求行中的参数,同$query_string
$content_length : 请求头中的Content-length字段。
$content_type : 请求头中的Content-Type字段。
$document_root : 当前请求在root指令中指定的值。
$host : 请求主机头字段,否则为服务器名称。
$http_user_agent : 客户端agent信息
$http_cookie : 客户端cookie信息
$limit_rate : 这个变量可以限制连接速率。
$request_method : 客户端请求的动作,通常为GET或POST。
$remote_addr : 客户端的IP地址。
$remote_port : 客户端的端口。
$remote_user : 已经经过Auth Basic Module验证的用户名。
$request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme : HTTP方法(如http,https)。
$server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name : 服务器名称。
$server_port : 请求到达服务器的端口号。
$request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri : 与$uri相同。
Nginx配置详解
#运行用户 user nobody; #启动进程,通常设置成和cpu的数量相等 worker_processes 1; #全局错误日志及PID文件 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; #工作模式及连接数上限 events { #epoll是多路复用IO(I/O Multiplexing)中的一种方式, #仅用于linux2.6以上内核,可以大大提高nginx的性能 use epoll; #单个后台worker process进程的最大并发链接数 worker_connections 1024; # 并发总数是 worker_processes 和 worker_connections 的乘积 # 即 max_clients = worker_processes * worker_connections } http { #设定mime类型,类型由mime.type文件定义 include mime.types; default_type application/octet-stream; #设定日志格式 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; sendfile on; #sendfile实际上是 Linux2.0+以后的推出的一个系统调用,web服务器可以通过调整自身的配置来决定是否利用 sendfile这个系统调用。 #先来看一下不用 sendfile的传统网络传输过程: #read(file,tmp_buf, len); #write(socket,tmp_buf, len); #硬盘 >> kernel buffer >> user buffer>> kernel socket buffer >>协议栈 #一般来说一个网络应用是通过读硬盘数据,然后写数据到socket 来完成网络传输的。上面2行用代码解释了这一点,不过上面2行简单的代码掩盖了底层的很多操作,来看看底层是怎么执行上面2行代码的: #1、系统调用 read()产生一个上下文切换:从 user mode 切换到 kernel mode,然后 DMA 执行拷贝,把文件数据从硬盘读到一个 kernel buffer 里。 #2、数据从 kernel buffer拷贝到 user buffer,然后系统调用 read() 返回,这时又产生一个上下文切换:从kernel mode 切换到 user mode。 #3、 系统调用write()产生一个上下文切换:从 user mode切换到 kernel mode,然后把步骤2读到 user buffer的数据拷贝到 kernel buffer(数据第2次拷贝到 kernel buffer),不过这次是个不同的 kernel buffer,这个 buffer和 socket相关联。 #4、系统调用 write()返回,产生一个上下文切换:从 kernel mode 切换到 user mode(第4次切换了),然后 DMA 从 kernel buffer拷贝数据到协议栈(第4次拷贝了)。 #上面4个步骤有4次上下文切换,有4次拷贝,我们发现如果能减少切换次数和拷贝次数将会有效提升性能。 #在kernel2.0+ 版本中,系统调用 sendfile() 就是用来简化上面步骤提升性能的。sendfile() 不但能减少切换次数而且还能减少拷贝次数。 #再来看一下用 sendfile()来进行网络传输的过程: #sendfile(socket,file, len); #硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈 #1、系统调用sendfile()通过 DMA把硬盘数据拷贝到 kernel buffer,然后数据被 kernel直接拷贝到另外一个与 socket相关的 kernel socket buffer。这里没有 user mode和 kernel mode之间的切换,在 kernel中直接完成了从一个 buffer到另一个 buffer的拷贝。 #2、DMA 把数据从 kernelbuffer 直接拷贝给协议栈,没有切换,也不需要数据从 user mode 拷贝到 kernel mode,因为数据就在 kernel 里。 #步骤减少了,切换减少了,拷贝减少了,自然性能就提升了。这就是为http://write.blog.csdn.net/postedit什么说在Nginx 配置文件里打开 sendfile on 选项能提高 web server性能的原因。 #tcp_nodelay on; #你怎么可以强制 socket 发送缓冲区里的数据? #一个解决方案是 sokect 的 TCP_NODELAY 选项。这样就可以使缓冲区中的数据立即发送出去。 #Nginx的 TCP_NODELAY 选项使得在打开一个新的 socket 时增加了TCP_NODELAY选项。 #但这时会造成一种情况: #终端应用程序每产生一次操作就会发送一个包,而典型情况下一个包会拥有一个字节的数据以及40个字节长的包头,于是产生4000%的过载,很轻易地就能令网络发生拥塞。 #为了避免这种情况,TCP堆栈实现了等待数据 0.2秒钟,因此操作后它不会发送一个数据包,而是将这段时间内的数据打成一个大的包。这一机制是由Nagle算法保证。 #Nagle化后来成了一种标准并且立即在因特网上得以实现。它现在已经成为默认配置了,但有些场合下把这一选项关掉也是合乎需要的。现在假设某个应用程序发出了一个请求,希望发送小块数据。我们可以选择立即发送数据或者等待产生更多的数据然后再一次发送两种策略。 #如果我们马上发送数据,那么交互性的以及客户/服务器型的应用程序将极大地受益。如果请求立即发出那么响应时间也会快一些。以上操作可以通过设置套接字的 TCP_NODELAY = on 选项来完成,这样就禁用了Nagle 算法。(不需要等待0.2s) #tcp_nopush on; #在 nginx 中,tcp_nopush 配置和 tcp_nodelay "互斥"。它可以配置一次发送数据的包大小。也就是说,它不是按时间累计 0.2 秒后发送包,而是当包累计到一定大小后就发送。 #在 nginx 中,tcp_nopush 必须和 sendfile 搭配使用。 #连接超时时间 keepalive_timeout 65; #开启gzip压缩 gzip on; #小于1k的不压缩 gzip_min_length 1k; #gzip缓冲区大小 gzip_buffers 4 16k; #需要压缩的文件类型 gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; #IE1-6 浏览器不压缩 gzip_disable "MSIE [1-6]."; #连接建立后等待请求头的超时时间 client_header_timeout 3m; #链接建立后等待请求内容的超时时间 client_body_timeout 3m; #设定请求头缓冲区大小 client_header_buffer_size 4k; #当请求头超出缓冲区大小时,额外分配的缓冲区大小。 #当处理请求或连接转换到保持活动状态时,释放会缓冲区 large_client_header_buffers 4 8k; #设定请求体缓冲区大小 client_body_buffer_size 8k; #设定请求体最大值 #如果请求体超过该值,NGINX发回HTTP 413(Request Entity too large)错误 client_max_body_size 10m; #设定虚拟主机基本配置 server { #侦听80端口 listen 80; #定义使用 www.nginx.cn访问 server_name www.nginx.cn; #定义服务器的默认网站根目录位置 root /home/web; #设定本虚拟主机的访问日志 access_log logs/nginx.access.log main; error_log logs/nginx.error.log error; #默认请求 location / { #到/home/web下寻找文件 root /home/web/; } #rewrite请求 location ^~ /api { #去掉url前的前缀/api #/api/test/... -> /test/... rewrite ^/api/(.*) /$1 last; } # 定义错误提示页面 error_page 500 502 503 504 /50x.html; location = /50x.html { root /home/web/; } #静态文件由nginx托管 location ~ ^/(images|javascript|js|css|flash|media|static)/ { root /home/web/; #expires指令会修改源服务器的response header中的Cache-Control和Expires #浏览器会根据Cache-Control和Expires判断下次访问相同资源时是否需要重新发送请求 expires 30m; #30分钟内访问相同资源浏览器会使用本地缓存,不会发送请求 } #禁止访问 .out 文件 location ~ \.out { deny all; } } }
fastcgi虚拟主机配置
http{ #设定fastcgi虚拟主机配置 server { . . . #PHP 脚本请求全部转发到 FastCGI处理 location ~ \.php$ { include fastcgi_params; #fastcgi地址 fastcgi_pass 127.0.0.1 8000; fastcgi_index index.php; #访问的php文件位置 root /home/web/php/; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } . . . } }
uwsgi虚拟主机配置
http{ #设定uwsgi虚拟主机配置 server{ . . . location / { include uwsgi_params; #uwsgi地址 uwsgi_pass 127.0.0.1 8001; #uwsgi超时时间 uwsgi_read_timeout 30; } . . . } }
反向代理以及负载均衡虚拟主机配置
http{ #反向代理以及负载均衡虚拟主机配置 #被代理服务器地址和权重 upstream web_server { #使用ip的hash值选择服务器,可以保证session的有效性。 ip_hash; server 127.0.0.1:9001; #weight=5; server 127.0.0.1:9002; #weight=1; server 127.0.0.1:9003; #backup; #backup节点只有当其他节点都失效了才会被访问 #nginx 的 upstream支持的集中调度算法 #1、轮询(默认) # 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动删除。 #2、weight # 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 #3、ip_hash # 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session 保持的问题。 #4、fair(第三方) # 可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配,Nginx本身默认是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。 #5、url_hash(第三方) # 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率,Nginx本身默认是不支持url_hash的,如果需要这种高度算法,必须安装Nginx的hash软件包。 #6、least_conn # 根据后端服务器的连接状况进行分配客户请求,连接最少的服务器将被有限分配客户端请求。 } #nginx缓存设置 proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=STATIC:10m inactive=24h max_size=1g; #levels:表示创建两级目录结构,比如/export/cache/proxy_cache//*/,将所有文件放在一级目录结构中如果文件量很大会导致访问文件效率低。 #keys_zone:设置存储所有缓存key和相关信息的共享内存区,1M大约能存储8000个key。 #inactive:inactive指定被缓存的内容多久不被访问将从缓存中移除,以保证内容的新鲜,默认10分钟,此设置的优先级很高,如果缓存经常不能命中,可以检查该设置是否过小。 #max_size :最大缓存阀值,“cachemanager”进程会监控最大缓存大小,当缓存达到该阀值,该进程将从缓存中移除最近最少使用的内容。 server{ . . . location / { proxy_pass http://web_server; #当被代理服务器返回302重定向时,修改location中的目的地址 #proxy_redirect http://www.test.com:9001 http://www.test.com; #添加请求头 被代理服务器可以通过 header["Host"] 获取到nginx地址, header["X-Real-IP"] 获取到真实客户端地址。 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #设置代理超时时间 proxy_connect_timeout 1; proxy_send_timeout 90; proxy_read_timeout 90; #设置代理缓冲区 proxy_buffers 32 4k; } #nginx做静态文件缓存 location /static/ { proxy_pass http://web_server; #使用proxy_cache_path中定义的缓存 proxy_cache STATIC; #设置不同状态码的缓存时间 proxy_cache_valid 200 5m; #nginx缓存会把源服务器response的header也给缓存,如果header的cookie中带有session信息,那么不同用户访问同一个页面,会造成session错乱。 proxy_ignore_headers Set-Cookie; #这句代码很关键,尤其要忽略set-cookie proxy_hide_header Set-Cookie; #如果源服务器response的header中有Cache-Control和Expires,那么nginx的缓存时间将由Cache-Control和Expires决定,而忽略proxy_cache_valid设置的值。 #如果想要proxy_cache_valid生效则需要忽略源服务器response的header中的Cache-Control和Expires #proxy_ignore_headers Cache-Control; #proxy_hide_header Cache-Control; #proxy_ignore_headers Expires; #proxy_hide_header Expires; } . . . } }
参考文档: