nginx常用模块介绍

nginx使用geo模块 nginx常用模块介绍_nginx

 

IP访问控制模块

用来对特定IP的进行访问控制 默认是允许所有ip访问,

若部分允许需定义 deny all

location  ~.*\.(sql|log|txt|jar|war|sh|py|php)  {

 deny all;

}

 

比如可以限制某些目录下的某些文件的访问,具体可以自己组合禁止访问所有目录下的 sql|log|txt|jar|sh|py 后缀的文件,

 

location  ~.*\.(sql|log|txt|jar|war|sh|py|php)  {

 deny all;

}

对客户端进行限制相关配置-预防CC攻击

一般在下面的需求: 秒杀、抢购并发限制 下载带宽限制 防止攻击

limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法

limit_req_conn 用来限制同一时间连接数,即并发限制

nginx 限制连接数 ngx_http_limit_conn_module 模块

1、用于限制每个已定义键的连接数特别是来自单个IP地址的连接数。并不是所有的连接都被计算在内。只有当服务器处理了一个请求,并且整个请求头已经被 读取时,才会计算连接。

语法: limit_conn_zone $binary_remote_addr zone=addr:10m;

默认值: none

配置段: http

例子:limit_conn_zone $binary_remote_addr zone=addr:10m;

说明:区域名称为addr,大小为10m,键值是客户端IP。 如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回  503 (Service Temporarily Unavailable)错误。

2、设置允许一个IP同时的连接数。

location / {

deny  192.168.1.1; 

allow  192.168.1.0/24; 

allow  xx.xx.xx.xx;

deny  all;

}

 

nginx限制请求数 limit_req_zone

语法: limit_req_zone $variable zone=name:size rate=rate;

默认值: none

配置段: http

例子:limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

Zone=one 表示设置了名为・one・,大小为10兆字节

rate=10r/s   的意思是允许1秒钟不超过10个请求

使用$binary_remote_addr变量,可以将每条状态记录的大小减少到64个字节,这样1M的内存可以保存大约1万6千个64字节的记录。 如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回  503 (Service Temporarily Unavailable)错误。 速度可以设置为每秒处理请求数和每分钟处理请求数,其值必须是整数,所以如果你需要指定每秒处理少于1个的请求,2秒处理一个请求,可以使用

“30r/m”。

可选参数:

rate=10r/s   的意思是允许1秒钟不超过10个请求

burst=5   允许超过频率限制的请求数不多于5个,假设1、2、3、4秒请求为每秒9个,那么第5秒内请求15个是允许的,反之,如果第一秒内请求15个,会将5个请求放到第二秒,第二秒内超过10的请求直接503,类似多秒内平均速率限制。

nodelay  超过的请求不被延迟处理,设置后15个请求在1秒内处理。

 

关于漏桶算法

漏桶(Leaky Bucket)算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(访问频率超过接口响应速率),

然后就拒绝请求,可以看出漏桶算法能强行限制数据的传输速率.示意图如下:

可见这里有两个变量,一个是桶的大小,支持流量突发增多时可以存多少的水(burst),另一个是水桶漏洞的大小(rate)

连接限制跟请求限制,会对所有的ip进行限制,我们不希望自己的测试的ip,或者搜索引擎蜘蛛受到限制 ngx_http_geo_module 模块创建变量,并根据客户端IP 地址对变量赋值

nginx使用geo模块 nginx常用模块介绍_nginx_02

 

请求失败的结果

ab -n20 -c10 http://127.0.0.1/

 

rewrite模块(ngx_http_rewrite_module)

rewrite 的主要功能是实现URL地址的重定向。 Nginx 的 rewrite 功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译

nginx 就会支持 rewrite 的模块,但是也必须要PCRE的支持。

使用场景:

1、可以调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求。

2、为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。

3、网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的360buy.com会跳转到jd.com

4、根据特殊变量、目录、客户端的信息进行URL调整等

 

if指令

语法:if(condition){・} 区块:server,location

