架构设计:负载均衡层设计方案——Nginx进阶

Posted yangykaifa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构设计:负载均衡层设计方案——Nginx进阶相关的知识,希望对你有一定的参考价值。

上篇文章《架构设计:负载均衡层设计方案(2)——nginx安装》(http://blog.csdn.net/yinwenjie/article/details/46620711),我们介绍了Nginx的核心设计思想、基本安装和使用。本来准备继续介绍Nginx的几个使用特性,可是奈何博文篇幅太长,仅仅有将一篇文章拆成两篇。本文我们将承接上文,继续解说Nginx的有用特性,包含gzip功能、rewirte功能和一个第三方的节点监測模块。本文我们还将提到Taobao团队对Nginx的深度改造Tengine。

1、Nginx继续进阶

1.1、gzip

nginx对返回给浏览器的http response body是能够进行压缩的。尽管须要消耗一点cpu和内存资源,可是想到100KB的数据量能够压缩到60KB甚至更小进行传输,是否有一定的吸引力?这里我的建议是。不要为了节约成本将业务服务和负载层服务放在一台物理服务器上。这样做既影响性能又添加了运维难度。

http返回数据进行压缩的功能在非常多场景下都有用:

  • 假设浏览器使用的是3G/4G网络,那么流量对于用户来说就是money。

  • 压缩可节约服务器机房的对外带宽,为很多其它用户服务。依照眼下的市场价良好的机房带宽资源的一般在200RMB/Mbps,而服务器方案的压力往往也来自于机房带宽。

  • 主要注意的是,不是Nginx开启了gzip功能。HTTP响应的数据就一定会被压缩。除了满足Nginx设置的“须要压缩的http格式”以外,client(浏览器)也须要支持gzip(不然它怎么解压呢),一个好消息是,眼下大多数浏览器和API都支持http压缩。

    我们首先来解说Nginx中的gzip的设置參数,然后我们解说当开启压缩功能后。HTTP的交互过程和过程中关键的几个属性。

    我们首先来看看Nginx中开启gzip的属性(gzip的设置放置在HTTP主配置区域):

    #开启gzip压缩服务,
    gzip on;

    #gzip压缩是要申请暂时内存空间的,假设前提是压缩后大小是小于等于压缩前的。比如。假设原始文件大小为10K,那么它超过了8K,所以分配的内存是8 * 2 = 16K;再比如,原始文件大小为18K。非常明显16K也是不够的,那么依照 8 * 2 * 2 = 32K的大小申请内存。

    假设没有设置,默认值是申请跟原始数据同样大小的内存空间去存储gzip压缩结果。
    gzip_buffers 2 8k;

    #进行压缩的原始文件的最小大小值,也就是说假设原始文件小于5K,那么就不会进行压缩了
    gzip_min_length 5K;

    #gzip压缩基于的http协议版本号,默认就是HTTP 1.1
    gzip_http_version 1.1;

    # gzip压缩级别1-9,级别越高压缩率越大,压缩时间也就越长CPU越高
    gzip_comp_level 5;

    #须要进行gzip压缩的Content-Type的Header的类型。建议js、text、css、xml、json都要进行压缩。图片就不是必需了,gif、jpge文件已经压缩得非常好了,就算再压。效果也不好,而且还耗费cpu。
    gzip_types text/html text/plain application/x-javascript text/css application/xml;

    设置完毕后。重新启动nginx,就可以生效。以下我们来看看浏览器和服务器进行gzip压缩的请求和处理返回过程(实际上在我的《标准Web系统的架构分层》文章中,已经有所提及):

技术分享

  • 整个请求过程来看。开启gzip和不开启gip功能,其http的请求和返回过程是一致的,不同的是參数。这个能够看看我的另外一篇文章《标准Web系统的架构分层》http://blog.csdn.net/yinwenjie/article/details/46480485

  • 当开启HTTP的gzip功能时,client发出http请求时。会通过headers中的Accept-Encoding属性告诉服务器“我支持gzip解压,解压格式(算法)deflate,sdch为:”。Accept-Encoding:gzip,deflate,sdch

  • 注意。不是request说自己支持解压。Nginx返回response数据的时候就一定会压缩。这还要看本次Nginx返回数据的格式是什么。假设返回数据的原始数据格式,和设置的gzip_types相符合,这时Nginx才会进行压缩。

  • Nginx返回response headers是,假设数据被压缩了,就会在Content-Encoding属性中标示gzip。表示接下来返回的response content是经过压缩的;而且在Content-Type属性中表示数据的原始格式。

  • 最后返回经过压缩的response content给client,client再进行解压。

    这里注意一下。在client发送的headers里面,有一个deflate,sdch。

    这是两种压缩算法,假设读者感兴趣,能够查查相关的资料(我建议查查。了解哈弗曼压缩算法对扩展自己的架构思路非常有帮助)

1.2、rewrite

本小结内容,假定读者了解正則表達式。

假设您不清楚正則表達式,请首先Google或者百度。正則表達式不在我们讨论的范围内。

Nginx的强大在于其对URL请求的重写(重定位)。Nginx的rewrite功能依赖于PCRE Lib,请一定在Nginx编译安装时,安装Pcre lib。

请參见我的上一篇文章《架构设计:负载均衡层设计方案(2)——Nginx安装》http://blog.csdn.net/yinwenjie/article/details/46620711

我们先从解说rewrite的关键语法,然后出示几个演示样例。由演示样例进行解说。先来说一下Nginx中几个关键的语法:

正在表达式匹配:

  • ~ 区分大写和小写进行正則表達式匹配
  • ~* 不区分大写和小写进行正則表達式匹配
  • !~ 区分大写和小写进行正則表達式不匹配
  • !~* 不区分大写和小写进行正則表達式不匹配

举例说明:

演示样例1:location ~* \.(jpg|gif|png|ioc|jpeg)$

location是Nginx中的keyword,代表当前的URL请求值。
以上表达式表示对URL进行不区分大写和小写的匹配。一旦URL以jpg或gif或png或ioc或jpeg结尾时,匹配成功。

演示样例2:$var1 ~ ^(\d+)$

var1是Nginx中使用setkeyword定义的变量,以上语句代表var1和一个整数进行匹配。

Nginx中的全局变量:
从上面的各个实例中。我们已经发现Nginx是支持变量的,Nginx还内置了一些全局变量,这里列举一些比較重要的全局变量:

  • $content_length: 获取request中header部分的“Content_Length”值。
  • $content_type: 获取request中header部分的“Content_type”值。
  • $request_method: 请求方式,经常使用的有两种请求方式:POST、GET
  • $remote_addr: 发送请求的clientip
  • $remote_port: 发送请求的client端口
  • $request_uri: 含有參数的完整的初始URI
  • $server_addr: request到达的server的ip。
  • $server_port: 请求到达的服务器的端口号。

rewrite语法

rewrite regex replacement flag

#regex:表示当前匹配的正則表達式。仅仅有$url大写和小写相关匹配regex正則表達式。这个$url才会被rewrite进行重定向。

#replacement:重定向目标规则。这个目标规则支持动态变量绑定,这个问题下文立即用演示样例来讲。

#flag:重定向规则。

rewrite中的Flagkeyword

  • redirect:通知client重定向到rewrtie后面的地址。
  • permanent:通知client永久重定向到rewrtie后面的地址。
  • last:将rewrite后的地址又一次在server标签运行。
  • break:将rewrite后地址又一次在当前的location标签运行。

实际上针对client来说,其效果是一样的,都是由client又一次发起http请求,请求地址又一次定位到replacement规则的URL地址;这里关键要解说最经常使用的last和break两个keyword:

全部的rewrite语句都是要在server中的location中书写的。例如以下:
server {
    。。。。。。
    。

。。。。

。 location ... { if(...) { rewirte regex replacement flag; } rewirte regex replacement flag; } } 那么,breakkeyword说明重写的replacement地址在当前location的区域立即运行。 lastkeyword说明重写的replacement地址在当前server全部的location中又一次再做匹配。

以下我们结合rewritekeyword和rewrite flagkeyword给出典型的演示样例进行解说:

演示样例1:
location ~* ^/(.+)/(.+)\.(jpg|gif|png|jpeg)$ {
    rewrite ^/orderinfo/(.+)\.(jpg|gif|png|jpeg)$   /img/$1.$2   break;
    root   /cephclient;
}

location在不进行大写和小写区分的情况下利用正則表達式对$url进行匹配。当匹配成功后进行rewrite重定位。

rewrite进行重写url的规则是:regex表达式第一个括号里的内容相应$1。regex表达式第二个括号里的内容相应$2,以此类推。 这样重定位的意义就非常明白了:将不论什么文件夹下的文件名称重定位到img文件夹下的相应文件名称, 而且立即在这个location中(注意是Nginx,而不是client)运行这个重写后的URL定位。 演示样例2: server { 。。。。

。。 location ~* ^/orderinfo/(.+)\.(jpg|gif|png|jpeg)$ { rewrite ^/orderinfo/(.+)\.(.+)$ /img/$1.$2 last; } location / { root /cephclient; } } 在server中,有两个location位置,当url须要訪问orderinfo文件夹下的某一个图片时,rewrite将重写这个url, 而且又一次带入这个url到server运行,这样“location /”这个location就会运行了。并找到图片存储的文件夹。

1.3、健康检查模块

在本小节我们介绍一个用于Nginx对后端UpStream集群节点健康状态检查的第三方模块:nginx_upstream_check_module(https://github.com/yaoweibin/nginx_upstream_check_module)。这个模块有资料介绍是TaoBao团队开发的,可是我在GitHua上试图求证时并没有找到直接证据。

这里须要说明的是。眼下有非常多Nginx模块实现Nginx对后端集群节点的健康监測,不止nginx_upstream_check_module。Nginx官方有一个模块healthcheck_nginx_upstreams也能够实现对后端节点的健康监測(https://github.com/cep21/healthcheck_nginx_upstreams有具体的安装和使用介绍)

我们回到对nginx_upstream_check_module的解说。要使用这个第三方模块首先您须要进行下载,然后通过patch命令将补丁打入您原有的Nginx源代码中,而且又一次进行编译安装

以下我们来重点解说一下这个模块的安装和使用。

下载nginx_upstream_check_module模块:

wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master

您也能够直接到GitHua上进行下载。还一个在linux系统上使用git命令进行下载。

解压安装。并补丁打入Nginx源代码

# unzip ./nginx_upstream_check_module-master.zip

注意是将补丁打入Nginx源代码。不是Nginx的安装路径:

# cd ./nginx-1.6.2

# patch -p1 < ../nginx_upstream_check_module-master/check_1.5.12+.patch

假设补丁成功安装,您将看到以下的提示信息:
patching file src/http/modules/ngx_http_upstream_ip_hash_module.c
patching file src/http/modules/ngx_http_upstream_least_conn_module.c
patching file src/http/ngx_http_upstream_round_robin.c
patching file src/http/ngx_http_upstream_round_robin.h

这里请注意:在nginx_upstream_check_module官网的安装说明中,有一个打补丁的注意事项:
If you use nginx-1.2.1 or nginx-1.3.0, the nginx upstream round robin
module changed greatly. You should use the patch named
‘check_1.2.1.patch‘.
If you use nginx-1.2.2+ or nginx-1.3.1+, It added the upstream
least_conn module. You should use the patch named ‘check_1.2.2+.patch‘.
If you use nginx-1.2.6+ or nginx-1.3.9+, It adjusted the round robin
module. You should use the patch named ‘check_1.2.6+.patch‘.
If you use nginx-1.5.12+, You should use the patch named
‘check_1.5.12+.patch‘.
If you use nginx-1.7.2+, You should use the patch named
‘check_1.7.2+.patch‘.

这里我们的Nginx的版本号是1.6.2,那么就应该打入check_1.5.12+.patch这个补丁

又一次编译安装Nginx:

注意又一次编译Nginx,要使用add-module參数将这个第三方模块安装进去:

# ./configure --prefix=/usr/nginx-1.6.2/ --add-module=../nginx_upstream_check_module-master/

# make && make install

通过以上的步骤,第三方的nginx_upstream_check_module模块就在Nginx中准备好了。

接下来我们解说一下怎样使用这个模块。首先看一下upstream的配置信息:

upstream cluster {
    # simple round-robin
    server 192.168.0.1:80;
    server 192.168.0.2:80;

    check interval=5000 rise=1 fall=3 timeout=4000;

    #check interval=3000 rise=2 fall=5 timeout=1000 type=ssl_hello;
    #check interval=3000 rise=2 fall=5 timeout=1000 type=http;
    #check_http_send "HEAD / HTTP/1.0\r\n\r\n";
    #check_http_expect_alive http_2xx http_3xx;
}

上面的代码中,check部分就是调用nginx_upstream_check_module模块的语法:

check interval=milliseconds [fall=count] [rise=count]
[timeout=milliseconds] [default_down=true|false]
[type=tcp|http|ssl_hello|mysql|ajp|fastcgi]

interval:必要參数。检查请求的间隔时间。

fall:当检查失败次数超过了fall,这个服务节点就变成down状态。

rise:当检查成功的次数超过了rise,这个服务节点又会变成up状态。

timeout:请求超时时间,超过等待时间后。这次检查就算失败。

default_down:后端服务器的初始状态。默认情况下。检查功能在Nginx启动的时候将会把全部后端节点的状态置为down。检查成功后,在置为up。

type:这是检查通信的协议类型,默觉得http。

以上类型是检查功能所支持的全部协议类型。

check_http_send http_packet

http_packet的默认格式为:"GET / HTTP/1.0\r\n\r\n"

check_http_send设置,这个设置描写叙述了检查模块在每次检查时。向后端节点发送什么样的信息

check_http_expect_alive [ http_2xx | http_3xx | http_4xx | http_5xx ]

这些状态代码表示服务器的HTTP响应上是OK的,后端节点是可用的。默认情况的设置是:http_2xx | http_3xx

当您依据您的配置要求完毕检查模块的配置后。请首先使用nginx -t 命令监測配置文件是否可用,然后在用nginx -s reload重新启动nginx。

1.4、不得不提的tengine

Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大訪问量站点的需求。加入了非常多高级功能和特性。Tengine的性能和稳定性已经在大型的站点如淘宝网,天猫商城等得到了非常好的检验。

它的最终目标是打造一个高效、稳定、安全、易用的Web平台(http://tengine.taobao.org/)。

您应该懂了,我建议您依据业务的实际情况。适时在生产环境引入Tengine。但在本博客公布时,Tengine的2.X版本号还不稳定。所以建议有用1.5.2的稳定版本号。

请记住Tengine就是经过升读改造后的Nginx

2、后文介绍

花了两篇文章的功夫,最终将我想给大家解说的nginx的有用特性讲完了,可是nginx远远不止这些特性。后面有时间我们会再回到Nginx,重点解说针对Nginx的脚本开发,我们还会解说Nginx和Lua的集成。可是为了不扰乱这个系列博文的时间安排。下篇文章我们将開始介绍LVS技术,争取用一篇文章的篇幅讲清楚LVS核心设计思想、单节点安装和使用。再下篇文章我们介绍Keepalived技术,以及keepalived和LVS、Nginx分别进行集成,敬请关注。








以上是关于架构设计:负载均衡层设计方案——Nginx进阶的主要内容,如果未能解决你的问题,请参考以下文章

架构设计:负载均衡层设计方案——LVS + Keepalived + Nginx安装及配置

架构设计:负载均衡层设计方案之负载均衡技术总结篇

架构设计:负载均衡层设计方案之负载均衡技术总结篇

架构设计:负载均衡层设计方案——负载场景和解决方式

高并发系统设计负载均衡架构

了解负载均衡