当前位置:  操作系统/服务器>linux
本页文章导读:
    ▪nginx负载均衡配置(consistent_hash、error_page)进阶      接着上篇文章往向讲,采用consistent方式进行url_hash负载均衡。 重新编译nginx:   代码如下: wget http://download.github.com/replay-ngx_http_consistent_hash-77b6940.tar.gz tar zxvf replay-ngx_http_consistent_hash-77b6940.t.........
    ▪学习nginx负载均衡(url_hash)的配置      介绍: nginx是著名的非专职全七层负载均衡器,在用惯了四层LVS后,终于碰上了麻烦:LVS后端的4台RS磁盘都较小(20G),跑不到一天就塞满了东西;而根据预估,实际上一天时间该节点也就.........
    ▪学习使用nginx的proxy_cache和cache_purge模块      学习使用nginx的proxy_cache和cache_purge模块,有需要的朋友可以跟着参考学习下。 nginx的类squid哈希式cache功能,据说是基本稳定可用了,测试了一下,记录在此: 首先是编译nginx,方便起见,把.........

[1]nginx负载均衡配置(consistent_hash、error_page)进阶
    来源: 互联网  发布时间: 2013-12-24

接着上篇文章往向讲,采用consistent方式进行url_hash负载均衡。

重新编译nginx:
 

代码如下:
wget http://download.github.com/replay-ngx_http_consistent_hash-77b6940.tar.gz
tar zxvf replay-ngx_http_consistent_hash-77b6940.tar.gz
cd nginx-0.7.65
./configure --prefix=/home/nginx   --with-pcre=/tmp/pcre-8.01 --with-http_stub_status_module --with-http_ssl_module --without-http_rewrite_module --add-module=/tmp/nginx_upstream_hash-0.3 --add-module=/tmp/replay-ngx_http_consistent_hash-77b6940
make && make install

修改配置文件:
 

代码如下:
upstream images6.static.com {
    server 11.11.11.12:80;
    server 11.11.11.13:80;
    consistent_hash $request_uri;
}

访问测试正常。

error_page配置备份:
 

代码如下:

upstream backup {
    server 11.11.11.14:80;
}

error_page 404 500 502 503 504 =200 @fetch;
location @fetch {
    proxy_pass        http://backup;
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
}

注意:=200里的等号,左边有空格,右边没空格。


    
[2]学习nginx负载均衡(url_hash)的配置
    来源: 互联网  发布时间: 2013-12-24

介绍:
nginx是著名的非专职全七层负载均衡器,在用惯了四层LVS后,终于碰上了麻烦:LVS后端的4台RS磁盘都较小(20G),跑不到一天就塞满了东西;而根据预估,实际上一天时间该节点也就只有20G的文件增长。很显然,因为lvs转发的轮询算法,导致RS重复缓存了相同的文件。

针对这个情况,可以有两个办法(我只想到两个,欢迎大家补充):
1)、架构拆分,把不同的几个域名分别指向不同的server,这个在DNS上就能完成,不过就丧失了lvs的冗余;也可以用nginx的upstream+server配置,分别指向不通的RS,不过不同域名文件数量如果相差比较大的话,RS的负载就不均衡了。
2)、url_hash,采用HAproxy的loadbalance uri或者nginx的upstream_hash模块,都可以做到针对url进行哈希算法式的负载均衡转发。

那么,开始试试nginx的url_hash负载均衡吧:

安装部署:
 

代码如下:
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.01.tar.gz
tar zxvf pcre-8.01.tar.gz
wget http://wiki.nginx.org/images/7/78/Nginx_upstream_hash-0.3.tar.gz
tar zxvf Nginx_upstream_hash-0.3.tar.gz
wget http://sysoev.ru/nginx/nginx-0.7.65.tar.gz
tar zxvf nginx-0.7.65.tar.gz

vi nginx-0.7.65/src/http/ngx_http_upstream.h
 