该指令用于检查一个条件是否符合,如果条件符合,则执行大括号内的语句。if指令不支持嵌套,不支持多个条件&&和||处理。 其中,condition中可以包含的判断标识如下

~为区分大小写匹配

~*为不区分大小写匹配

-f和!-f用来判断是否存在文件

-d和!-d用来判断是否存在目录

-e和!-e用来判断是否存在文件或目录

-x和!-x用来判断文件是否可执行

if ($http_user_agent~*(mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)) { rewrite  ^(.*) http://www..baidu.com$1 permanent;

}

return指令

语法:return code [text] return code URL;
return URL;

区块:server,location,if 该指令用于结束规则的执行并返回状态吗给客户端。 状态码包括:
204(No  Content)、400(Bad  Request)、402(Payment  Required)、403(Forbidden) 404(Not  Found)、405(Method  Not  Allowed)、406(Not  Acceptable)、   408(Request  Timeout)、410(Gone)、411(Length  Required)、
413(Request Entity Too Large)、416(Requested Range Not Satisfiable)、 500(Internal Server Error)、501(Not Implemented)、502(Bad Gateway)、 503(Service Unavailable)和504(Gateway Timeout)。

例如,示例,如果访问的URL以.sh  .bash  结尾,返回状态码403 location   ~   .*\.(sh|bash)?$
{
return  403;
}

Rewrite语法

语法:rewrite regex replacement [flag];
默认值:・
上下文:server, location, if

rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。 正则:perl兼容正则表达式语句进行规则匹配
替代内容:将正则匹配的内容替换成replacement flag标记:rewrite支持的flag标记

last标记说明

last   #本条规则匹配完成后,继续向下匹配新的location URI规则 结束当前的请求处理,用替换后的URI重新匹配location; 可理解为重写(rewrite)后,发起了一个新请求,进入server模块,匹配locaton; 如果重新匹配循环的次数超过10次,nginx会返回500错误;

break    #本条规则匹配完成即终止,不再匹配后面的任何规则 结束当前的请求处理,使用当前资源,不在执行location里余下的语句

redirect	#返回302临时重定向,浏览器地址会显示跳转后的URL地址 permanent  #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

nginx防盗链实现

语法:	valid_referers none | blocked | server_names | string ...;
默认值:  ・
上下文: server, location

Referer”请求头为指定值时,内嵌变量$invalid_referer被设置为空字符串,    否则这个变量会被置成・1・。查找匹配时不区分大小写。 该指令的参数可以为下面的内容:
none
缺少・Referer・请求头;

blocked
“Referer” 请求头存在,但是它的值被防火墙或者代理服务器删除; 这些值都不以・http://・ 或者 ・https://・字符串作为开头; server_names
“Referer”  请求头包含某个虚拟主机名;

防止别人直接从你网站引用图片等链接,消耗了你的资源和网络流量,那么我们的  就可以设置防盗链策略下面的方法是直接给予404的错误提示,或者是 显示一个图片

