Nginx location的匹配规则


   ~      波浪线表示执行一个正则匹配,区分大小写
   ~*    表示执行一个正则匹配,不区分大小写
   ^~    ^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
   =      进行普通字符精确匹配
   @    #"@" 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files

location 匹配优先级

   = 精确匹配会第一个被处理。如果发现精确匹配,nginx停止搜索其他匹配。
   普通字符匹配,正则表达式规则和长的块规则将被优先和查询匹配,也就是说如果该项匹配还需去看有没有正则表达式匹配和更长的匹配。
   ^~ 则只匹配该规则,nginx停止搜索其他匹配,否则nginx会继续处理其他location指令。
   最后匹配理带有"~"和"~*"的指令,如果找到相应的匹配,则nginx停止搜索其他匹配;当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。

示例

location  = / {
 # 只匹配"/".
 [ configuration A ]
}
location  / {
 # 匹配任何请求,因为所有请求都是以"/"开始
 # 但是更长字符匹配或者正则表达式匹配会优先匹配
 [ configuration B ]
}
location ^~ /images/ {
 # 匹配任何以 /images/ 开始的请求,并停止匹配 其它location
 [ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
 # 匹配以 gif, jpg, or jpeg结尾的请求.
 # 但是所有 /images/ 目录的请求将由 [Configuration C]处理.  
 [ configuration D ]
}


URL 重写
仅是URL重写,不需要用location匹配,直接在server里写rewrite即可。

centos编译nginx

以下是自用的nginx编译归纳

yum安装常用包

yum -y update
yum -y install epel-release -y
yum install lua-devel git -y
yum -y --skip-broken install gcc  vim-enhanced gcc-c++ libtool-libs libtool autoconf subversion zip unzip  wget crontabs iptables file bison patch mlocate flex diffutils automake imake make cmake kernel-devel cpp zlib-devel

编译安装pcre

cd /tmp
wget -c http://sourceforge.net/projects/pcre/files/pcre/8.21/pcre-8.21.tar.gz/download -O -|tar xz
cd pcre-8.21
./configure
make && make install
if [ `uname -i` == x86_64 ]; then ln -s /usr/lib64/{libpcre.*,libjpeg.so,libpng.so,libXpm.so,libc-client.so,libkrb5.so,libexpat.so,libevent.so} /usr/lib/;fi

编译安装sregex

阅读剩余部分...

nginx过滤ApacheBench和WordPress的简单cc请求攻击

加入server段然后reload配置可以过滤掉低能的cc攻击。

if ($http_user_agent ~* (ApacheBench|pingback|WordPress|MJ12bot|AhrefsBot|360JK|PHP|php|Jorgee) ) {return 400;}
if ($http_user_agent = "" ) {return 101;}
if ( $request = "POST /reg.html HTTP/1.1" ) {return 400;}
if ( $request = "POST / HTTP/1.1" ) {return 400;}
if ( $request = "POST / HTTP/1.0" ) {return 400;}
if ( $request = "POST // HTTP/1.0" ) {return 400;}

使用Nginx+Lua实现Web项目的灰度发布

1.问题:小团队,快速迭代开发,版本发布没有经过测试就要放出去,怎样在内网测试过后在外网能在真实环境让内部人员再过一次测试且不影响外网用户

2.实现思想:

a.至少要有两台机器

b.公司是统一出口IP

c.根据IP将请求转发到不同的机器

阅读剩余部分...

nginx和MySQL安装加载gperftools模块

gperftools是google小组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if [ `uname -i` == "x86_64" ];
then
cd /tmp
wget -c http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz 
tar zxf libunwind-1.1.tar.gz
cd libunwind-1.1
./configure
make && make install
fi
cd /tmp
wget -c https://gperftools.googlecode.com/files/gperftools-2.0.tar.gz
tar zxf gperftools-2.0.tar.gz
cd gperftools-2.0
./configure  
make  && make install 
 
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
ldconfig
将编译好的libtcmalloc.so模块加入mysqld_safe启动的时候进行动态加载
1
2
sed -i 's/executing mysqld_safe/executing mysqld_safe\nexport LD_PRELOAD=\/usr\/local\/lib\/libtcmalloc.so/g'    /usr/bin/mysqld_safe
/etc/init.d/mysql restart
nginx不支持动态加载所以要重新编译
1
2
3
4
5
6
./configure 【其他参数】 --with-google_perftools_module
make && make install 
echo "google_perftools_profiles /tmp/tcmalloc;">>/etc/nginx/nginx.conf
/etc/init.d/nginx restart
mkdir /tmp/tcmalloc/ 
chmod  0777 /tmp/tcmalloc/

Nginx负载均衡与健康检查

   在业界,一直流传这样一句话:Nginx抗并发能力强!为什么Nginx抗并发能力强?原因是使用了非阻塞、异步传输
阻塞:如apache代理tomcat时,apache开启10个进程,同时处理着10个请求,在tomcat没有返回给apache结果时,apache是不会处理用户发出的第11个请求
非阻塞:如nginx代理tomcat时,nginx开启1000个并发,同时处理着1000个请求,在tomcat没有返回给nginx结果时,nginx会依然处理后面用户发给的请求
同步传输:比如squid代理tomcat时,浏览器发起请求,然后请求会squid立刻被转到后端服务器,于是在浏览器和后端服务器之间就建立了一个连接。在请求发起到请求完成,这条连接都是一直存在的。
异步传输:比如nginx代理tomcat时,浏览器发起请求,请求不会立刻转到后端服务器,而是将请求数据(header)先保存到nginx上,然后nginx再把这个请求发到后端服务器, 后端服务器处理完之后把数据返回到nginx上,nginx将数据流发到浏览器。

     如上图所示假设用户执行一个上传文件操作,由于用户网速较慢,因此需要花半个小时才能把文件传到服务器。squid的同步代理在用户开始上传后就和 后端tomcat建立了连接,半小时后文件上传结束,所以,后端tomcat服务器连接保持了半个小时;而nginx异步代理就是先将数据保存在 nginx上,因此仅仅是nginx和用户 保持了半小时连接,后端服务器在这半小时内没有为这个请求开启连接,半小时后用户上传结束,nginx才将上传内容发到后端tomcat,nginx和后 台之间的带宽 是很充裕的,所以只花了一秒钟就将请求发送到了后台,由此可见,后端服务器连接保持了一秒。

阅读剩余部分...

dedecms免疫漏洞之nginx

在nginx的配文件里面server段下面添加
rewrite /(plus|member|special|include|data|a|images|templets|uploads|dede)/(.*)\.(pl|php|cgi|asp|aspx|py|jsp) http://cachefly.cachefly.net/100mb.test redirect;

上面是用rewrite重定向的方法还有第二种方法用location
location ~(plus|member|special|include|data|a|images|templets|uploads|dede)/(.*)\.(pl|php|cgi|asp|aspx|py|tpl|jsp) {return 400;}
然后 reload或者restart一下nginx就可以了,上面的规则是直接给请求者返回一个100M的包,当然你也可以修改成其他的,详细用法参照http://wiki.nginx.org 



Nginx中禁止访问.txt文件

location ~* \.(txt|doc)$ {
               if (-f $request_filename) {
                  root /home/domain/public_html/test;
                  break;
                  }
               }

Nginx出现413 Request Entity Too Large

处理Nginx出现的413 Request Entity Too Large错误
这个错误一般在上传文件的时候出现,打开nginx主配置文件nginx.conf,找到http{}段,添加

client_max_body_size 8m;

重新加载nginx的配置
nginx -t
kill -HUP nginx_pid

要是跑php的话这个大小client_max_body_size要和php.ini中的如下值的最大值一致或者稍大,这样就不会因为提交数据大小不一致出现的错误。
post_max_size = 8M
upload_max_filesize = 2M

重启php-cgi
killall php_cgi
php_cgi start

Nginx 的编译安装

# tar zxvf nginx-0.6.29-tar.gz
# cd nginx-0.6.29
  ./configure \
    "--prefix=/usr/local/nginx" \
    "--sbin-path=/usr/local/nginx/sbin/nginx" \
    "--conf-path=/usr/local/nginx/conf/nginx.conf" \
    "--error-log-path=/usr/local/nginx/logs/error.log" \
    "--http-log-path=/usr/local/nginx/logs/access.log" \
    "--pid-path=/usr/local/nginx/var/nginx.pid" \
    "--lock-path=/usr/local/nginx/var/nginx.lock" \
    "--http-client-body-temp-path=/dev/shm//nginx_temp/client_body" \
    "--http-proxy-temp-path=/dev/shm/nginx_temp/proxy" \
    "--http-fastcgi-temp-path=/dev/shm/nginx_temp/fastcgi" \
    "--user=www" \
    "--group=www" \
    "--with-cpu-opt=pentium4F" \
    "--without-select_module" \
    "--without-poll_module" \
    "--with-http_realip_module" \
    "--with-http_sub_module" \
    "--with-http_gzip_static_module" \
    "--with-http_stub_status_module" \
    "--without-http_ssi_module" \
    "--without-http_userid_module" \
    "--without-http_geo_module" \
    "--without-http_memcached_module" \
    "--without-http_map_module" \
    "--without-mail_pop3_module" \
    "--without-mail_imap_module" \
    "--without-mail_smtp_module" \
    "--with-pcre"
# make
# make install

# mkdir /dev/shm/nginx_temp

注:有时会因为pcre编译不过去,需要修改一下 --with-pcre=/usr/local/src/pcre-7.8,前提是已经下载了pcre源码包,并解压,不需要编译pcre。

nginx打开目录浏览功能

nginx默认是不允许列出整个目录的。如需此功能,
        打开nginx.conf文件,在location server 或 http段中加入
        autoindex on;
        另外两个参数最好也加上去:

autoindex_exact_size off;
默认为on,显示出文件的确切大小,单位是bytes。
改为off后,显示出文件的大概大小,单位是kB或者MB或者GB

        autoindex_localtime on;
      默认为off,显示的文件时间为GMT时间。
      改为on后,显示的文件时间为文件的服务器时间

详细参照:http://wiki.nginx.org/NginxChsHttpAutoindexModule

关于Nginx遇到*.php的错误页面不能跳转问题


1、最简单的重定向404页面(404.html为自定义的页面)

error_page  404  /404.html;

2、需要重定向4**  5** 的所有的页面(error.html为自定义页面)

error_page 402 403 404 500 502 503 504 /error.html;

3、需要重定向请求错误的php页面

如果是一般的文件上面的都可以解决,但是如果是PHP的,就会出no input file specified.或者是直接在浏览器输出404
需要在主配置文件nginx.conf 中 fastcgi  位置加上   fastcgi_intercept_errors on; 默认是关闭的

PS:特别注意的是404.html(自定义的文件)文件页面大小要超过512k,不然会被ie浏览器替换为ie默认的错误页面。

总结:需要将*.php的错误页面跳转的三步骤:
  1,自定义404.html或404.php的跳转页面,文件大小超过512k
  2,主配置文件nginx.conf加入fastcgi_intercept_errors on参数
  3,error_page设置,需要将哪些系统返回状态做跳转

【转帖】Nginx优化use参数epoll,kqueue,rtsig,eventport,poll

源自:www.nginx8.cn
下图对比了poll select epoll和kqueue的性能。select和poll是一个级别的,epoll和kqueue是一个级别的,相差不多。epoll用在linux上,kqueue用在bsd上,不能物理上共存。如果你的服务器cpu较好,linux内核新,可考虑用epoll.



Basically what this says is that FreeBSD's kqueue out-performs Linux's epoll by a bit.

select() and poll() are anachronisms.

As an aside, libevent rocks and I use it all the time for writing portable network code. It allows you to use the best available I/O multiplexing functionality on a given platform without having to write seperate code for all of them via a fairly coder-friendly API, and has a nice little async DNS library with it to boot.
Macro的某个机器(centos5.3,e7300)的nginx从默认的没有use设置改为use epoll后实际情况 load average: 0.14, 0.21, 0.26,负载似乎减少了0.1,可能并发请求量不大,暂时没看出有多大效果 :
Active connections: 2548 server accepts handled requests 35279765 35279765 59264847 Reading: 13 Writing: 16 Waiting: 2519   
freebsd里的kqueue和linux 2.6下的epoll
   两个东西极其相似,写好了一个之后,移到别外一个平台下,只要稍作修改就可以了,原理是一样,个人认为,从功能角度来盾kqueue比epoll灵活得多。在写kqueue的时候,内核帮你考虑好了不少东西。但是从效率来看,从我作的压力测试来看epoll比kqueue强。看看我的实验结果吧
客户端: linux ,P3,256M ,pthread多线程程序,开1万个线程,可是实际运行结果是,在linux2.4上只能打开4000多个线程的时候就报资源不足,郁闷了好久,不知道是什么资源,最大打开文件数是够了,内存也够(通过设置16k的栈空间)。后来把客户端移到linux2.6内核下,很快开出1万个线程来了。
epoll服务器端:P3,256M,在一万个并发线程下,面不改色,有条不紊地处理着数据,并发数能达到8000个连接。
kqueue 服务器端:结果比较失望,在只能一条队列的情况下,并发数只能到2000,然后在客户端的读取数据时就会出现"connect reset by peer"的错误。后来改用了两条队列,一条用来接收新连接,一条用来处理原有的连接。在这种情况下,并发数也只能到3000,然后又会陆陆续续出现连接的错误。


Nginx优化use参数epoll,kqueue,rtsig,eventport,poll和select的区别

参考:http://wiki.nginx.org/NginxOptimizations
Event ModelsNginx supports the following methods of treating the connections, which can be assigned by the use directive:
select - standard method. Compiled by default, if the current platform does not have a more effective method. You can enable or disable this module by using configuration parameters --with-select_module and --without-select_module.poll - standard method. Compiled by default, if the current platform does not have a more effective method. You can enable or disable this module by using configuration parameters --with-poll_module and --without-poll_module.kqueue - the effective method, used on FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 and MacOS X. With dual-processor machines running MacOS X using kqueue can lead to kernel panic.epoll - the effective method, used on Linux 2.6+. In some distrubutions, like SuSE 8.2, there are patches for supporting epoll by kernel version 2.4.rtsig - real time signals, the executable used on Linux 2.2.19+. By default no more than 1024 POSIX realtime (queued) signals can be outstanding in the entire system. This is insufficient for highly loaded servers; it's therefore necessary to increase the queue size by using the kernel parameter /proc/sys/kernel/rtsig-max However, starting with Linux 2.6.6-mm2, this parameter is no longer available, and for each process there is a separate queue of signals, the size of which is assigned by RLIMIT_SIGPENDING. When the queue becomes overcrowded, nginx discards it and begins processing connections using the poll method until the situation normalizes./dev/poll - the effective method, used on Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ and Tru64 UNIX 5.1A+.eventport - the effective method, utilized in Solaris 10. To avoid kernel panic, it is necessary to install this security patch.

Nginx的主配置文件

user  www  www;
worker_processes  4;                           
##开启4个进程,经我测试2足够,如果你服务器cpu资源很多,那么就分配为cpu的1倍或2倍

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        var/nginx.pid;
worker_rlimit_nofile 51200;                 
##指一个nginx进程打开的最大文件描述符个数,理论值应该和(ulimit -n )结果数值和nginx进程数值相除的结果一致,但实际中不可能有这样均匀,所以最好和ulimit -n 的值一致。

events {
    use epoll;   
##使用epoll的I/O模型
    worker_connections  4096;  
##每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为worker_processes * worker_connections
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    server_names_hash_max_size 512;
    server_names_hash_bucket_size 128;

    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;

    keepalive_timeout  1;  
##keepalive超时时间
    client_header_timeout 10;
    client_body_timeout   10;
    send_timeout          30;

    client_header_buffer_size    4k;  
##客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得
#   open_file_cache max=51200 inactive=20s;  
##这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存
#   open_file_cache_valid 30s;
##这个是指多长时间检查一次缓存的有效信息
#   open_file_cache_min_uses 1;
##open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。
    large_client_header_buffers  4 4k;
    client_body_temp_path  /dev/shm/nginx_temp/client_body 1 2;

######
##一般情况下压缩后的html、css、js、php、jhtml等文件,大小能降至原来的25%,也就是说,原本一个100k的html,压缩后只剩下25k。这无疑能节省很多带宽,也能降低服务器的负载。
######
    gzip on;   //打开gzip压缩
    gzip_min_length  1024;  
##设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取,默认值是0,不管页面多大都压缩,建议设置成1024,小于1k可能会越压越大
    gzip_buffers     4 8k;
##设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。例如 4 4k 代表以4k为单位,按照原始数据大小以4k为单位的4倍申请内存。 4 8k 代表以8k为单位,按照原始数据大小以8k为单位的4倍申请内存。如果没有设置,默认值是申请跟原始数据相同大小的内存空间去存储gzip压缩结果。

    gzip_http_version 1.1;  
##识别http的协议版本。由于早期的一些浏览器或者http客户端,可能不支持gzip自解压,用户就会看到乱码,所以做一些判断还是有必要的。注:现在除了类似于百度的蜘蛛之类的东西不支持自解压,99.99%的浏览器基本上都支持gzip解压了,所以可以不用设这个值,保持系统默认即可。
    gzip_comp_level 5;  
##gzip压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理最慢(传输快但比较消耗cpu)。
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
##匹配MIME类型进行压缩,(无论是否指定)"text/html"类型总是会被压缩的。

    log_format main '$remote_addr - $remote_user [$time_local] $request '
                    '"$status" $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';   
##记录日志的格式,这里的main是自定义的,目的是在后边的vhosts/* 中用到
    access_log "logs/access.log" main;
##规定记录日志的文件,格式为main格式(上边定义的)

    include vhosts/*;   //vhosts/目录下就是我们的虚拟主机配置文件了
}

【转】Nginx 的 server_names_hash_bucket_size 问题

在 Nginx 0.6.35 的版本中,配置多个 server 虚拟主机,必须要在配置文档中 http { 里头加上 server_names_hash_bucket_size 64; 这么一句

http {

server_names_hash_bucket_size 64;

include mime.types;
default_type application/octet-stream;
………….省略

}

不然不但 nginx 启动不了,而且 nginx -t 测试配置文档的时候会提示

could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32
2009/02/20 13:54:27 [emerg] 11372#0: the configuration file /opt/nginx/conf/nginx.conf test failed

  下面是在中文wiki上摘抄的一段说明
  保存服务器名字的hash表是由指令 server_names_hash_max_size 和 server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果 hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大 hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小.