代码如下:

struct ngx_http_upstream_srv_conf_s {
ngx_http_upstream_peer_t         peer;
void                           **srv_conf;

ngx_array_t                     *servers;  /* ngx_http_upstream_server_t */

+ngx_array_t                     *values;
+ngx_array_t                     *lengths;
+ngx_uint_t                       retries;

ngx_uint_t                       flags;
ngx_str_t                        host;
u_char                          *file_name;
ngx_uint_t                       line;
in_port_t                        port;
in_port_t                        default_port;
};

为了安全,可以修改一下nginx的version信息:vi nginx-0.7.65/src/core/nginx.h
 

代码如下:

#define NGINX_VERSION      "2.6.STABLE21"
#define NGINX_VER          "squid/" NGINX_VERSION

vi nginx-0.7.65/src/http/ngx_http_header_filter_module.c
static char ngx_http_server_string[] = "Server: squid/2.6.STABLE21" CRLF;

vi nginx-0.7.65/src/http/ngx_http_special_response.c
static u_char ngx_http_error_tail[] =
"<hr><center>squid/2.6.STABLE21</center>" CRLF
"</body>" CRLF
"</html>" CRLF

cd pcre-8.01
./configure --prefix=/usr
make && make install
cd nginx-0.7.65
./configure --prefix=/home/nginx  --with-pcre --with-http_stub_status_module
--with-http_ssl_module --without-http_rewrite_module
--add-module=/tmp/nginx_upstream_hash-0.3

vi auto/cc/gcc
# debug
#CFLAGS="$CFLAGS -g"

make && make install

安装完成。

2、配置文件
 

代码如下:

upstream images6.static.com {
    server 11.11.11.11:80;
    server 11.11.21.12:80;
    server 11.11.21.13:80;
    server 11.11.21.14:80;
    hash    $request_uri;
}

server {
    listen       80;
    server_name  images6.static.com;
    access_log  /dev/null  main;
    location / {
        proxy_pass         http://images6.static.com;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

以上配置的问题:
1)、RS中不能设置nginx本机的其他端口,我本来设定的server 11.11.11.10:3128,希望能把nginx本机也开上squid,省出一台机器来。结果在确认配置了DNS的情况下,返回状态码全是503。
2)、RS一旦有宕机的,nginx不会重算hash,导致部分url返回错误信息;而启用hash_again标签的话,其他RS就都乱了。
3)、RS中默认logformat中将显示nginx的IP。

解决办法:
1. 不知道
2. 不采用hash_again标签而采用error_page重定向到专门的备份服务器保障访问
3. 修改RS的logformat,把%>a改成%{X-Real_IP}>h即可。

最后的根本性问题:
对nginx下的RS集群进行增减操作,是否会对hash表产生影响?nginx_upstream_hash目录中的CHANGES有如下三条:
Changes with upstream_hash 0.3                                   06 Aug 2008
*) Bugfix: infinite loop when retrying after a 404 and the "not_found" flag of *_next_upstream was set.
*) Change: no more "hash_method" directive. Hash method is always CRC-32.
*) Change: failover strategy is compatible with PECL Memcache.

nginx的wiki上,关于hash_again的doc这么写到:

Number of times to rehash the value and choose a different server if the backend connection fails. Increase this number to provide high availability.

关于PECL Memcache,请参考下列链接:
http://www.surfchen.org/archives/348
http://tech.idv2.com/2008/07/24/memcached-004/

尤其是第二个链接,其中关于rehash的解释,很好的解释了为什么大家都不推荐使用hash_again标签。 由此可知,upstream_hash模块,使用的是余数计算standard+CRC32方式,10+2的存活率是17%,3+1的存活率是23%! 而存活率最高的是consistent+CRC32方式,存活率是n/(n+m)*100%,10+2是83%,3+1是75%。