location   ~*   ^.+\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$   { valid_referers none blocked www.baidu.com baidu.com;
if($invalid_referer){
#return  302     http://www.xxxx.com/img/nolink.jpg;
return 404; break;
}

 

nginx缓存机制

什么是缓存?

Web缓存是可以自动保存常见文档副本的HTTP 设备。当Web请求抵达缓存时,如果本地有“已缓存的”副本,就可以从本地设备而不是服务器中提取这个文档。

为什么使用缓存?

缓存减少了冗余的数据传输,节约了网络费用 缓存缓解了网络瓶颈的问题,对于带宽的要求 缓存降低了对原始服务器的要求,降低服务器压力 缓存加速了页面的展示

缓存的分类:

缓存分为服务端侧(比如 Nginx,redis,memcached)和客户端侧(比如 web browser)。

服务端缓存又分为 代理服务器缓存 和 反向代理服务器缓存(也叫网关缓存,比如 Nginx反向代理就可以设置缓存) 客户端侧缓存一般指的是浏览器缓存、app缓存等等,目的就是加速各种静态资源的访问,降低服务器压力。 简单看看浏览器的缓存规则:

第一次访问某个网站

nginx使用geo模块 nginx常用模块介绍_nginx_03

 

第二次访问某个网站

nginx使用geo模块 nginx常用模块介绍_缓存_04

 

我们发现多了一些字段关于这些字段的详细介绍

HTTP 缓存控制头介绍

HTTP 中最基本的缓存机制,涉及到的 HTTP 头字段,包括 Cache-Control, Last-Modified, If-Modified-Since, Etag, If-None-Match 等

Last-Modified/If-Modified-Since

Last-Modified :标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。

If-Modified-Since :当资源过期时(使用Cache-Control标识的max-age),发现资源具有 Last-Modified 声明,则再次向web服务器请求时带上头 I

f-Modified-Since ,表示请求时间。web服务器收到请求后发现有头 If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说

明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应 HTTP 304 (无需包体,节省浏

览),告知浏览器继续使用所保存的 cache 。

当我们按下f5刷新的时候,我们看看浏览器发送的请求头:

nginx使用geo模块 nginx常用模块介绍_nginx使用geo模块_05

 

此处发送时有一个 If-Modified-Since 请求头,其值就是上次请求响应的 Last-Modified

响应状态码为304

nginx使用geo模块 nginx常用模块介绍_服务器_06

 

Ctrl+f5强制刷新

如果你想强制从服务器获取最新的内容,不去对比,那么就可以强制刷新

nginx使用geo模块 nginx常用模块介绍_nginx_07

 

Pragma行是为了兼容 HTTP1.0 ,作用与 Cache-Control: no-cache 是一样的

Etag/If-None-Match

Etag :web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器觉得)。

If-None-Match :当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头 If-None-Match (Etag 的值)。web服务器收到请求后发现有头 If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。

Etag 是啥:

Last-Modified 标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间 如果某些文件会被定期生成,当有时内容并没有任何变化,但 Last-Modified 却改变了,导致文件没法使用缓存 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形 Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识

符,能够更加准确的控制缓存。 Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag ,一致的情况下,才会继续比对 Last-Modified ,最后才

决定是否返回304。

如下所示:

nginx使用geo模块 nginx常用模块介绍_nginx_08

 

浏览器第一次请求,无缓存状态

nginx使用geo模块 nginx常用模块介绍_服务器_09

 

浏览器第二次请求

nginx使用geo模块 nginx常用模块介绍_服务器_10

 

Nginx web缓存设置

nginx 提供了 expires、etag、if-modified-since 指令来进行浏览器缓存控制。

expires

假设我们使用 nginx 作为静态资源服务器,此时可以使用 expires 进行缓存控制。

location  ~.*\.(sql|log|txt|jar|war|sh|py|php)  {

 deny all;

}

 

nginx使用geo模块 nginx常用模块介绍_服务器_11

 

ngx_http_proxy_module

Proxy 模块,用于把请求后抛给服务器节点或 upstream 服务器池 常用配置,具体看手册

请求头传递

语法:return code [text] return code URL;
return URL;

区块:server,location,if 该指令用于结束规则的执行并返回状态吗给客户端。 状态码包括:
204(No  Content)、400(Bad  Request)、402(Payment  Required)、403(Forbidden) 404(Not  Found)、405(Method  Not  Allowed)、406(Not  Acceptable)、   408(Request  Timeout)、410(Gone)、411(Length  Required)、
413(Request Entity Too Large)、416(Requested Range Not Satisfiable)、 500(Internal Server Error)、501(Not Implemented)、502(Bad Gateway)、 503(Service Unavailable)和504(Gateway Timeout)。

例如,示例,如果访问的URL以.sh  .bash  结尾,返回状态码403 location   ~   .*\.(sh|bash)?$
{
return  403;
}

 

缓存细节

NGINX仅仅默认缓存GET和HEAD客户端请求,在响应头部中 Cache-Control 被配置为 Private,No-Cache,No-Store 或者 Set-Cookie , NGINX 不会进行缓 存。

