Linux系统中使用Nignx配置反向代理负载均衡

使用nginx实现动静分离的负载均衡集群

Nginx官网源码包下载链接:http://nginx.org/en/download.html
官方文档:http://nginx.org/en/docs/

Nginx简介;

  • 概述:Nginx是一款由俄罗斯开发的开源的高性能HTTP服务器和反向代理服务器,同时支持IMAP/POP3/SMTP代理服务,其性能优势着为显著,官网上称:单台nginx服务器可以处理50000并发;

  • 特点:高性能、稳定、消耗硬件资源小、能够处理大并发,主要用于静态的解析,动静页面的分离;

  • 优势:

    1.作为Web服务器,nginx处理静态文件、索引文件以及自动索引效率非常高。

    2.作为代理服务器,Nginx可以实现无缓存的反向代理加速,提高网站运行速度。

    3.作为负载均衡服务器,Nginx既可以在内部直接支持Rails和PHP,也可以支持HTTP代理服务器,对外进行服务。同时支持简单的容错和利用算法进行负载均衡。

  • 在性能方面,Nginx在实现上非常注重效率。它采用内核Poll模型,可以支持更多的并发连接,最大可以支持对50 000个并发连接数的响应,而且占用很低的内存资源。

  • 在稳定性方面,Nginx采取了分阶段资源分配技术,使得对CPU与内存的占用率非常低。Nginx官方表示Nginx保持10 000个没有活动的连接,这些连接只占2.5M内存,因此,类似DOS这样的攻击对Nginx来说基本上是没有任何作用的。

  • 在高可用性方面,Nginx支持热部署,启动速度特别迅速,因此可以在不间断服务的情况下,对软件版本或者配置进行升级,即使运行数月也无需重新启动,几乎可以做到7*24小时的不间断运行。

Nginx实现原理;

Nginx核心组件:

核心模块:HTTP模块、EVENT事件模块、MAIL模块。

基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块、HTTP Rewrite模块

第三方模块:HTTP Upstream Request Hash模块、Notice模块、HTTP Access Key模块。

Nginx模块分类(基于功能):

  • Handlers:处理器模块,此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。

  • Filters:过滤器模块,此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。

  • Proxies:代理类模块,此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

Nginx的进程模型:

单工作进程模式:除主进程外,还有一个工作进程,工作进程是单线程的,默认为此模式;

多工作进程模式:每个工作进程包含多个线程;

Nginx master进程:

1.接收外界传递给Nginx的信号,进而管理服务的状态等;

2.管理worker进程,向各worker进程发送信号,监控worker进程的运行状态,当worker进程异常情况下退出后,会自动重新启动新的worker进程;

3.master进程充当整个进程组与用户的交互接口,同时对进程进行监护。它不需要处理网络事件,不负责业务的执行,只会通过管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。

worker进程:

1.处理基本的网络事件,多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核♥数一致;

Nginx支持高并发的原因;

I/O模型之select:

1.每个连接对应一个描述。select模型受限于 FD_SETSIZE(即进程最大打开的描述符数),linux2.6.35为1024,实际上linux每个进程所能打开描数字的个数仅受限于内存大小,然而在设计select的系统调用时,却是参考FD_SETSIZE的值。可通过重新编译内核更改此值,但不能根治此问题,对于百万级的用户连接请求即便增加相应进程数,仍显得杯水车薪;
2、select每次请求都会扫描一个文件描述符的集合,这个集合的大小是作为select第一个参数传入的值。但是每个进程所能打开文件描述符若是增加了,扫描的效率也将减小;
3、内核到用户空间,采用内存复制方式传递信息,这样就增加了不必要的复制延迟;
I/O模型之epoll模型:

1.请求无文件描述字大小限制,仅与内存大小相关;

2.epoll返回时已经明确的知道哪个socket fd发生了什么事件,不用像select那样再一个个比对;

3.内核到用户空间,采用共享内存方式传递消息,使用mmap加速内核与用户空间的消息传递;

apache:Apache 2.2.9之前只支持select模型,2.2.9之后支持epoll模型;

Nginx:支持epoll模型;

LB负载均衡集群分两类: LVS (四层)和 nginx或haproxy (七层)

客户端通过访问分发器的VIP来访问网站

       |

现在应用更复杂,比如现在网站页面有: .php .html .png .jpeg .jsp 等, 有动态页面有静态页面。静态页面一般是不变的,想访问更快些,前面学习过SQUID。

       |

但是前面的LVS是四层的。基于IP的。现在需要在应用层基于不同的应用进行分发。

       |

七层LB , Nginx / Haproxy都可以支持7层LB

理想的效果是这样:

静态文件处理:可以使用nginx 或apache

动文件处理: apache ,tomcat

图片文件处理: squid

使用nginx实现动静分离的负载均衡集群

Nginx 负载均衡基础知识

Nginx 的 upstream 负载的5种方式,目前最常用 前3 种方式

  • 1)、轮询(默认)

    每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。

  • 2)、weight

指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。

  • 3)、ip_hash

    每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。

  • 4)、fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

  • 5)、url_hash(第三方) url哈西