nginx的wiki中,还有另一个3rd模块upstream_consistent_hash,下回可以试试; 网上还有针对upstream_hash模块的补丁
http://www.sanotes.net/wp-content/uploads/2009/06/nginx_upstream_hash.pdf,好模块就是有人研究呀!!


    
[3]学习使用nginx的proxy_cache和cache_purge模块
    来源: 互联网  发布时间: 2013-12-24

学习使用nginx的proxy_cache和cache_purge模块,有需要的朋友可以跟着参考学习下。

nginx的类squid哈希式cache功能,据说是基本稳定可用了,测试了一下,记录在此:

首先是编译nginx,方便起见,把一些心仪的模块统统加上了,version如下:
built by gcc 4.1.2 20080704 (Red Hat 4.1.2-44)
TLS SNI support disabled
configure arguments: --prefix=/home/nginx --with-pcre --add-module=../ngx_http_consistent_hash --add-module=../ngx_max_connections --add-module=../ngx_cache_purge --add-module=../ngx_mp4_streaming_public --with-cc-opt=-O3 --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --without-http_memcached_module --without-http_fastcgi_module --with-google_perftools_module

编译过程中几个注意事项:
1)、必须采用–with-pcre,而不要偷懒采用–without-http_rewrite_module,否则配置文件里将不支持if判断;
2)、加载mp4_streaming,必须采用–with-cc-opt=-O3方式进行编译。
3)、max_connections模块默认支持nginx最新版本是0.8.32,需要vi修改其DIR,然后path -p0,但千万不要看见有个Makefile就执行make && make install了,因为它会毫无道理的把整个nginx安装到当前目录的.nginx下隐藏起来。

话说我add这个max_connections模块能怎么用自己也没想好,反正官方有limit_zone和limit_req限制client,再add个限制nginx2oringin的也不在乎吧……汗~~

比较囧的一点是,经过我折腾的nginx,虽然去除了debug -g模式编译,还是有4M多大……

sina的ncache模块,在我下载的最新的nginx0.8.34src上无法使用,而且ncache作者介绍说ncache的缓存不用内存,且其purge方式为标记为过期但并不更改文件内容直到下次访问请求以节省磁盘IO的负担;但根据我的试验,nginx的cache_purge模块则是采用了删除过期文件的方式进行(当然,proxy_cache的过期还是标记而不删除的,不然太耗IO了……)。

实验完成后的配置文件:
 

代码如下:

user nobody nobody;
worker_processes 1;
google_perftools_profiles /tmp/tcmalloc;
worker_rlimit_nofile 65535;

events
{
    use epoll;
    worker_connections 65535;
}