如果你不想源服务器控制是否缓存,也可以在 nginx 当中配置忽略利用 roxy_ignore_headers Cache-Control 指令实现 下面的指令允许多种请求类型缓存

proxy_cache_methods GET HEAD POST ;

缓存设置优化

proxy_cache_min_uses 设置响应被缓存的最小请求次数。 当缓存不断被填满时,这项设置便十分有用,因为这确保了只有那些被经常访问的内容才会被添加到缓存中。该项默认值为1。

proxy_cache_lock 开启此功能时,对于相同的请求,同时只允许一个请求发往后端。

只有这些请求中的第一个被允许发送至服务器。其他请求在第一个请求得到满意结果之后在缓存中得到文件。如果不启用 proxy_cache_lock ,则所有在缓存中 找不到文件的请求都会直接与源服务器通信。

不缓存的条件

有时候,我们也不想所有的请求都被缓存,我们可以指定某些请求不被缓存,比如带有后台后缀的,可以通过一些条件判断决定是否缓存。

语法:rewrite regex replacement [flag];
默认值:・
上下文:server, location, if

rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。 正则:perl兼容正则表达式语句进行规则匹配
替代内容:将正则匹配的内容替换成replacement flag标记:rewrite支持的flag标记

比如后台模块是不允许缓存的,就可以设置不缓存

nginx使用geo模块 nginx常用模块介绍_nginx_12

 

清除缓存

某些时候我们如果不想等待缓存的过期,想要主动清除缓存,可以采用第三方的缓存清除模块清除缓存 nginx_ngx_cache_purge

last   #本条规则匹配完成后,继续向下匹配新的location URI规则 结束当前的请求处理,用替换后的URI重新匹配location; 可理解为重写(rewrite)后,发起了一个新请求,进入server模块,匹配locaton; 如果重新匹配循环的次数超过10次,nginx会返回500错误;

break    #本条规则匹配完成即终止,不再匹配后面的任何规则 结束当前的请求处理,使用当前资源,不在执行location里余下的语句

redirect	#返回302临时重定向,浏览器地址会显示跳转后的URL地址 permanent  #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

注意:要在proxy_cache 指令 下方

语法:	valid_referers none | blocked | server_names | string ...;
默认值:  ・
上下文: server, location

Referer”请求头为指定值时,内嵌变量$invalid_referer被设置为空字符串,    否则这个变量会被置成・1・。查找匹配时不区分大小写。 该指令的参数可以为下面的内容:
none
缺少・Referer・请求头;

blocked
“Referer” 请求头存在,但是它的值被防火墙或者代理服务器删除; 这些值都不以・http://・ 或者 ・https://・字符串作为开头; server_names
“Referer”  请求头包含某个虚拟主机名;

防止别人直接从你网站引用图片等链接,消耗了你的资源和网络流量,那么我们的  就可以设置防盗链策略下面的方法是直接给予404的错误提示,或者是 显示一个图片