按访问url的hash结果来分配请求,使同样的url定向到同一个后端服务器,后端服务器为缓存时比较有效

正向代理和反向代理

反向代理,外部机器通过网关访问网关后面服务器上的内容,网关起到了反向代理的功能,我们平时通过浏览器访问远程的web服务器大都是这样实现的。

正向代理,就是上面的过程反过来,我们平时说的代理上网,局域网中的用户通过网关做代理访问外部的网络。

使用nginx实现负载均衡和动静分离

  • 源码编译安装nginx

一、安装nginx时必须先安装相应的编译工具和相关依赖

[root@harry63 ~]# yum -y install gcc gcc-c++ autoconf automake
[root@harry63 ~]# yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel

zlib:nginx提供gzip模块,需要zlib库支持
openssl:nginx提供ssl功能
pcre:支持地址重写rewrite功能

  • 安装nginx:
[root@harry63 ~]# ll nginx-1.8.0.tar.gz  -h  #整个nginx文件不到只813K,很小
-rw-r--r-- 1 root root 813K Jul 14 20:17 nginx-1.8.0.tar.gz
[root@harry63 ~]# tar -zxvf nginx-1.8.0.tar.gz  -C /usr/local/src/
[root@harry63 ~]# cd /usr/local/src/nginx-1.8.0/
[root@harry63 ~]# ./configure --prefix=/usr/local/nginx  --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module

##查看参数:
[root@harry63 nginx-1.8.0]# ./configure  --help | grep mp4

  • 参数说明:

--with-http_dav_module 启用ngx_http_dav_module支持(增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法)默认情况下为关闭,需编译开启

--with-http_stub_status_module启用ngx_http_stub_status_module支持(获取nginx自上次启动以来的工作状态)

--with-http_addition_module 启用ngx_http_addition_module支持(作为一个输出过滤器,支持不完全缓冲,分部分响应请求)

--with-http_sub_module 启用ngx_http_sub_module支持(允许用一些其他文本替换nginx响应中的一些文本)

--with-http_flv_module 启用ngx_http_flv_module支持(提供寻求内存使用基于时间的偏移量文件)

--with-http_mp4_module 启用对mp4文件支持(提供寻求内存使用基于时间的偏移量文件)

  • 编译和安装: (查看CPU逻辑数cat /proc/cpuinfo | grep processor | wc -l)
[root@harry63 ~]#make -j 4
[root@harry63 ~]#make  install
  • 生成运行nginx的用户:
[root@harry63 nginx-1.8.0]# useradd -u 8000 -s /sbin/nologin  nginx

[root@harry63 nginx-1.8.0]# id !$
id nginx
uid=8000(nginx) gid=8000(nginx) groups=8000(nginx)

  • nginx主要目录结构说明:

[root@harry63 /]# ls /server/nginx-1.8.0/

conf html logs sbin

conf #配置文件

conf #配置文件

html #网站根目录

logs #日志

sbin #nginx启动脚本

  • 主配置文件:
[root@harry63 /]# ls /server/nginx-1.8.0/conf/nginx.conf
  • 启动nginx:
[root@harry63 /]# /server/nginx-1.8.0/sbin/nginx   
[root@harry63 /]# netstat -antup | grep :80
tcp        0     0 0.0.0.0:80                 0.0.0.0:*                   LISTEN      5281/httpd       

[root@harry63 /]# netstat -antup | grep :80

  • 开机启动:

[root@harry63 nginx-1.8.0]# echo '/server/nginx-1.8.0/sbin/nginx & ' >> /etc/rc.local

测试在浏览器访问:

http://192.168.1.63/

nginx服务日常操作:

  • 测试配置文件语法:
[root@harry63 nginx-1.8.0]# /server/nginx-1.8.0/sbin/nginx -t
nginx: the configuration file /server/nginx-1.8.0/conf/nginx.confsyntax is ok
nginx: configuration file /server/nginx-1.8.0/conf/nginx.conf test is successful
  • 重新加载配置文件
[root@harry63 nginx-1.8.0]# /server/nginx-1.8.0/sbin/nginx -s reload
  • 关闭nginx
[root@harry63 /]# /server/nginx-1.8.0/sbin/nginx -s stop
[root@harry63 /]# /server/nginx-1.8.0/sbin/nginx -s start #没有start参数
nginx: invalid option: "-s start"

配置nginx成为分发器,实现动静分离

[root@harry63 conf]# cd  /server/nginx-1.8.0/conf    #配置文件目录
[root@harry63 conf]# cp nginx.conf nginx.conf.back   #备份一下配置文件
[root@harry63 conf]# vim nginx.conf    
[root@harry63 nginx-1.8.0]# vim /server/nginx-1.8.0/conf/nginx.conf  #指定启动nginx用户
改:# user nobody;
为:user nginx nginx;  

改:

location / {

 root   html;

index  index.html index.htm;          #在location / { 。。。} 中添加以下内容 #定义分发策略

location / {

root   html;
        index index.html index.htm;
if ($request_uri ~* \.html$){

               proxy_pass http://htmlservers;

      }   

   if ($request_uri ~* \.php$){

               proxy_pass http://phpservers;

      }  

              proxy_pass http://picservers;
      }

把以下内容注释掉,否则php文件直接在nginx服务器上解析了,不再解析给后端服务器:

location ~ .php$ {
 73 #           root          html;
 74 #           fastcgi_pass   127.0.0.1:9000;
 75 #           fastcgi_index  index.php;
 76 #           fastcgi_param  SCRIPT_FILENAME  /server/nginx-1.8.0/html$fastcgi_script_name;
 77 #           include        fastcgi_params;
 78 #       }
  • 定义负载均衡设备的 Ip

在配置文件nginx.conf的最后一行}前,添加以下内容:

    upstream  htmlservers {   #定义负载均衡服务器组名称
   server 192.168.1.62:80;  
   server 192.168.1.64:80;
     }
     
      upstream phpservers{
    server 192.168.1.62:80;
    server 192.168.1.64:80;
    }
    upstream picservers {
    server 192.168.1.62:80;
    server 192.168.1.64:80;
    }

后期可根据需要,配置成具体业务的IP地址

wq保存退出。

  • 重新加载nginx服务器配置文件:
[root@harry63 conf]# /server/nginx-1.8.0/sbin/nginx -t
nginx: the configuration file /server/nginx-1.8.0/conf/nginx.conf syntax is ok
nginx: configuration file /server/nginx-1.8.0/conf/nginx.conf test is successful

[root@harry63 conf]# /server/nginx-1.8.0/sbin/nginx -s reload
  • 配置web服务器:
[root@harry62 html]# yum install httpd  php -y
  • 生成静态测试文件:
[root@harry62 html]#echo 192.168.1.62 > /var/www/html/index.html
  • 生成动态测试文件:
[root@harry62 html]#vim  /var/www/html/test.php   #写如以下内容:
192.168.1.62-php
<?php
phpinfo();
?>
  • 生成图片文件:

上传如下图片,到“Rich七哥62网站/var/www/html/目录下:

  • 启动apache服务器:

[root@harry62 html]# service httpd restart

  • 配置后端服务器: Rich七哥64

IP: 192.168.1.64

  • 配置web服务器:

[root@harry64 html]# yum install httpd php -y

  • 生成静态测试文件:

echo 192.168.1.64 > /var/www/html/index.html

  • 生成动态测试文件:
vim  /var/www/html/test.php   #写如以下内容:
192.168.1.64-php
<?php
phpinfo();
?>

生成图片文件:

上传图片,到“Rich七哥64网站/var/www/html/目录下:

[root@harry64 html]# service httpd restart

到此nginx实现负载均衡结束。

测试负载均衡

测试转发静态页面:

http://192.168.1.63/

http://192.168.1.63/

测试转发动态页面:

http://192.168.1.63/test.php

http://192.168.1.63/test.php

测试转发图片:

http://192.168.1.63/pic.jpg

http://192.168.1.63/pic.jpg

测试自动剔除坏的节点:

[root@harry64 html]# service httpd stop

Stopping httpd: [ OK ]

访问:

http://192.168.1.63/pic.jpg

http://192.168.1.63/pic.jpg

都访问到:

测试性能:

扩展: 文件打开数过多

[root@harry64 html]# ab -n 1000 -c 1000 http://192.168.1.62/index.html #运行正常

[root@harry64 html]# ab -n 2000 -c 2000 http://192.168.1.62/index.html #报错

This is ApacheBench, Version 2.3 <$Revision: 655654 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.1.62 (be patient)

socket: Too many open files (24) # 测试时,一次打开的socket文件太多。

ulimit -a #查看

ulimit -n

1024

系统默认一个进程最多同时允许打开1024的文件

解决:

ulimit -n 10240 #报错的解决方法

Nginx负载的5种策略设置方法(在nginx配置文件里添加):

1、轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

upstream backserver {
server 192.168.1.62;
server 192.168.1.64;
}

2、指定权重

指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

upstream backserver {
server 192.168.1.62 weight=1;
server 192.168.1.64 weight=2;
}

3、IP绑定 ip_hash

每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

upstream backserver {
ip_hash;
server 192.168.1.62:80;
server 192.168.1.64:80;
}

4、fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

upstream backserver {
server server1;
server server2;
fair;
}

5、url_hash(第三方)

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}

总结,扩展:

如有tomcat ,apache,squid 配置为如下:

[root@harry63 conf]# vim nginx.conf  #  在最后添加以下内容。   定义Rich七哥服务器组

upstream tomcat_servers {
        server 192.168.1.2:8080;
       server  192.168.1.1:8080;
       server  192.168.1.11:8080;
}

upstream apache_servers {
       server  192.168.1.5:80;
       server  192.168.1.177:80;
       server  192.168.1.15:80;
}

upstream squid_servers {
       server  192.168.1.26:3128;
       server  192.168.1.55:3128;
       server  192.168.1.18:3128;

}
posted @ 2019-11-06 10:59  Rich七哥  阅读(314)  评论(0编辑  收藏  举报