前序、Nginx配置文件结构
nginx.conf文件
default.conf
全局块:配置影响nginx全局的指令。
- 运行nginx服务器的用户组
- nginx进程pid存放路径
- 日志存放路径
- 配置文件引入
- 允许生成worker process数
- ……
events块:配置影响nginx服务器或与用户的网络连接。
- 每个进程的最大连接数
- 选取哪种事件驱动模型处理连接请求
- 是否允许同时接受多个网路连接
- 开启多个网络连接序列化
- ……
http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。
- 文件引入
- mime-type定义
- 日志自定义
- 是否使用sendfile传输文件
- 连接超时时间
- 单连接请求数
- ……
server块:配置虚拟主机的相关参数,一个http中可以有多个server。
location块:配置请求的路由,以及各种页面的处理情况。
... #全局块 events { #events块 ... } http #http块 { server #server块 { location [PATTERN] #location块 { ... } } }
第一部分、全局块
user www www; #定义Nginx运行的用户和用户组,默认为:user nginx worker_processes 8; #nginx进程数,建议设置为等于CPU总核心数 error_log /var/log/nginx/error.log info; #指定日志路径 pid /var/run/nginx.pid; #指定nginx进程运行文件存放地址
第二部分、events块
#工作模式与连接数上限
events { accept_mutex on; #设置网路连接序列化,防止惊群现象发生,默认为on multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为off use epoll; #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport worker_connections 1024; #最大连接数 }
第三部分、http块
http { include /etc/nginx/mime.types; #文件扩展名与文件类型映射表 default_type application/octet-stream; #默认文件类型,默认为text/plain #charset utf-8; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log log/access.log main; # Nginx常见配置参数 sendfile on; #允许sendfile方式传输文件,默认为off tcp_nopush on; #防止网络阻塞 sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。 keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。 client_max_body_size 10m; #设置最大的允许客户端请求主体的大小(上传文件大小限制) server_tokens off; #隐藏nginx版本号的显示,默认为on # FastCGI相关参数 ...下文详述... # gzip模块设置 ...下文详述... # upstream模块设置 ...下文详述... # server块 server{ ...... } }
log_format格式
- $remote_addr 与 $http_x_forwarded_for 用以记录客户端的ip地址;
- $remote_user :用来记录客户端用户名称;
- $time_local : 用来记录访问时间与时区;
- $request : 用来记录请求的url与http协议;
- $status : 用来记录请求状态;成功是200;
- $body_bytes_sent :记录发送给客户端文件主体内容大小;
- $http_referer :用来记录从那个页面链接访问过来的;
- $http_user_agent :记录客户端浏览器的相关信息;
FastCGI相关参数
是为了改善网站的性能:减少资源占用,提高访问速度。
fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k;
gzip模块
gzip on; #开启gzip压缩输出 gzip_min_length 1k; #最小压缩文件大小 gzip_buffers 4 16k; #压缩缓冲区 gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0) gzip_comp_level 2; #压缩等级 gzip_types text/plain application/x-javascript text/css application/xml; #压缩类型
超时时间设置
- keepalive_timeout:用于设置客户端连接保持会话的超时时间,超过这个时间服务器会关闭该连接。
- client_header_timeout:用于设置读取客户端请求头数据的超时时间,如果超时客户端还没有发送完整的 header 数据,服务器将返回 “Request time out (408)” 错误。
- client_body_timeout:用于设置读取客户端请求主体数据的超时时间,如果超时客户端还没有发送完整的主体数据,服务器将返回 “Request time out (408)” 错误。
- send_timeout:用于指定响应客户端的超时时间,如果超过这个时间,客户端没有任何活动,Nginx 将会关闭连接。
- tcp_nodelay:默认情况下当数据发送时,内核并不会马上发送,可能会等待更多的字节组成一个数据包,这样可以提高 I/O 性能,但是,在每次只发送很少字节的业务场景中,使用 tcp_nodelay 功能,等待时间会比较长。
keepalive_timeout 65; client_header_timeout 15; client_body_timeout 15; send_timeout 25;
upstream负载均衡模块
upstream myupstream { server 192.168.1.1:80 weight=3; server 192.168.1.2:80 weight=2; server 192.168.1.3:80 weight=3; }
upstream开启keepalive
upstream myupstream { server ops-coffee.cn:8080; keepalive 1024; } server { location / { proxy_http_version 1.1; proxy_set_header Connection ""; proxy_pass http://myupstream; } }
nginx在项目中大多数情况下会作为反向代理使用,例如nginx后接tomcat,nginx后接php等,这时我们开启nginx和后端服务之间的keepalive能够减少频繁创建TCP连接造成的资源消耗,配置如上。
keepalive:指定每个nginxworker可以保持的最大连接数量为1024,默认不设置,即nginx作为client时keepalive未生效
proxy_http_version 1.1:开启keepalive要求HTTP协议版本为HTTP 1.1
proxy_set_header Connection “”:为了兼容老的协议以及防止http头中有Connection close导致的keepalive失效,这里需要及时清掉HTTP头部的Connection。
第四部分、server块
server { listen 80; #监听端口 server_name blog.ysea.cn hmsou.com; #域名可以有多个,用空格隔开 #charset koi8-r; #默认编码 #access_log /var/log/nginx/host.access.log main; #日志文件 #keepalive_requests 120; #单连接请求上限次数。 #error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # location块 location / { index index.html index.htm index.php; root /data/hmsou; deny 127.0.0.1; #拒绝的ip allow 172.18.5.54; #允许的ip } }
配置默认站点
server { listen 80 default; }
当一个nginx服务上创建了多个虚拟主机时默认会从上到下查找,如果匹配不到虚拟主机则会返回第一个虚拟主机的内容,如果你想指定一个默认站点时,可以将这个站点的虚拟主机放在配置文件中第一个虚拟主机的位置,或者在这个站点的虚拟主机上配置listen default。
禁止非法域名解析访问
第一种方式:配置一个server虚拟主机区块,放置在所有server区块最前面。
server { listen 80 default; server_name _; return 404; }
可能有一些未备案的域名或者你不希望的域名将服务器地址指向了你的服务器,这时候就会对你的站点造成一定的影响,需要禁止IP或未配置的域名访问,我们利用上边所说的default规则,将默认流量都转到404去。
第二种方式:将计就计,通过你的域名访问时候,自动跳转到我的域名上上边。
server { listen 80 default_server; server_name _; rewrite ^(.*) http://www.nmtui.com/$1 permanent; } if ($host !~ ^www\.nmtui\.com$){ rewrite ^(.*) http://www.nmtui.com/$1 permanent; }
SSL(https)相关
server { listen 443; server_name localhost; charset utf-8; ssl on; ssl_certificate /etc/nginx/server.crt; ssl_certificate_key /etc/nginx/server.key; access_log /var/logs/nginx/hmsou.com.ssl.access.log access; error_log /var/logs/nginx/hmsou.com.ssl.error.log; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers RC4:HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; keepalive_timeout 120; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; }
第五部分、location块
Proxy反向代理模块
location / { proxy_pass http://myupstream; #请求转向myupstream 定义的服务器列表 proxy_set_header Host $host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 以下是一些反向代理的配置,可选 client_max_body_size 10m; #允许客户端请求的最大单文件字节数 client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数 proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时) proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时) proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时) proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置 proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 }
加杠不加杠的陷阱
稍不注意可能会落入一个proxy_pass加杠不加杠的陷阱,这里详细说下proxy_pass http://myupstream与proxy_pass http://myupstream/的区别:
虽然只是一个/的区别但结果确千差万别。分为以下两种情况:
1. 目标地址中不带uri(proxy_pass http://myupstream)。此时新的目标url中,匹配的uri部分不做修改,原来是什么就是什么。
location /ops-coffee/ { proxy_pass http://192.168.106.135:8181; }
http://domain/ops-coffee/ –> http://192.168.106.135:8181/ops-coffee/
http://domain/ops-coffee/action/abc –> http://192.168.106.135:8181/ops-coffee/action/abc
2. 目标地址中带uri(proxy_pass http://myupstream/,/也是uri),此时新的目标url中,匹配的uri部分将会被修改为该参数中的uri。
location /ops-coffee/ { proxy_pass http://192.168.106.135:8181/; }
http://domain/ops-coffee/ –> http://192.168.106.135:8181
http://domain/ops-coffee/action/abc –> http://192.168.106.135:8181/action/abc
依据UA屏蔽爬虫
location / { if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot") { return 403; } }
黑白名单
location / { allow 133.27.182.82; allow 113.106.18.0/24; allow 121.201.104.0/24; deny all; }
使用Auth权限访问
location / { auth_basic "bbs-auth"; auth_basic_user_file /usr/local/nginx/conf/bbsauthpwd; }
限制带宽
# 用户下载达到 500k 后,便控制其速度在 50k 以内 location / { limit_rate_after 500k; limit_rate 50k; }
限制连接
# 定义了一个名为“down”,10M大小,以连接IP为key的连接数据存储空间 limit_conn_zone $binary_remote_addr zone=down:10m; # 读取名为`down`连接数据存储空间的数据,限制每个key(上面是以ip作为IP) 最大同时连接数为4 location ~ .*\.(rar|zip|apk)?$ { limit_conn down 4; limit_rate 150k; } limit_conn_log_level notice; #指定当触发limit的时候日志打印级别
限制请求
- 定义一个名为”one”, 10M大小,每秒1个请求的请求数据存储空间;
- 引用名为“one”的存储空间,burst为等待请求数量数,当等待请求数量超过50个时,则抛出503错误,nodelay 针对的是 burst 参数,burst=50 nodelay 表示这50个请求立马处理,不能延迟,相当于特事特办。不过,即使这20个突发请求立马处理结束,后续来了请求也不会立马处理。burst=50 相当于缓存队列中占了50个坑,即使请求被处理了,这20个位置这只能按 100ms一个来释放
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; limit_req zone=one burst=50 nodelay; limit_req_log_level notice; #指定当触发limit的时候日志打印级别
配置expires缓存期限
Nginx expires 的功能就是给用户访问的静态内容设定一个过期时间。
当用户第一次访问这些内容时,会把这些内容存储在用户浏览器本地,这样用户第二次及以后继续访问该网站时,浏览器会检查加载已经缓存在用户浏览器本地的内容,就不会去服务器下载了,直到缓存的内容过期或被清除。
不希望被缓存的内容:广告图片、网站流量统计工具、更新很频繁的文件。
缓存期限参考:新浪缓存 15 天,京东缓存 25 年,淘宝缓存 10 年。
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$ { expires 3650d; # 缓存期限为 10 年 }
配置防盗链
防盗链:简单地说,就是其它网站未经许可,通过在其自身网站程序里非法调用其他网站的资源,然后在自己的网站上显示这些调用的资源,使得被盗链的那一端消耗带宽资源 。
通过 HTTP referer 实现防盗链。
# 第一种,匹配后缀 location ~ .*\.(gif|jpg|jpeg|png|bm|swf|flv|rar|zip|gz|bz2)$ { # 指定需要使用防盗链的媒体资源 access_log off; expires 15d; valid_referers none blocked *.test.com *.abc.com; #仅允许这些域名访问上面的媒体资源 if ($invalid_referer) { #如果域名不是上面指定的地址就返回403 return 403; } } # 第二种,绑定目录 location /images { vaild_referers none blocked *.test.com *.abc.com;; if ($invalid_referer) { return 403; } }
开启列目录
当你想让nginx作为文件下载服务器存在时,需要开启nginx列目录
location / { autoindex on; autoindex_exact_size off; autoindex_localtime on; }
autoindex_exact_size:为on(默认)时显示文件的确切大小,单位是byte;改为off显示文件大概大小,单位KB或MB或GB
autoindex_localtime:为off(默认)时显示的文件时间为GMT时间;改为on后,显示的文件时间为服务器时间
直接返回验证文件
location = /XDFyle6tNA.txt { default_type text/plain; return 200 'd6296a84657eb275c05c31b10924f6ea'; }
很多时候微信等程序都需要我们放一个txt的文件到项目里以验证项目归属,我们可以直接通过上边这种方式修改nginx即可,无需真正的把文件给放到服务器上。
404自动跳转到首页
server { location / { error_page 404 = @ops-coffee; } location @ops-coffee { rewrite .* / permanent; } }
网站出现404页面不是特别友好,我们可以通过上边的配置在出现404之后给自动跳转到首页去。
配置跨域
降低了安全性,不推荐使用。
location / { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; if ($request_method = 'OPTIONS') { return 204; } }
1. Access-Control-Allow-Origin
服务器默认是不被允许跨域的。给Nginx服务器配置`Access-Control-Allow-Origin *`后,表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。
2. Access-Control-Allow-Headers 是为了防止出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
这个错误表示当前请求Content-Type的值不被支持。其实是我们发起了”application/json”的类型请求导致的。这里涉及到一个概念:预检请求(preflight request),请看下面”预检请求”的介绍。
3. Access-Control-Allow-Methods 是为了防止出现以下错误:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
4.给OPTIONS 添加 204的返回,是为了处理在发送POST请求时Nginx依然拒绝访问的错误发送”预检请求”时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
第六部分、Nginx其他信息
Nginx 常见错误码
- 301 永久重定向
- 302 临时重定向
- 403 禁止访问
- 404 文件不存在
- 413 文件上传超过限制
- 500 服务器错误
- 502 后台服务器无响应
- 504 Nginx超时,请求过多,工作进程不足
Nginx 常用命令
- nginx -s stop :快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。
- nginx -s quit :平稳关闭Nginx,保存相关信息,有安排的结束web服务。
- nginx -s reload :因改变了Nginx相关配置,需要重新加载配置而重载。
- nginx -s reopen :重新打开日志文件。
- nginx -c filename :为 Nginx 指定一个配置文件,来代替缺省的。
- nginx -t :不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
- nginx -v:显示 nginx 的版本。
- nginx -V:显示 nginx 的版本,编译器版本和配置参数。