location   ~*   ^.+\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$   { valid_referers none blocked www.baidu.com baidu.com;
if($invalid_referer){
#return  302     http://www.xxxx.com/img/nolink.jpg;
return 404; break;
}

 

半自动平滑升级

所谓半自动,其实就是在最后迁移的时候使用源码自带的升级命令:make upgrade 来自动完成

1、需要下载对应的需要加载的第三方的扩展,或者是需要附加设置的参数    (注意:之前的配置参数要保留)
--add_module=PATH	添加第三方扩展
2、执行make不要执行make install
3、重命名 nginx 旧版本二进制文件,即 sbin 目录下的 nginx(期间 nginx 并不会停止服务)
4、然后拷贝一份新编译的二进制文件到安装目录
5、在源码目录执行  make upgrade 开始升级:

 

nginx负载均衡

当我们的应用单例不能支撑用户请求时,此时就需要扩容,从一台服务器扩容到两台、几十台、几百台,我们需要一个入口,将客户端请求均衡分布在后台的多 个服务器上。

负载均衡在服务端开发中算是一个比较重要的特性, nginx 提供的负载均衡可以实现上游服务器的负载均衡、故障转移、失败重试、容错、健康检查,当某些 上游服务器出现问题时,可以将请求转到其它的上游服务器从而保障高可用。

第一步我们需要给 nginx 配置上游服务器,即负载均衡到真实的处理业务的服务器 通过在 http 指令下配置 upstream 即可。

语法:	upstream name { ... }
默认值:  ・
上下文: http
例子:
upstream backend {
server  demo.example.com	weight=5; server  demo2.example.com:8080;

}

server {
location / {
proxy_pass  http://backend;
}
}
upstream 指令当中包含server指令
语法:	server address [parameters];
默认值:  ・
上下文: upstream
可以定义下面的参数:
weight=number  设定服务器的权重,默认是1,权重越大被访问机会越大,要根据机器的配置情况来配置

max_fails=number          设定Nginx与服务器通信的尝试失败的次数。在fail_timeout参数定义的时间段内,如果失败的次数达到此值,Nginx就认为服务器不 可用。在下一个fail_timeout时间段,服务器不会再被尝试。 失败的尝试次数默认是1。

可以通过指令proxy_next_upstream   和memcached_next_upstream来配置什么是失败的尝试。     默认配置时,http_404状态不被认为是失败的尝试。

fail_timeout=time
统计失败尝试次数的时间段。在这段时间中,服务器失败次数达到指定的尝试次数,服务器就被认为不可用。默认情况下,该超时时间是10秒。

backup
标记为备用服务器。当主服务器不可用以后,请求会被传给这些服务器,配置这个指令可以实现故障转移。

down
标记服务器永久不可用,可以跟ip_hash指令一起使用。
当访问Nginx时,会将请求反向代理到backend配置的upstream    server。

负载均衡的方法

nginx 支持以下负载均衡机制:

1、轮询

默认轮训方式 每一个来自网络中的请求,轮流分配给内部的服务器,从1到N然后重新开始。此种负载均衡算法适合服务器组内部的服务器都具有相同的配置并且平均服务请求 相对均衡的情况。

2、加权轮询

通过 weight 参数控制权重 根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。例如:服务器A的权值被设计成1,B的权值是3,C的权值是

6,则服务器A、B、C将分别接受到10%、30%、60%的服务请求。此种均衡算法能确保高性能的服务器得到更多的使用率,避免低性能的服务器负载过重。

3、IP Hash

在 upstream 当中配置 ip_hash ;

这种方式通过生成请求源IP的哈希值,并通过这个哈希值来找到正确的真实服务器。这意味着对于同一主机来说他对应的服务器总是相同。使用这种方式,你不 需要保存任何源IP。 将客户端会话"沾住"或者"持久化",以便总是能选择特定服务器,那么可以使用 ip-hash 负载均衡机制。

使用 ip-hash 时,客户端IP地址作为 hash key 使用,用来决策选择服务器集群中的哪个服务器来处理这个客户端的请求。这个方法保证从同一个客户端发起的 请求总是定向到同一台服务器,除非服务器不可用。

4、最少连接数

在 upstream 当中配置 least_conn 实现最少连接数 客户端的每一次请求服务在服务器停留的时间可能会有较大的差异,随着工作时间加长,如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能

会产生极大的不同,并没有达到真正的负载均衡。最少连接数均衡算法对内部中需负载的每一台服务器都有一个数据记录,记录当前该服务器正在处理的连接数量,当有新的服务连接请求时,将把当前请求分配给连接数最少的服务器,使均衡更加符合实际情况,负载更加均衡。

失败重试

通过配置上游服务器 max_fails 和 fail_timeout ,指定每个上游服务器,当 fail_timeout 时间内失败了 max_fails 次请求,则认为该上游服务器不可用/不 存活,然后这段时间将不会访问这台上游服务器, fail_timeout 时间后会再次进行重试。

max_fails=2 fail_timeout=30s 这2个一起搭配使用,表示:当失败2次的时候,就停止使30秒