http
{
    include       mime.types;
    default_type  application/octet-stream;
   
    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  logs/access.log  main ;
   
    #  charset  utf-8;
   
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 300m;
   
    sendfile on;
    tcp_nopush     on;
   
    keepalive_timeout 60;
   
    tcp_nodelay on;
   
    client_body_buffer_size  512k;
    proxy_connect_timeout    5;
    proxy_read_timeout       60;
    proxy_send_timeout       5;
    proxy_buffer_size        16k;
    proxy_buffers            4 64k;
    proxy_busy_buffers_size 128k;
    proxy_temp_file_write_size 128k;
   
    gzip on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 2;
    gzip_types       text/plain application/x-javascript text/css application/xml;
    gzip_vary on;
    #定义cache临时缓存路径,必须和哈希缓存路径在同一个磁盘上
    proxy_temp_path   /cache/proxy_temp_dir;
    #定义cache哈希缓存路径,目录层次,缓存名称及所允许缓存的最大文件大小,未被访问文件多久自动清除,缓存最多使用多大磁盘
    proxy_cache_path  /cache/proxy_cache_dir  levels=1:2   keys_zone=cache_one:200m inactive=1d max_size=30g;
    #后端源站地址
    upstream backend{
        server 10.10.10.13:80;
    }
   
    server
    {
        listen       80;
        server_name  www.test.com;
        #这里就是关键部分了,定义哈希缓存及缓存过期;
        #因为nginx提供的过期控制是针对http_status_code的,我本想通过location中限定类型的方法完成曲线救国,结果发现:一旦location中限定了文件类型,缓存过期的定义就失效!!
        #也就是说,限定文件类型后的哈希缓存,是绝绝对对的强制永久缓存——不单过期失效,下面的purge也失效——或许换一个场景,这个刚好有用。
        #   location ~* .*.(css|gif|jpg|png|html|swf|flv)
        location / {
        #启用flv拖动功能;
            flv;
            #这里定义是如果碰上502、504、timeout和invalid_header等情况,自动调向下一个oringin继续请求,这个有时候有用,有时候可能被攻击的会很惨……
            proxy_next_upstream http_502 http_504 error timeout invalid_header;
            #使用上面定义的具体某个缓存;
            proxy_cache cache_one;
            #200和304的状态码访问都缓存1天;
            proxy_cache_valid  200 304 1d;
            #由主机名、唯一资源定位符、参数判断符和请求参数共同生成哈希缓存的key
            proxy_cache_key $host$uri$is_args$args;
            #下面几个是常见的nginx透明代理header
            proxy_pass_header User-Agent;
            proxy_set_header Host  $host;
            proxy_set_header X-Forwarded-For  $remote_addr;
            #下面是为了证明给大家看他确实能缓存,增加的两句话;如果真想要看到HIT和MISS的话,可以addnginx的另一个模块slowfs_cache,配置上和官方的proxy_cache极其相似,不过自带有变量$slowfs_cache_status,可以显示HIT/MISS/EXPIRED。
            add_header X-Cache "HIT from cache_test";
            add_header Age "1";
            proxy_pass http://backend;
        }
        #下面这段就是add的purge_mod,只要在url的^/前再加上/purge,就会自动被理解成PURGE请求,刷新成功返回200的特定页面,失败返回404的普通错误页面。
        #这个proxy_cache_purge格式没法改变,我本想改成if ($request_method = PUREG){…}试试,结果发现它不认……
        location ~ /purge(/.*){
            allow            127.0.0.1;
            allow            211.151.67.0/24;
            deny            all;
            proxy_cache_purge    cache_one   $host$1$is_args$args;
        }
        #不区分大小写匹配~*,网上流传很广的写法*~*是错滴;而且能匹配不代表保存同一份缓存;
        #这部分定义不缓存而是透传的请求类型。介于无法通过类型来控制缓存,那么这里不缓存的控制就必须确保严格正确了……
        #可是bug来了,当我写成swf?$的时候,swf/swf?/swf?*都不缓存;写成swf?的时候,又变成都缓存——nginx压根就分不清!
        location ~* .*.(swf|asp)?{
            proxy_pass_header User-Agent;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarder-For $remote_addr;
            add_header X-Cache "MISS from cache_test";
            proxy_pass http://backend;
        }
    }
}

配置完成。测试如下:
wget http://www.test.com/List/j.Html -S -O /dev/null -e http_proxy=127.0.0.1 –13:17:48–  http://www.test.com/List/j.Html Connecting to 127.0.0.1:80… connected. Proxy request sent, awaiting response… HTTP/1.1 200 OK Server: squid/2.6.STABLE21 Date: Sun, 07 Mar 2010 05:17:48 GMT Content-Type: text/html; charset=utf-8 Connection: close Vary: Accept-Encoding Content-Length: 25126 Last-Modified: Wed, 10 Feb 2010 09:38:26 GMT ETag: “948acecb34aaca1:6647” X-Powered-By: ASP.NET X-Cache: HIT from cache_test Age: 1 Accept-Ranges: bytes Length: 25126 (25K) [text/html] Saving to: `/dev/null’

100%[============================================>] 25,126      --.-K/s   in 0s

