Nginx基础知识、常见问题和解决方法整理

Nginx中文手册下载:http://www.21andy.com/blog/20100203/1609.html
Nginx指令索引:http://www.howtocn.org/nginx:directiveindex

  1. 有关nginx的worker_processes参数
    worker_processes #指定工作衍生进程数(一般等于CPU的总核数或者总核数的两倍),每个进程耗费10MB-12MB内存
    我的CPU为2个物理CPU,每个CPU4个核心
    具体设置值为:
    worker_processes     8;
    worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
    worker_processes参数设置详解:http://hi.baidu.com/wh_as/item/dfa6c3add9244136020a4df5
    nginx的worker_processes该怎么设置:http://segmentfault.com/q/1010000000132550
    Nginx 多核cpu 优化:(Core) + worker_processes (worker_cpu_affinity):http://blog.bin9.com/html/n2011/1210.html
    nginx的 CPU参数worker_processes和worker_cpu_affinity使用说明:http://blog.csdn.net/zuiaituantuan/article/details/7264969
    worker_cpu_affinity参数配置详解:http://blog.chinaunix.net/uid-20662363-id-2953741.html
  2. nginx error_log 日志配置
    语法:
    error_log file [ debug | info | notice | warn | error | crit ]  | [{  debug_core | debug_alloc | debug_mutex | debug_event | debug_http | debug_mail | debug_mysql } ]
    日志级别 = 错误日志级别 | 调试日志级别; 或者
    日志级别 = 错误日志级别;
    错误日志的级别: emerg, alert, crit, error, warn, notic, info, debug,
    调试日志的级别: debug_core, debug_alloc, debug_mutex, debug_event, debug_http, debug_mail, debug_mysql,error_log 指令的日志级别配置分为 错误日志级别和调试日志级别
    且错误日志只能设置一个级别,错误日志必须书写在调试日志级别的前面,调试日志可以设置多个级别
    其他配置方法可能达不到你的预期.
    参考资料:
    1、http://cjhust.blog.163.com/blog/static/175827157201242182635874/
  3. nginx 反向代理 负载均衡 综合应用配置文件 带参数说明
    #使用的用户和组
    user www www;
    
    #指定工作衍生进程数(一般等于CPU的总核数或者总核数的两倍),每个进程耗费10MB-12MB内存
    worker_processes  8;
    
    #指定错误日志存放的路径,错误日志记录级别可选项为:[debug | info | noticd | warn | error | crit]
    error_log  /var/log/nginx/error.log  crit;
    
    #指定pid存放的路径,文件内记录当前nginx主进程的ID,kill -HUP 'logs/nginx.pid'
    pid        /var/run/nginx.pid;
    
    #指定文件描述符数量,一个 nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit-n) 与 nginx 进程数相除,但是 nginx 分配请求并不是那么均匀,所以最好与 ulimit -n的值保持一致。
    worker_rlimit_nofile 65535;
    
    #工作模式及连接数上限
    events {
    
    	#提高linux的io操作选项,Linux系统推荐采用epoll模型,FreeBSD系统推荐采用kequeue,linux下建议开启
    	use epoll;
    
    	#允许最大连接数,每个nginx进程的连接数(最大连接=连接数(65535) x 进程数(8))
    	worker_connections 65535;
    }
    
    http {
    
    	#mimie.types 浏览器请求的文件媒体类型
    	include       mime.types;
    
    	#用来告诉浏览器请求的文件媒体类型
    	default_type  application/octet-stream;
    
    	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  /var/log/nginx/access.log  main;
    
        #服务器名字的 hash 表大小
    	server_names_hash_bucket_size 128;
    
    	#用于设置客户端请求的Header头缓冲区大小,大部分情况1KB大小足够。不能超过large_client_header_buffers缓冲区大小的设置
    	client_header_buffer_size 32k;
    
    	#该指令用于设置客户端请求的Header头缓冲区大小,默认值为4KB。
    	large_client_header_buffers 4 32k;
    
        #开启高效文件传输模式
    	sendfile on;
    
    	#防止网络阻塞
    	tcp_nopush on;
    
     	#该指令允许或禁止使用套接字选项TCP_NODELAY,仅适用于keep-alive连接,防止网络阻塞
     	tcp_nodelay on;
    
    	#禁止显示版本号
    	server_tokens off;
    
    	#keepalive_timeout  0该指令可以使客户端到服务器端的连接持续有效,客户端与服务器长连接的超时时间,超过这个时间,服务器将关闭连接
    	keepalive_timeout 60;
    
    	#指定连接到后端FastCGI的超时时间。
    	fastcgi_connect_timeout 300;
    
    	#向FastCGI传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI传送请求的超时时间。
    	fastcgi_send_timeout 300;
    
    	#该指令用于设置upstream模块等待FastCGI进程发送数据的超时时间,默认值为60s;接收FastCGI应答的超时时间,这个值是指已经完成两次握手后接收FastCGI应答的超时时间。
    	fastcgi_read_timeout 300;
    
    	#该指令设置FastCGI服务器相应头部的缓冲区大小。通常情况,该缓冲区大小设置等于fastcgi_buffers指令设置的一个缓冲区的大小
    	fastcgi_buffer_size 64k;
    
    	#该指令设置了读取FastCGI进程返回信息的缓冲区数量和大小
    	fastcgi_buffers 4 64k;
    
    	#建议为fastcgi_buffers的两倍
    	fastcgi_busy_buffers_size 128k;
    
    	#在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍,设置上述数值设置太小时若负载上来时可能报 502 Bad Gateway
    	fastcgi_temp_file_write_size 128k;
    
    	#开启gzip压缩,对网页文件、css、js、xml等启动gzip压缩,减少数据传输量,提高访问速度。
    	gzip on;
    
    	#该指令允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。
    	gzip_min_length  1k;
    
    	#设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。下面的设置代表16k为单位,按照原始数据大小以16k为单位的4倍申请内存。
    	gzip_buffers     4 16k;
    
    	#识别http的协议版本。
    	gzip_http_version 1.1;
    
    	#gzip压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理速度最慢(传输快但比较消耗cpu)
    	gzip_comp_level 2;
    
    	#匹配mime类型进行压缩,无论是否指定,“text/html”类型总是会被压缩的。
    	gzip_types      text/plain application/x-javascript text/css application/xml;
    
    	#启用应答头“Vary: Accept-Encoding”
    	gzip_vary on;
    
    	#允许客户端请求的最大单个文件字节数
    	client_max_body_size 300m;
    
    	#缓冲区代理缓冲用户端请求的最大字节数,可以理解为先保存到本地再传给用户
    	client_body_buffer_size 512k;
    
    	#跟后端服务器连接的超时时间_发起握手等候响应超时时间
    	proxy_connect_timeout 5;
    
    	#连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理
    	proxy_read_timeout 60;
    
    	#后端服务器数据回传时间_就是在规定时间内后端服务器必须传完所有的数据
    	proxy_send_timeout 5;
    
    	#代理请求缓存区_这个缓存区会保存用户的头信息以供Nginx进行规则处理_一般只要能保存下头信息即可
    	proxy_buffer_size 16k;
    
    	#同上 告诉Nginx保存单个用的几个Buffer最大用多大空间
    	proxy_buffers 4 64k;
    
    	#如果系统很忙的时候可以申请更大的proxy_buffers 官方推荐*2
    	proxy_busy_buffers_size 128k;
    
    	#proxy缓存临时文件的大小
    	proxy_temp_file_write_size 128k;
    
    	#注:proxy_temp_path和proxy_cache_path指定的路径必须在同一分区
        proxy_temp_path   /www/wwwroot/web/proxy_temp_dir;
        #设置Web缓存区名称为cache_one,内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。
        proxy_cache_path  /www/wwwroot/web/proxy_cache_dir  levels=1:2  keys_zone=cache_one:200m inactive=1d max_size=30g;
    
    	#第一组php负载均衡服务器
    	upstream backend_server {
    		server 192.168.0.202:80 weight=1 max_fails=2 fail_timeout=30s;
    		server 192.168.0.203:80 weight=1 max_fails=2 fail_timeout=30s;
    		server 192.168.0.204:80 weight=1 max_fails=2 fail_timeout=30s;
    	}
    
    	#第二组
    	upstream php_server_pool {
    		server 192.168.0.204:8080;
    		server 192.168.0.205:8080;
    	 }
    
    	#第三组
    	upstream message_server_pool {
    		server 192.168.0.206:80 weight=1 max_fails=2 fail_timeout=30s;
    		server 192.168.0.207:80 weight=1 max_fails=2 fail_timeout=30s;
    		server 192.168.0.208:80 weight=1 max_fails=2 fail_timeout=30s;
    	}
    
    	server {
    		#该指令用于设置虚拟主机监听的服务器地址和端口号。
    		listen 80;
    		server_name  www.yourdomain.com 192.168.8.42;
    		index index.html index.htm;
    		root  /data0/htdocs/www;
    
    		location / {
    			#如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移
    			proxy_next_upstream http_502  http_504 error timeout invalid_header;
    			proxy_cache cache_one;
    			#对不同的HTTP状态码设置不同的缓存时间
    			proxy_cache_valid  200 304 12h;
    			#以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希,存储缓存内容到二级缓存目录内
    			proxy_cache_key $host$uri$is_args$args;
    			proxy_set_header Host  $host;			#当使用反向代理后,如果我们通过$_SERVER['REMOTE_ADDR']将得到的是Nginx负载均衡服务器的IP。这时我们在反向代理时添加了Header头信息X-Forwarded-For,这样我们就可以通过$_SERVER['X-FORWARDED-FOR']获得用户的IP
    			proxy_set_header X-Forwarded-For  $remote_addr;
    			proxy_pass http://backend_server;
    			expires      1d;
    		}
    		#用于清除缓存,假设一个URL为http://192.168.8.42/test.txt,通过访问http://192.168.8.42/purge/test.txt就可以清除该URL的缓存。
    		location ~ /purge(/.*) {
    			#设置只允许指定的IP或IP段才可以清除URL缓存。
    			allow            127.0.0.1;
    			allow            192.168.0.0/16;
    			deny            all;
    			proxy_cache_purge    cache_one   $host$1$is_args$args;
    		}
    
    		#扩展名以.php、.jsp、.cgi结尾的动态应用程序不缓存。
    		location ~ .*\.(php|jsp|cgi)?$ {
    			proxy_set_header Host  $host;
    			proxy_set_header X-Forwarded-For  $remote_addr;
    			proxy_pass http://backend_server;
    		}
    
    		access_log  off;
    	}
    
    	#第二个虚拟主机
    	server {
    		listen 80;
    		server_name www1.xiaozhe.com;
    		#访问http://www1.xiaozhe.com/message/*地址反向代理message_server_pool服务器
    		location /message/ {
    			proxy_pass http://message_server_pool;
    			proxy_set_header Host $host;
    		}
    		#访问除了/message/之外的http://www1.xiaozhe.com/**地址,反向代理php_server_pool这组服务器
    		location / {
    			proxy_pass http://php_server_pool;
    			proxy_set_header Host $host;
    			proxy_set_header X-Forwarded-For $remote_addr;
    		}
    		access_log /data1/logs/message.xiaozhe.com.access.log;
    	}
    
    	#第三个虚拟主机
    	server {
    		listen 80;
    		server_name bbs.xiaozhe.com *.bbs.xiaozhe.com;
    
    		location / {
    			proxy_pass http://bbs_server_pool;
    			proxy_set_header Host $host;
    			proxy_set_header X-Forwarded-For $remote_addr;
    		}
    
    		#不记录日志
    		access_log off;
    	}
    }
    

    参考资料:
    1、http://www.yunwei8.com/nginxzhyy/
    2、http://dngood.blog.51cto.com/446195/633805
    3、使用Nginx的proxy_cache缓存功能取代Squid[原创]:http://blog.s135.com/nginx_cache/1/1/

  4. nginx rewrite 正则表达式匹配,其中:
    ~ 为区分大小写匹配
    ~* 为不区分大小写匹配
    !~和!~*分别为区分大小写不匹配及不区分大小写不匹配
    文件及目录匹配,其中:
    -f和!-f用来判断是否存在文件
    -d和!-d用来判断是否存在目录
    -e和!-e用来判断是否存在文件或目录
    -x和!-x用来判断文件是否可执行
    flag标记有:
    last 相当于Apache里的[L]标记,表示完成rewrite
    break 终止匹配, 不再匹配后面的规则
    redirect 返回302临时重定向 地址栏会显示跳转后的地址
    permanent 返回301永久重定向 地址栏会显示跳转后的地址
    nginx的全局变量参数解释:
    $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后。
    参考资料:
    1、http://blog.163.com/a12333a_li/blog/static/8759428520127645139124/
    2、http://www.onexin.net/nginx-rewrite-references/
  5. 缓存覆盖问题
    在nginx中设置缓存最先设置的将会覆盖后面设置的,参考案例:

    # 广告目录缓存5分钟
    location ~ /gg/(.*)\.(gif|jpg|jpeg|png|bmp|htm|html|css|js|flv|ico|swf)?$ {
      expires      300;
      access_log off;
    }
    
    location ~ .*\.(jpg|jpeg|gif|png|ico|asf|avi|fla|flv|mp3|mp4|rm|rmi|rmvb|wav|wma|wmv|7z|aiff|bmp|csv|doc|docx|gz|gzip|mid|xml|zip|mov|mpc|mepg|mpg|ods|odt|pdf|ppt|pptx|pxd|qt|ram|rar|rtf|sdc|sitd|swf|sxc|sxw|tar|tgz|tif|tiff|txt|vsd|xls|xlsx)$ {
      expires      7d;
      access_log off;
    }
    
  6. 规则错误 directive "rewrite" is not terminated by ";
    处理方法:将重定向后的url用双引号引起来!
    出错:rewrite ^/e/([a-z0-5]{6})$ /index.php?s=/element/elementInfo/shorttag/$1 last;
    正确:rewrite "^/e/([a-z0-5]{6})$" /index.php?s=/element/elementInfo/shorttag/$1 last;
    为什么有些必须要引号,有些又可以省略呢,仔细看第一条规则,里面出现了符号 “{6}”,应该是它造成的,因为配置文件中都是用它来作为配置的段起止标记,所以为了安全起见,最好还是都带上引号。
    参考资料:
    Nginx-Rewrite :http://dngood.blog.51cto.com/446195/1004837
  7. 关闭nginx空主机头 防止域名乱指向
    问题
    目前国内很多机房都要求网站主关闭nginx空主机头,防止未备案的域名指向过来造成麻烦
    设置
    nginx的默认配置中的虚拟主机允许用户通过IP访问,或者通过未设置的域名访问(比如有人把他自己的域名指向了你的ip)
    这是因为默认配置中的server区域里有这一行:
    listen 80 default;
    后面的default参数表示这个是默认虚拟主机,接受所有指向过来的域名
    比如别人通过ip或者未知域名访问你的网站的时候,你希望禁止显示任何有效内容,可以给他返回500.
    server {
    listen 80 default;
    return 500;
    }
    利用
    也可以把这些流量收集起来,导入到自己的网站,只要做以下跳转设置就可以:
    server {
    listen 80 default;
    rewrite ^(.*) http://www.yourdomain.com permanent;
    }
发表评论?

1 条评论。

  1. 持续关注此次的教学过程,也欢迎博主及时分享

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据