访问限制
- http {
- ...
- limit_req_zone $binary_remote_addr zone=allips:10m rate=100r/s; #100r/s表示每秒钟100请求,100r/m表示每分钟
- ...
- }
- server {
- ...
- limit_req zone=allips nodelay; #超过限制直接返回503错误
- limit_req zone=allips burst=50; #可有50个处于等待状态
- ...
- }
routeros
配置示例
- worker_processes 2;
- error_log /www/logs/nginx/error.log warn;
- pid /var/run/nginx.pid;
- events {
- worker_connections 20240;
- multi_accept on;
- use epoll;
- }
- http {
- include mime.types;
- default_type application/octet-stream;
- log_format main '$remote_addr - [$time_local] - "$http_host $request" '
- '$status $body_bytes_sent "$http_referer" '
- '"$http_user_agent" "$http_x_forwarded_for" "$upstream_addr"';
- access_log /www/logs/nginx/access.log main;
- sendfile on;
- tcp_nopush on;
- tcp_nodelay off;
- client_max_body_size 2048m;
- keepalive_timeout 65;
- gzip on;
- gzip_min_length 1k;
- gzip_comp_level 9;
- gzip_vary on;
- gzip_buffers 16 8k;
- gzip_types text/plain text/css application/javascript application/json text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png;
- open_file_cache max=200000 inactive=20s;
- open_file_cache_valid 30s;
- open_file_cache_min_uses 2;
- open_file_cache_errors on;
- client_body_timeout 240;
- send_timeout 3;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Host $Host;
- proxy_headers_hash_max_size 51200;
- proxy_headers_hash_bucket_size 6400;
- proxy_read_timeout 180;
- proxy_send_timeout 5;
- proxy_buffer_size 128k;
- proxy_buffers 100 128k;
- proxy_busy_buffers_size 256k;
- proxy_temp_file_write_size 256k;
- proxy_temp_path /tmp/temp_dir;
- proxy_cache_path /tmp/cache levels=1:2 keys_zone=cache_one:100m inactive=1d max_size=2g;
- location /login {
- proxy_pass http://target_servers/login ;
- proxy_redirect http://$host/ http://$http_host/;
- #其中host不带端口的,也就是nginx部署的主机ip,而$http_host是带端口的
- }
- include ./conf.d/*.conf;
- }
nginx
Nginx配置参数解析
- worker_processes 定义了nginx对外提供web服务时的worker进程数。最优值取决于许多因素,包括(但不限于)CPU核的数量、存储数据的硬盘数量及负载模式。不能确定的时候,将其设置为可用的CPU内核数将是一个好的开始(设置为“auto”将尝试自动检测它)。
- worker_rlimit_nofile 更改worker进程的最大打开文件数限制。如果没设置的话,这个值为操作系统的限制。设置后你的操作系统和Nginx可以处理比“ulimit -a”更多的文件,所以把这个值设高,这样nginx就不会有“too many open files”问题了。
- worker_connections 设置可由一个worker进程同时打开的最大连接数。如果设置了上面提到的worker_rlimit_nofile,我们可以将这个值设得很高。
- 记住,最大客户数也由系统的可用socket连接数限制(~ 64K),所以设置不切实际的高没什么好处。
- multi_accept 告诉nginx收到一个新连接通知后接受尽可能多的连接。
- use 设置用于复用客户端线程的轮询方法。如果你使用Linux 2.6+,你应该使用epoll。如果你使用*BSD,你应该使用kqueue。
- server_tokens 并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。
- sendfile 可以让sendfile()发挥作用。sendfile()可以在磁盘和TCP socket之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile是传送数据之前在用户空间申请数据缓冲区。之后用read()将数据从文件拷贝到这个缓冲区,write()将缓冲区数据写入网络。sendfile()是立即将数据从磁盘读到OS缓存。因为这种拷贝是在内核完成的,sendfile()要比组合read()和write()以及打开关闭丢弃缓冲更加有效(更多有关于sendfile)。
- include 只是一个在当前文件中包含另一个文件内容的指令
- default_type 设置文件使用的默认的MIME-type。
- charset 设置我们的头文件中的默认的字符集
- limit_conn_zone 设置用于保存各种key(比如当前连接数)的共享内存的参数。5m就是5兆字节,这个值应该被设置的足够大以存储(32K*5)32byte状态或者(16K*5)64byte状态。
- limit_conn 为给定的key设置最大连接数。这里key是addr,我们设置的值是100,也就是说我们允许每一个IP地址最多同时打开有100个连接。
- keepalive_timeout 给客户端分配keep-alive链接超时时间。服务器将在这个超时时间过后关闭链接。我们将它设置低些可以让ngnix持续工作的时间更长。
- client_header_timeout 和client_body_timeout 设置请求头和请求体(各自)的超时时间。我们也可以把这个设置低些。
- reset_timeout_connection 告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。
- send_timeout 指定客户端的响应超时时间。这个设置不会用于整个转发器,而是在两次客户端读取操作之间。如果在这段时间内,客户端没有读取任何数据,nginx就会关闭连接。
- gzip 是告诉nginx采用gzip压缩的形式发送数据。这将会减少我们发送的数据量。
- gzip_disable 为指定的客户端禁用gzip功能。我们设置成IE6或者更低版本以使我们的方案能够广泛兼容。
- gzip_static 告诉nginx在压缩资源之前,先查找是否有预先gzip处理过的资源。这要求你预先压缩你的文件(在这个例子中被注释掉了),从而允许你使用最高压缩比,这样nginx就不用再压缩这些文件了(想要更详尽的gzip_static的信息,请点击这里)。
- gzip_proxied 允许或者禁止压缩基于请求和响应的响应流。我们设置为any,意味着将会压缩所有的请求。
- gzip_min_length 设置对数据启用压缩的最少字节数。如果一个请求小于1000字节,我们最好不要压缩它,因为压缩这些小的数据会降低处理此请求的所有进程的速度。
- gzip_comp_level 设置数据的压缩等级。这个等级可以是1-9之间的任意数值,9是最慢但是压缩比最大的。我们设置为4,这是一个比较折中的设置。
- gzip_type 设置需要压缩的数据格式
- open_file_cache 打开缓存的同时也指定了缓存最大数目,以及缓存的时间。我们可以设置一个相对高的最大时间,这样我们可以在它们不活动超过20秒后清除掉。
- open_file_cache_valid 在open_file_cache中指定检测正确信息的间隔时间。
- open_file_cache_min_uses 定义了open_file_cache中指令参数不活动时间期间里最小的文件数。
- open_file_cache_errors 指定了当搜索一个文件时是否缓存错误信息,也包括再次给配置中添加文件。我们也包括了服务器模块,这些是在不同文件中定义的。如果你的服务器模块不在这些位置,你就得修改这一行来指定正确的位置。
lsl
Nginx下的rewrite规则
- 一.正则表达式匹配,其中:
- * ~ 为区分大小写匹配
- * ~* 为不区分大小写匹配
- * !~和!~*分别为区分大小写不匹配及不区分大小写不匹配
- 二.文件及目录匹配,其中:
- * -f和!-f用来判断是否存在文件
- * -d和!-d用来判断是否存在目录
- * -e和!-e用来判断是否存在文件或目录
- * -x和!-x用来判断文件是否可执行
- 三.rewrite指令的最后一项参数为flag标记,flag标记有:
- 1.last 相当于apache里面的[L]标记,表示rewrite。
- 2.break 本条规则匹配完成后,终止匹配,不再匹配后面的规则。
- 3.redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址。
- 4.permanent 返回301永久重定向,浏览器地址会显示跳转后的URL地址。
- 使用last和break实现URI重写,浏览器地址栏不变。而且两者有细微差别,使用alias指令必须用last标记;使用proxy_pass指令时,需要使用break标记。Last标记在本条rewrite规则执行完毕后,会对其所在server{......}标签重新发起请求,而break标记则在本条规则匹配完成后,终止匹配。
nimrod
Apache和Nginx规则的对应关系
- RewriteCond对应Nginx的if
- RewriteRule对应Nginx的rewrite
- [R]对应Nginx的redirect
- [P]对应Nginx的last
- [R,L]对应Nginx的redirect
- [P,L]对应Nginx的last
- [PT,L]对应Nginx的last
cs
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 themachine’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 #请求到达服务器的端口号。
mipsasm
location正则写法
- location = / {
- # 精确匹配 / ,主机名后面不能带任何字符串
- [ configuration A ]
- }
- location / {
- # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
- # 但是正则和最长字符串会优先匹配
- [ configuration B ]
- }
- location /documents/ {
- # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
- # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
- [ configuration C ]
- }
- location ~ /documents/Abc {
- # 匹配任何以 /documents/Abc 开头的地址,匹配符合以后,还要继续往下搜索
- # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
- [ configuration CC ]
- }
- location ^~ /images/ {
- # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
- [ configuration D ]
- }
- location ~* \.(gif|jpg|jpeg)$ {
- # 匹配所有以 gif,jpg或jpeg 结尾的请求
- # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
- [ configuration E ]
- }
- location /images/ {
- # 字符匹配到 /images/,继续往下,会发现 ^~ 存在
- [ configuration F ]
- }
- location /images/abc {
- # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
- # F与G的放置顺序是没有关系的
- [ configuration G ]
- }
- location ~ /images/abc/ {
- # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
- [ configuration H ]
- }
- location ~* /js/.*/\.js
- * = 开头表示精确匹配
- 如 A 中只匹配根目录结尾的请求,后面不能带任何字符串。
- * ^~ 开头表示uri以某个常规字符串开头,不是正则匹配
- * ~ 开头表示区分大小写的正则匹配;
- * ~* 开头表示不区分大小写的正则匹配
- * / 通用匹配, 如果没有其它匹配,任何请求都会匹配到
crmsh
顺序 no优先级:
- > (location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)
- 上面的匹配结果
- 按照上面的location写法,以下的匹配示例成立:
- 1. / -> config A
- 精确完全匹配,即使/index.html也匹配不了
- 2. /downloads/download.html -> config B
- 匹配B以后,往下没有任何匹配,采用B
- 3. /images/1.gif -> configuration D
- 匹配到F,往下匹配到D,停止往下
- 4. /images/abc/def -> config D
- 最长匹配到G,往下匹配D,停止往下
- 你可以看到 任何以/images/开头的都会匹配到D并停止,FG写在这里是没有任何意义的,H是永远轮不到的,这里只是为了说明匹配顺序
- 5. /documents/document.html -> config C
- 匹配到C,往下没有任何匹配,采用C
- 6. /documents/1.jpg -> configuration E
- 匹配到C,往下正则匹配到E
- 7. /documents/Abc.jpg -> config CC
- 最长匹配到C,往下正则顺序匹配到CC,不会往下到E
routeros
实际使用建议
- 所以实际使用中,个人觉得至少有三个匹配规则定义,如下:
- #直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
- #这里是直接转发给后端应用服务器了,也可以是一个静态首页
- # 第一个必选规则
- location = / {
- proxy_pass http://tomcat:8080/index
- }
- # 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
- # 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
- location ^~ /static/ {
- root /webroot/static/;
- }
- location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
- root /webroot/res/;
- }
- #第三个规则就是通用规则,用来转发动态请求到后端应用服务器
- #非静态文件请求就默认是动态请求,自己根据实际把握
- #毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
- location / {
- proxy_pass http://tomcat:8080/
- }
crmsh
日志按天自动切割
- #######################
- ##用法:include conf.d/params_log;
- #####
- #######################
- if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") {
- set $ng_log_year $1;
- set $ng_log_month $2;
- set $ng_log_day $3;
- }
- access_log logs/$server_name-$ng_log_year$ng_log_month$ng_log_day.log main;
clean
http://tengine.taobao.org/book/chapter_02.html http://nginx.org/en/docs/http/ngx_http_rewrite_module.html
Rewrite规则
abc.com 跳转到www.abc.com
- # 在server中添加
- if ( $host != 'www.abc.com') {
- rewrite ^/(.*) http://www.abc.com/$1 permanent;
- }
nginx
rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。rewrite只能放在server{},location{},if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用,例如 http://seanlook.com/a/we/index.php?id=1&u=str 只对/a/we/index.php重写。语法rewrite regex replacement [flag];
如果相对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用proxy_pass反向代理。
表明看rewrite和location功能有点像,都能实现跳转,主要区别在于rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。很多情况下rewrite也会写在location里,它们的执行顺序是:
- 执行server块的rewrite指令
- 执行location匹配
- 执行选定的location中的rewrite指令
如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件;循环超过10次,则返回500 Internal Server Error错误。
flag标志位
last : 相当于Apache的[L]标记,表示完成rewrite break : 停止执行当前虚拟主机的后续rewrite指令集 redirect : 返回302临时重定向,地址栏会显示跳转后的地址 permanent : 返回301永久重定向,地址栏会显示跳转后的地址 因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。这里 last 和 break 区别有点难以理解:
last一般写在server和if中,而break一般使用在location中 last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配 break和last都能组织继续执行后面的rewrite指令
if指令与全局变量
if判断指令 语法为if(condition){...},对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行,if条件(conditon)可以是如下任何内容:
当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false
直接比较变量和内容时,使用=或!=
正则表达式匹配,*不区分大小写的匹配,!~区分大小写的不匹配
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
例如:
- if ($http_user_agent ~ MSIE) {
- rewrite ^(.*)$ /msie/$1 break;
- } //如果UA包含"MSIE",rewrite请求到/msid/目录下
- if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
- set $id $1;
- } //如果cookie匹配正则,设置变量$id等于正则引用部分
- if ($request_method = POST) {
- return 405;
- } //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
- if ($slow) {
- limit_rate 10k;
- } //限速,$slow可以通过 set 指令设置
- if (!-f $request_filename){
- break;
- proxy_pass http://127.0.0.1;
- } //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
- if ($args ~ post=140){
- rewrite ^ http://example.com/ permanent;
- } //如果query string中包含"post=140",永久重定向到example.com
- location ~* \.(gif|jpg|png|swf|flv)$ {
- valid_referers none blocked www.jefflei.com www.leizhenfang.com;
- if ($invalid_referer) {
- return 404;
- } //防盗链
- }
stata
Nginx下的rewrite规则
- . : 匹配除换行符以外的任意字符
- ? : 重复0次或1次
- + : 重复1次或更多次
- * : 重复0次或更多次
- \d :匹配数字
- ^ : 匹配字符串的开始
- $ : 匹配字符串的介绍
- {n} : 重复n次
- {n,} : 重复n次或更多次
- [c] : 匹配单个字符c
- [a-z] : 匹配a-z小写字母的任意一个
- 小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。
lsl
rewrite实例
例1:
- http {
- # 定义image日志格式
- log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
- # 开启重写日志
- rewrite_log on;
- server {
- root /home/www;
- location / {
- # 重写规则信息
- error_log logs/rewrite.log notice;
- # 注意这里要用‘’单引号引起来,避免{}
- rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
- # 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行
- set $image_file $3;
- set $image_type $4;
- }
- location /data {
- # 指定针对图片的日志格式,来分析图片类型和大小
- access_log logs/images.log mian;
- root /data/images;
- # 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里
- try_files /$arg_file /image404.html;
- }
- location = /image404.html {
- # 图片不存在返回特定的信息
- return 404 "image not found\n";
- }
- }
nginx
对形如/images/ef/uh7b3/test.png的请求,重写到/data?file=test.png,于是匹配到location /data,先看/data/images/test.png文件存不存在,如果存在则正常响应,如果不存在则重写tryfiles到新的image404 location,直接返回404状态码。
例2:
- rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
对形如/images/bla_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。
例3: 见 ssl部分页面加密 。
nginx获取访问IP
- location /ip {
- default_type text/json;
- content_by_lua '
- local headers=ngx.req.get_headers()
- local ip=headers["X-REAL-IP"] or headers["X_FORWARDED_FOR"] or ngx.var.remote_addr or "0.0.0.0"
- ngx.say(ip)
- ';
- }
applescript
参考
http://www.nginx.cn/216.html http://www.ttlsa.com/nginx/nginx-rewriting-rules-guide/ 老僧系列nginx之rewrite规则快速上手 http://fantefei.blog.51cto.com/2229719/919431
Comments
热评话题