13:17:48 (521 MB/s) - `/dev/null’ saved [25126/25126]

[root@sdl4 ~ 13:17:48]# wget -S -O /dev/null -e http_proxy=127.0.0.1 “http://www.test.com/Search.ASP?KeyWord=整形视频” –13:17:50–  http://www.test.com/Search.ASP?KeyWord=%D5%FB%D0%CE%CA%D3%C6%B5 Connecting to 127.0.0.1:80… connected. Proxy request sent, awaiting response… HTTP/1.1 200 OK Server: squid/2.6.STABLE21 Date: Sun, 07 Mar 2010 05:17:51 GMT Content-Type: text/html; charset=utf-8 Connection: close Vary: Accept-Encoding X-Powered-By: ASP.NET Content-Length: 24987 Set-Cookie: ASPSESSIONIDSSQQSBST=KDPDLODBNLGONONBNHCJCEGP; path=/ Cache-control: private X-Cache: MISS from cache_test Length: 24987 (24K) [text/html] Saving to: `/dev/null’

100%[==========================================>] 24,987      25.6K/s   in 1.0s

13:17:52 (25.6 KB/s) - `/dev/null' saved [24987/24987] 完成。
至于?的问题,目前针对需要,倒有另一个办法: 在location / {}中,根据请求参数判断进行传递。即写成如下:
 

代码如下:
location / {
    ……
    if ($is_args){
        add_header X-Cache "MISS from cache_test";
        proxy_pass http://backend;
    }
}
location ~* .*\.asp{
    proxy_pass_header User-Agent;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarder-For $remote_addr;
    add_header X-Cache "MISS from cache_test";
    proxy_pass http://backend;
}

不过依然有问题:
nginx的if不支持&&或者||,万一有些类型(比如htm和jpg)又要求带?的也缓存,显然又和这个$is_args冲突; 或许采用下面的办法能继续区分?(未试验)
 

代码如下:
set $yn $is_args;
if ($uri ~* .(htm|jpg)){
    set $yn "";
}
if ($yn){
    proxy_pass http://backend;
}
 

; 2. nginx的if中不单不支持proxy_cache,居然也不支持proxy_set_header等定义,只能单纯的proxy_pass。


    
最新技术文章:
▪linux系统中的列出敏感用户的脚本代码
▪a10 config backup for aXAPI
▪一键备份gitolite服务器的Shell脚本
▪nagios 分发文件实现代码
▪阿里云云服务器Linux系统更新yum源Shell脚本
▪一个监控LINUX目录和文件变化的Shell脚本分享
论坛 iis7站长之家
▪Shell正则表达式之grep、sed、awk实操笔记
▪3个备份系统文件并邮件发送的Shell脚本分享
▪CentOS 6.3下给PHP添加mssql扩展模块教程
▪监控网站是否可以正常打开的Shell脚本分享
▪shell脚本编程之if语句学习笔记
▪shell脚本编程之循环语句学习笔记
▪shell脚本编程之case语句学习笔记
▪Shell脚本实现的阳历转农历代码分享
▪Shell脚本实现复制文件到多台服务器的代码分...
▪Shell脚本实现批量下载网络图片代码分享
▪Shell脚本实现检测文件是否被修改过代码分享
▪Shell脚本数组用法小结
▪Shell脚本批量重命名文件后缀的3种实现
▪C语言实现的ls命令源码分享
▪Linux下查找后门程序 CentOS 查后门程序的shell脚...
▪Shell 函数参数
▪linux shell 自定义函数方法(定义、返回值、变...
▪Shell实现判断进程是否存在并重新启动脚本分...
▪Shell脚本break和continue命令简明教程
▪Shell脚本函数定义和函数参数
▪让代码整洁、过程清晰的BASH Shell编程技巧
▪shell常用重定向实例讲解
▪awk中RS、ORS、FS、OFS的区别和联系小结
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3