Nginx提升学习架构总结
1.选择nginx的理由 (1)支持高并发;(官方5w并发,实测3w并发,因为采用epoll网络IO模型) (2)内存消耗少;(nginx+php-fcgi在3w并发下开启10个nginx进程,消耗150mb内存,64个nginx进程消耗内存1280mb) (3)成本低廉;(开源免费,可用于商业,相对硬件f5成本低) (4)节省带宽; (5)稳定高; (6)内置健康检查功能; (7)支持反向代理; (8)支持负载均衡;(应用层) 2.网络IO连接方法 分2种:阻塞IO(block IO)和多路复用IO(现在服务器多用); 阻塞IO:一个请求过来,只能干这个事情,别的事情不能干;(如同学来找你,告诉他你的地址,且在宿舍门口等,在这个过程中,一直等待,直到同学找到你,期间你不能做任何事情) 多路复用IO:包含select和epoll模型;(select模型举例如同学来找你,告诉你同学地址并在宿舍等,同学来到宿舍门口还是找不到你,就找楼管,楼管挨个宿舍去找,效率很慢;epoll模型举例如同学来找你,告诉你同学地址并在宿舍等,同学来到宿舍门口还是找不到你,就找楼管,楼管处有人员登记数据库,查看登记名册,告诉你同学在哪层楼多少号房间,这样就快速找到你了) 3.nginx虚拟主机及相关配置 (1)nginx配置文件结构图 ...... event{ ...... } http{ ...... server{ ...... } server{ ...... } } (2)nginx虚拟主机 定义server,可以基于端口、ip、域名做虚拟主机。 (3)nginx匹配规则 location语法:location=[=|~|~*|^~]/uri/{...} ~ 区分大小写 ~* 不区分大小写 ^~ 禁止表达式匹配 = 精确匹配 举例如: location =/{ #只匹配/的查询 } location /{ #匹配任何以/开头的查询,但正则与一些较长字符串被首先匹配 #./document/index.html } location ^~ /images/{ #匹配任何以/images/开头的查询,且停止搜索,不检查正则 #./images/1.gif } location ^* \.(gif|jpg|jpeg)${ #匹配任何以gif,jpg,jpeg结尾的文件,但所有/images/目录的请求在上面处理,精确匹配 #./document/1.gif } 解释:url和uri url:统一资源定位符,如http://www.onon.com/news/a10.html uri:统一资源标示符,指具体的路径,如news/a10.html (4)自定义错误页面 error_page 403 404 /40x.html; location = /40x.html{ root /var/web/error/; } 解释:server中定义,其中/40x.html前面的/是指定义server指定文件root的路径。 另针对error指定专门存放路径,如上面的“root /var/web/error/”,至此就可以将40x.html页面放到改目录下。 对于50x错误也同样定义: error_page 500 502 503 504 /50x.html location = /50x.html{ root /var/web/error/; } (5)自动索引及别名功能 location /onon{ root /web/html; index index.html; autoindex on; } 解释:将/web/html目录下的文件索引显示 location /over/{ alias /data/web3/images/toto/; } 解释:访问/data/web3/images/toto/top.jpg文件时,可以使用/over/top.jpg访问 (6)控制站点访问 location /onon{ root /web/html; index index.html; autoindex on; deny 192.168.0.110; allow 192.168.0.0/24; allow 192.168.1.12; deny all; } (7)目录身份验证 /usr/local/apache/bin/htpasswd -c /home/nginx/conf/authdb webadmin nginx auth_basic认证采用apache兼容的密码文件,创建webadmin用户,输入密码即可。 当访问/onon时就会提示输入用户名和密码。 location /onon{ root /web/html; index index.html; autoindex on; auth_basic "Enter your user and password"; auth_basic_user_file /home/nginx/conf/authdb; deny 192.168.0.110; allow 192.168.0.0/24; allow 192.168.1.12; deny all; } (8)nginx状态检查 location /nginx_status{ stub_status on; access_log off; } 解释:不需要开启访问日志access_log;访问目录/nginx_status添加认证,见上;编译的时候需要添加此模块:--with-http_stub_status_module (9)nginx rewrite 编译时需要添加pcre库,prel兼容正则表达式; nginx rewrite是实现url/uri重写; 语法指令:set、if、return、break、rewrite 语法规则: =和!= ~ 区分大小写 ~* 不区分大小写 !~和!~* -f和!-f 判断文件是否存在 -d和!-d 判断目录是否存在 -e和!-e 判断文件或目录是否存在 -x和!-x 判断文件是否可以执行 $1 - $9 位置化参数 全局变量(系统已定义好) $arg_PARAMETER#这个变量包含GET请求中,如果有变量PARAMETER时的值。 $args #这个变量等于请求行中(GET请求)的参数,例如foo=123&bar=blahblah; $binary_remote_addr#二进制的客户地址。 $body_bytes_sent#响应时送出的body字节数数量。即使连接中断,这个数据也是精确的。 $content_length#请求头中的Content-length字段。 $content_type#请求头中的Content-Type字段。 $cookie_COOKIE#cookie COOKIE变量的值 $document_root#当前请求在root指令中指定的值。 $document_uri#与$uri相同。 $host#请求主机头字段,否则为服务器名称。 $hostname#Set to the machine’s hostname as returned by gethostname $http_HEADER $is_args#如果有$args参数,这个变量等于”?”,否则等于”",空值。 $http_user_agent#客户端agent信息 $http_cookie#客户端cookie信息 $limit_rate#这个变量可以限制连接速率。 $query_string#与$args相同。 $request_body_file#客户端请求主体信息的临时文件名。 $request_method#客户端请求的动作,通常为GET或POST。 $remote_addr#客户端的IP地址。 $remote_port#客户端的端口。 $remote_user#已经经过Auth Basic Module验证的用户名。 $request_completion#如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty)。 $request_method#GET或POST $request_filename#当前请求的文件路径,由root或alias指令与URI请求生成。 $request_uri#包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。不能修改。 $scheme#HTTP方法(如http,https)。 $server_protocol#请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 $server_addr#服务器地址,在完成一次系统调用后可以确定这个值。 $server_name#服务器名称。 $server_port#请求到达服务器的端口号。 $uri#不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。该值有可能和$request_uri 不一致。$request_uri是浏览器发过来的值。该值是rewrite后的值。例如做了internal redirects后。 if指令: if($http_user_agent ~MSIE){ rewrite ^(.*)$ /msie/$1 break; } 解释:$http_user_agent用户代理,如浏览器ie,firefox等; ~区分大小写,MSIE浏览器ie; ^以什么开始,$以什么结尾,.*匹配任意字符串;$1位置符,/msie/$1指的是web所指向的root路径下 的/msie/$1,如/data/web3/images/toto/msie/index.html return指令: 如果访问url以“*.sh”或“*.bash”结尾,则返回状态码403 location ~.*\.(sh|bash)?$ { return 403; } 解释:“~”匹配大小写,“.*”前面不管是什么字符,“.(sh|bash)?$”以sh或bas,用$标识,“\”去掉其后面“.”的特殊意义的。403错误就是指error_page定义的错误。 rewrite指令: 最后一项参数flag标记,有以下: last:完成rewrite,相当于apache的[L]标记,浏览器url地址不变; break:本条规则匹配后就完成,终止匹配,浏览器url地址不变; redirect:返回302临时重定向,浏览器显示跳转后的url; permanent:返回301永久重定向,浏览器显示跳转后的url; 案例: 1)将/bbs目录重写到/data rewrite ^/bbs/?$ /data/ permanent; location /data{ index index.html; } location /bbs{ rewrite ~/bbs/?$ /data/ permanent; } 2)根据不同的浏览器将得到不同的结果 if($http_user_agent ~MSIE){ rewrite ^(.*)$ /msie/$1 break; } server{ listen 80 default_server; server_name www.onon.com; index index.html; root /data/www/onon; if($http_user_agent ~Firefox){ rewrite ^(.*)$ /firefox/$1 break; } if($http_user_agent ~MSIE){ rewrite ^(.*)$ /msie/$1 break; } } 3)防止盗链 所谓防盗链就是别人网站的图片引用我们的网站上的,且点击别人网站上的那个图片,使用的是我们网站的流量,只引用我们网站的图片,不会跳转到我们网站上来。 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv)$ { valid_referers none blocked www.onon.com *.onon.com; if ($invalid_referer) { rewrite ^/(.*) http://www.onon.com/block.html; } } 4)实现域名跳转 访问www.onon.com跳转到www.onbing.com server{ listen 80 default_server; server_name www.onon.com; index index.html; root /data/www/onon; location / { rewrite ~(.*)$ http://www.onbing.com$1 permanent; } } 5)URL rewrite和反向代理同时进行 location /news/ { proxy_pass http://10.0.0.10; } location /health/ { proxy_pass http://10.0.0.20; } (10)nginx日志管理 语法如下:log_format name format (format ....) 自定义日志格式如下: log_format main '$remote_addr - $remote_user [$time_local] "$request"' '$status $body_bytes_sent "$http_referer"'; '"$http_user_agent" "$http_x_forwarded_for"'; $http_x_forwarded_for 记录远程用户真实ip地址,不是缓存/代理服务器地址; $remote_user 记录远程客户端用户名称,一般不会记录的; $time_local 记录访问时间及地区,记录用户访问时的本地时间; $request 记录请求的URL与HTTP协议,具体访问的页面; $status 记录请求的状态,第一次成功访问状态为200,再次访问页面未更新状态为304,页面找不到时为404 $body_bytes_sent 记录发送给客户端的文件主体内容大小 $http_referer 记录是从哪个页面链接访问过来的,如百度链接过来的; $http_user_agent 记录客户端浏览器的相关信息 注意:上面定义的日志格式,跟在access_log后面,error_log后面跟错误级别,如下: access_log /data0/logs/nginx/www.onon.com-access.log main; access_log /data0/logs/$server_name.log mylogformat buffer=32k; 解释:main、mylogformat为定义日志格式时取名;$server_name为自动获取访问地址,如www.onon.com,消耗资源;buffer=32k为设置缓存区大小,只记录日志文件描述符。 error_log /data0/logs/nginx/www.onon.com-error.log warn; 解释:warn为错误级别,日志等级有8个,分别为:emerg、alert、crit、err、warn、notice、info、debug 开启日志缓存 每一条日志记录,日志文件先打开文件,写入日志记录,马上关闭。 如何提高包含变量的日志文件存放路径性能?开启open_log_file_cache open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m; 解释:max最大文件描述符数量,inactive设定时间内没有使用此文件描述符,则自动删除此描述符, min_uses在inactive指定时间范围内,若日志文件超过被使用次数,则计入缓存,默认10秒,valid多长时间检查一次,看日志文件路径和文件名是否仍然存在,默认60秒。 nginx日志分割 vim /data/sh/nginxlog_cut.sh #! /bin/bash #nginx log 存放位置 logs_path="/data/logs/nglogcut/" #将日志改名 mkdir -p ${logs_path}$(date -d "yesterday" + "%Y")/$(date -d "yesterday" + "%m")/ mv ${logs_path}access.log ${logs_path}$(date -d "yesterday" + "%Y")/$(date -d "yesterday" + "%m")/access_$(date -d "yesterday" + "%Y%m%d").log 重新加载nginx服务 service nginx reload 添加计划任务 chmod +x /data/sh/nginxlog_cut.sh #crontab -l 01 01 * * * /bin/bash /data/sh/nginxlog_cut.sh (11)nginx压缩输出 在http{}中间启用压缩 模块:HttpGzipModule和HttpGzipStaticModule 前者用于启用在文件传输过程中使用gzip压缩,而后者的作用是将一个文件以压缩的方式传递到一个支持压缩功能的客户端之前,首先检查是否已经存在相应的*.gz结尾的文件名格式,这样避免重复压缩而造成资源浪费。 对于nginx的网页压缩传输在nginx中的配置是将其分到两种模式:一种是动态的,实时压缩输出(边压缩边输出),另一种是静态的,找到同名文件的.gz格式文件就输出。 启用gzip功能需要zlib库的支持,--with-http_gzip_module; 编译时需要指定--with-http_gzip_static_module gzip(GNU-ZIP)是一种压缩技术。经过gzip压缩后页面大小可以变为原来的30%甚至更小,这样,用户浏览页面的时候速度会块得多。gzip的压缩页面需要浏览器和服务器双方都支持,实际上就是服务器端压缩,传到浏览器后浏览器解压并解析。浏览器那里不需要我们担心,因为目前的巨大多数浏览器都支持解析gzip过的页面。 #vim nginx.conf http{ gzip on; gzip_min_length 1k; gzip_buffer 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; } 解释:gzip on开启gzip模块,关闭使用off; gzip_min_length设置允许压缩的页面最小字节数,页面字节数从header头的content-length中进行获取。默认为0,不管页面多大都压缩。建议设为1k,小于1k可能会越压越大; gzip_buffer设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。上面的设置为以16k为单位的4倍申请内存; gzip_http_version识别http协议的版本,早期的浏览器不支持gzip压缩,用户会看到乱码,所以为了支持前期版本加了此选项,目前此项基本可以忽略; gzip_comp_level为gzip压缩比,分1-9等级,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu); gzip_types匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的; gzip_vary和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩; (12)nginx的浏览器本地缓存设置 #vim nginx.conf location ~.*\.(gif|jpg|jpeg|png|bmp|swf|flv)${ expires 30d; } location ~.*\.(js|css|jsp)?${ expires 1h; } (13)设定限速(常见流媒体) location /download { limit_rate 256k; proxy_pass http://www.onbing.com; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; } location /movie { limit_rate_after 10m; limit_rate 100k; } 解释:前10m不限速,之后限速为100k。 if($http_user_agent ~Google|Yahoo|baidu){ limit_rate 20k; } 解释:通过google,yahoo或baidu搜索引擎访问进来的,限速为20k。 (14)反向代理 正向代理和反向代理?正向就是一个从内向外的访问,反向则是一个从外向内的访问。正向和反向是一个相对的概念。 正向:典型应用为在防火墙内的局域网客户端提供访问Internet的途径; 相对于用户,就是正向代理,代理用户去请求; 让nginx成为正向代理,而将外网视为整个后端在给我们提供服务。 反向:典型应用为将防火墙后面的服务器提供给Internet用户访问; 相对于内部的服务那么nginx就是反向代理,代理接受用户请求; http { client_body_buffer_size 600; client_header_buffer_size 600; client_max_body_size 300M; proxy_buffering on; proxy_cache_min_uses 3; proxy_ignore_client_abort off; proxy_intercept_errors on; proxy_next_upstream error timeout invalid_header; proxy_redirect off; proxy_connect_timeout 60; proxy_send_timeout 600; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_temp_path /usr/local/nginx/proxy_temp; proxy_cache_path /usr/local/nginx/proxy_cache/ levels=1:2 keys_zone=cache_onon:10m inactive=10m max_size=1000M; location /weibo { proxy_pass http://192.168.10.213; proxy_set_header Host $host; proxy_cache cache_onon; proxy_set_header X-Forward-For $remote_addr; } location ~.*\.(gif|jpg|jpeg|png|bmp|swf|flv|js|css|html)${ #状态码 proxy_cache cache_onon; proxy_cache_valid 200 10m; proxy_cache_valid 304 1m; proxy_cache_valid 301 302 1h; proxy_cache_valid any 1m; #哈希key值 proxy_cache_key $host$uri$is_args$args; proxy_set_header Host $host; proxy_set_header X-Forward-For $remote_addr; proxy_pass http://192.168.1.66; } } (15)负载均衡 upstream news_server_pool{ server 10.0.0.21:80 weight=1 max_fails=2 fail_timeout=30s; server 10.0.0.22:80 weight=1 max_fails=2 fail_timeout=30s; } upstream tv_server_pool{ server 10.0.0.31:80 weight=1 max_fails=2 fail_timeout=30s; server 10.0.0.32:80 weight=2 max_fails=2 fail_timeout=30s; } 解释:30s内检测2次,失效就找下一个服务器。 location /news { proxy_pass http://news_server_pool; proxy_set_header Host $host; proxy_set_header X-Forward-For $remote_addr; } location /tv { proxy_pass http://tv_server_pool; proxy_set_header Host $host; proxy_set_header X-Forward-For $remote_addr; } 本文转自自由心行博客51CTO博客,原文链接http://blog.51cto.com/xiaojiang2008/1247187如需转载请自行联系原作者 xiaojiang