使用nginx-haproxy搭建负载均衡实现动静分离

一、    使用nginx实现动静分离的负载均衡集群
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 的 upstream 负载的5种方式,目前最常用 前3 种方式
1)、轮询(默认)
      每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
      2)、weight
      指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。
      3)、ip_hash
      每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
      4)、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
         5)、url_hash(第三方) url哈西
      按访问url的hash结果来分配请求,使同样的url定向到同一个后端服务器,后端服务器为缓存时比较有效


二、    搭建nginx负载均衡,实现动静分离
1、    拓扑图
  

2、    源码编译nginx
安装依赖包

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


zlib:nginx提供gzip模块,需要zlib库支持
openssl:nginx提供ssl功能
pcre:支持地址重写rewrite功能
上传nginx的源码包到服务器

[root@xuegod110 ~]# ls
anaconda-ks.cfg  nginx-1.12.2.tar.gz
[root@xuegod110 ~]# tar xf nginx-1.12.2.tar.gz -C /usr/local/src/
[root@xuegod110 ~]# cd /usr/local/src/nginx-1.12.2/
[root@xuegod110 nginx-1.12.2]# ./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@xuegod110 nginx-1.12.2]# make && make install


查看编译的参数:

[root@xuegod110 nginx-1.12.2]# ./configure  --help

参数:
--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文件支持(提供寻求内存使用基于时间的偏移量文件)

3、    创建用户、配置nginx

[root@xuegod110 ~]# useradd -u 8000 -s /sbin/nologin nginx

nginx的主要目录文件

[root@xuegod110 ~]# ll /usr/local/nginx/
total 4
drwxr-xr-x. 2 root root 4096 Jul 17 18:55 conf      #配置文件
drwxr-xr-x. 2 root root   40 Jul 17 18:55 html      #网站根目录
drwxr-xr-x. 2 root root    6 Jul 17 18:55 logs       #日志
drwxr-xr-x. 2 root root   19 Jul 17 18:55 sbin       #nginx启动脚本

主配置文件

[root@xuegod110 ~]# ll /usr/local/nginx/conf/nginx.conf
-rw-r--r--. 1 root root 2656 Jul 17 18:55 /usr/local/nginx/conf/nginx.conf

启动nginx

[root@xuegod110 ~]# /usr/local/nginx/sbin/nginx
[root@xuegod110 ~]# netstat -antup | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      15284/nginx: maste

配置开机启动:

[root@xuegod110 ~]# echo '/server/nginx/sbin/nginx &' >> /etc/rc.local

配置系统启动脚本

[root@xuegod110 ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx
[root@xuegod110 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

4、    nginx日常用法
测试配置文件语法

[root@xuegod110 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

重新加载配置文件(不重启nginx)

[root@xuegod110 ~]# nginx -s reload

关闭nginx

[root@xuegod110 ~]# nginx -s stop

启动nginx

[root@xuegod110 ~]# /usr/local/nginx/sbin/nginx

5、    配置nginx成为分发器,实现动静分离
备份nginx的主配置文件

[root@xuegod110 ~]# cd /usr/local/nginx/
[root@xuegod110 nginx]# cp conf/nginx.conf conf/nginx.conf.bak

修改配置文件

[root@xuegod110 nginx]# vim conf/nginx.conf
改:
2 user  nginx;

改:
43         location / {
44             root   html;
45             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服务器上解析了,不再解析给后端服务器:
    76 #       location ~ \.php$ {
 77 #           root           html;
 78 #           fastcgi_pass   127.0.0.1:9000;
 79 #           fastcgi_index  index.php;
 80 #           fastcgi_param  SCRIPT_FILENAME  /server/nginx-1.8.0/html$fastcgi_script_name;
 81 #           include        fastcgi_params;
 82 #       }

定义负载均衡设备的lp
在配置文件nginx.conf的最后一行}前,添加以下内容:
upstream  htmlservers {   #定义负载均衡服务器组名称
         server 192.168.1.120:80;   
         server 192.168.1.130:80;
 }
 upstream  phpservers{
         server 192.168.1.120:80;   
         server 192.168.1.130:80;
 }
 upstream  picservers {
         server 192.168.1.120:80;   
         server 192.168.1.130:80;
 }   



我们配置的都是一样的IP地址,生产环境中可以根据实际的业务需求配置不同的服务器IP地址

保存退出,检查语法是否错误

[root@xuegod110 nginx]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

重启加载配置文件

[root@xuegod110 nginx]# nginx -s reload

6、    配置后端服务器xuegod120
安装httpd

[root@xuegod120 ~]# yum -y install httpd php

生成静态测试文件

[root@xuegod120 ~]# echo xuegod120 > /var/www/html/index.html

生成动态测试文件

[root@xuegod120 ~]# vim /var/www/html/test.php
xuegod120.cn-php
<?php
phpinfo();
?>

生成图片文件
上传图片到web的根目录下,命名为pic.jpg
 

[root@xuegod120 ~]# mv timg_\(2\).jpg /var/www/html/pic.jpg
[root@xuegod120 ~]# ll /var/www/html/pic.jpg
-rw-r--r-- 1 root root 75784 Mar 23 20:20 /var/www/html/pic.jpg

启动httpd服务器

[root@xuegod120 ~]# systemctl start httpd

7、    配置xuegod130服务器
安装httpd和php

[root@xuegod130 ~]# yum -y install httpd php

生成静态页面

[root@xuegod130 ~]# echo xuegod130 > /var/www/html/index.html

生成动态页面

[root@xuegod130 ~]# vim /var/www/html/test.php
xuegod130.cn-php
<?php
phpinfo();
?>

上传图片,命名为pic.jpg

[root@xuegod130 ~]# mv pic..jpg /var/www/html/pic.jpg
[root@xuegod130 ~]# ll /var/www/html/pic.jpg
-rw-r--r-- 1 root root 112491 Mar 23 20:19 /var/www/html/pic.jpg

重启httpd服务

[root@xuegod130 ~]# systemctl start httpd

8、    测试效果
测试转发静态页面
 

测试转发动态页面
 

测试转发图片
 



三、    对网站进行压测
扩展: 文件打开数过多

[root@xuegod120  ~]# ab -n 1000 -c 1000 http://192.168.1.110/index.html  #运行正常
[root@xuegod120  ~]# ab -n 2000 -c 2000 http://192.168.1.110/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.110 (be patient)
socket: Too many open files (24)           #测试时,一次打开的socket文件太多。

[root@xuegod120  ~]#  ulimit -a  #查看
[root@xuegod120  ~]# ulimit -n 
1024
系统默认一个进程最多同时允许打开1024的文件

解决:
[root@xuegod120  ~]# ulimit -n 10240         #报错的解决方法

Nginx负载的5种策略设置方法:
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 
upstream backserver { 
server 192.168.1.120; 
server 192.168.1.130; 

2、指定权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 
upstream backserver { 
server 192.168.1.120 weight=1; 
server 192.168.1.130 weight=2; 

3、IP绑定 ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 
upstream backserver { 
ip_hash; 
server 192.168.1.120:80; 
server 192.168.1.130: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@xuegod110 conf]# vim nginx.conf  #  在最后添加以下内容。   定义服务器组
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;
}


四、    使用haproxy实现负载均衡集群
1、    haproxy概述
HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。根据官方数据,其最高极限支持10G的并发。
HAProxy特别适用于那些负载特大的web站点, 这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
其支持从4层至7层的网络交换,即覆盖所有的TCP协议。就是说,Haproxy 甚至还支持 Mysql的均衡负载。

相同点:在功能上,proxy通过反向代理方式实现 WEB均衡负载。和 Nginx,ApacheProxy,lighttpd,Cheroke 等一样。
不同点:Haproxy 并不是 web 服务器。以上提到所有带反向代理均衡负载的产品,都清一色是 WEB 服务器。简单说,就是他们能处理解析页面的。而Haproxy 仅仅是一款的用于均衡负载的应用代理。其自身并不能提供web服务。
但其配置简单,拥有非常不错的服务器健康检查功能还有专门的系统状态监控页面,当其代理的后端服务器出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入。


www.haproxy.org  #打不开
http://haproxy.com/   #收费
http://haproxy.1wt.eu/    社区版地址, 打不开
https://github.com/haproxy/haproxy/releases/  在github 可以下载

2、    搭建haproxy负载均衡集群
1)    拓扑图

2)    安装haproxy
注意:这里如果是在上面实验的基础上做的haproxy,那么就先停止nginx服务,因为haproxy也是用80端口来进行数据转发。

[root@xuegod110 ~]# nginx -s stop

上传haproxy包到服务器

[root@xuegod110 ~]# ls
anaconda-ks.cfg  haproxy-1.7.9.tar.tar  
[root@xuegod110 ~]# tar xf haproxy-1.7.9.tar.tar -C /usr/local/src/
[root@xuegod110 ~]# cd /usr/local/src/haproxy-1.7.9/
[root@xuegod110 haproxy-1.7.9]# uname -r
3.10.0-862.el7.x86_64


 
注意:haproxy的安装是基于linux的内核版本来进行编译安装的

[root@xuegod110 haproxy-1.7.9]# make TARGET=linux2628

haproxy的安装路径,可以通过修改配置文件来修改,也可以通过安装来直接制定

[root@xuegod110 haproxy-1.7.9]# vim Makefile

先安装依赖包

[root@xuegod110 haproxy-1.7.9]# yum -y install make gcc gcc-c++ openssl-devel

指定安装路径

[root@xuegod110 haproxy-1.7.9]# make install PREFIX=/usr/local/haproxy

3)    生成配置文件

[root@xuegod110 ~]# ll /usr/local/haproxy/
total 0
drwxr-xr-x. 3 root root 21 Jul 17 19:30 doc
drwxr-xr-x. 2 root root 21 Jul 17 19:30 sbin
drwxr-xr-x. 3 root root 17 Jul 17 19:30 share
[root@xuegod110 ~]# mkdir /usr/local/haproxy/etc/
[root@xuegod110 ~]# vim /usr/local/haproxy/etc/haproxy.cfg
global
log 127.0.0.1  local0
#log 127.0.0.1  local1 notice
#log loghost    local0 info
maxconn 4096
chroot /usr/local/haproxy
uid 99                          #所属运行的用户uid
gid 99                          #所属运行的用户组
daemon                        #以后台形式运行haproxy
nbproc 1                   #启动1个haproxy实例。# #工作进程数量(CPU数量) ,实际工作中,应该设置成和CPU核心数一样。 这样可以发挥出最大的性能。
pidfile /usr/local/haproxy/run/haproxy.pid  #将所有进程写入pid文件
#debug   #调试错误时用
#quiet        #安静

defaults
log    global
log    127.0.0.1      local3        #日志文件的输出定向。产生的日志级别为local3. 系统中local1-7,用户自己定义
mode    http       #工作模式,所处理的类别,默认采用http模式,可配置成tcp作4层消息转发
option  httplog                        #日志类别,记载http日志
option  httpclose      #每次请求完毕后主动关闭http通道,haproxy不支持keep-alive,只能模拟这种模式的实现
option  dontlognull    #不记录空连接,产生的日志
option  forwardfor      #如果后端服务器需要获得客户端真实ip需要配置的参数,可以从Http Header中获得客户端ip
option  redispatch            #当serverid对应的服务器挂掉后,强制定向到其他健康服务器
retries 2                    #2次连接失败就认为服务器不可用,主要通过后面的check检查
maxconn 2000               #最大连接数
balance roundrobin                    #负载均衡算法
stats  uri    /haproxy-stats          #haproxy 监控页面的访问地址 # 可通过 http://localhost:80/haproxy-stats 访问
timeout connect      5000              #连接超时时间。 单位:ms 毫秒
timeout client       50000              #客户端连接超时时间
timeout server      50000              #服务器端连接超时时间
mode    http
option  httpchk GET /index.html          #健康检测#注意实际工作中测试时,应该下载某一个页面来进行测试,因此这个页面应该是个小页面,而不要用首页面。这里是每隔一秒检查一次页面。

frontend http          #前端配置,http名称可自定义
bind 0.0.0.0:80        #发起http请求80端口,会被转发到设置的ip及端口
default_backend http_back   #转发到后端 写上后端名称

backend http_back    #后端配置,名称上下关联
server  s1 192.168.1.120:80  weight 3 check  #后端的主机 IP &权衡
server  s2 192.168.1.130:80  weight 3 check  #后端的主机 IP &权衡
#server node1 192.168.179.131:8081 check inter 2000 rise 3 fall 3 weight 30
    # inter 2000 健康检查时间间隔2秒
    # rise 3 检测多少次才认为是正常的
    # fall 3 失败多少次才认为是不可用的
# weight 30 权重

4)    负载均衡算法
#source 根据请求源IP
    #static-rr 根据权重
    #leastconn 最少连接者先处理
    #uri 根据请求的uri
    #url_param 根据请求的url参数
    #rdp-cookie 据据cookie(name)来锁定并哈希每一次请求
    #hdr(name) 根据HTTP请求头来锁定每一次HTTP请求
#roundrobin 轮询方式5)    生成启动脚本

[root@xuegod110 ~]# cp /usr/local/src/haproxy-1.7.9/examples/haproxy.init /etc/init.d/haproxy
[root@xuegod110 ~]# chmod 755 /etc/init.d/haproxy
[root@xuegod110 ~]# >/etc/init.d/haproxy
[root@xuegod110 ~]# vim /etc/init.d/haproxy
#!/bin/sh
# chkconfig: - 85 15
# description: HA-Proxy server
# processname: haproxy
# config: /usr/local/haproxy/etc/haproxy.cfg
# pidfile: /usr/local/haproxy/run/haproxy.pid

# Source function library.
if [ -f /etc/init.d/functions ]; then
  . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
  . /etc/rc.d/init.d/functions
else
  exit 0
fi

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

# This is our service name
BASENAME=`haproxy`

BIN=/usr/sbin/haproxy

CFG=/usr/local/haproxy/etc/haproxy.cfg
[ -f $CFG ] || exit 1

PIDFILE=/usr/local/haproxy/run/haproxy.pid
LOCKFILE=/usr/local/haproxy/run/haproxy

RETVAL=0

start() {
  quiet_check
  if [ $? -ne 0 ]; then
    echo "Errors found in configuration file, check it with '$BASENAME check'."
    return 1
  fi

  echo -n "Starting $BASENAME: "
  daemon $BIN -D -f $CFG -p $PIDFILE
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && touch $LOCKFILE
  return $RETVAL
}

stop() {
  echo -n "Shutting down $BASENAME: "
  killproc $BASENAME -USR1
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
  [ $RETVAL -eq 0 ] && rm -f $PIDFILE
  return $RETVAL
}

restart() {
  quiet_check
  if [ $? -ne 0 ]; then
    echo "Errors found in configuration file, check it with '$BASENAME check'."
    return 1
  fi
  stop
  start
}

reload() {
  if ! [ -s $PIDFILE ]; then
    return 0
  fi

  quiet_check
  if [ $? -ne 0 ]; then
    echo "Errors found in configuration file, check it with '$BASENAME check'."
    return 1
  fi
  $BIN -D -f $CFG -p $PIDFILE -sf $(cat $PIDFILE)
}

check() {
  $BIN -c -q -V -f $CFG
}

quiet_check() {
  $BIN -c -q -f $CFG
}

rhstatus() {
  status $BASENAME
}

condrestart() {
  [ -e $LOCKFILE ] && restart || :
}

# See how we were called.
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    restart
    ;;
  reload)
    reload
    ;;
  condrestart)
    condrestart
    ;;
  status)
    rhstatus
    ;;
  check)
    check
    ;;
  *)
    echo $"Usage: $BASENAME {start|stop|restart|reload|condrestart|status|check}"
    exit 1
esac
 
exit $?

6)    复制haproxy文件到/usr/sbinx下

[root@xuegod110 ~]# cp /usr/local/haproxy/sbin/haproxy /usr/sbin/

7)    生成目录
haproxy配置文件内有对象的文件生成,需要创建对应的目录

[root@xuegod110 ~]# mkdir -p /usr/local/haproxy/run

8)    修改目录的所有者

[root@xuegod110 ~]# chown nobody /usr/local/haproxy/ -R

9)    配置日志收集

[root@xuegod110 ~]# vim /etc/rsyslog.conf
15  $ModLoad imudp            #取消注释
16  $UDPServerRun 514          #取消注释
73  local7.*          /var/log/boot.log       #下面添加两行
74  local3.*          /var/log/haproxy.log
75  local0.*          /var/log/haproxy.log

重启日志服务,生效

[root@xuegod110 ~]# systemctl restart rsyslog.service

3、    haproxy启动和停止服务
1)    特殊启动方法

[root@xuegod110 ~]# /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.cfg

2)    停止方法
安装killall命令

[root@xuegod110 ~]# yum -y install psmisc
[root@xuegod110 ~]# killall haproxy

3)    脚本启动方法

[root@xuegod110 ~]# /etc/init.d/haproxy start
Reloading systemd:                                         [  OK  ]
Starting haproxy (via systemctl):                          [  OK  ]
[root@xuegod110 ~]# systemctl restart haproxy

4、    这里两台后端服务器我们就不需要配置了,因为上面的nginx负载均衡动静分离实验已经配好了。

5、    测试效果
测试静态页面
 

测试动态页面
 

测试图片转发
 


测试haproxy的监控页面


注:
相关配置文件和启动脚本可以从这个配置模版中获得
[root@xuegod110 haproxy-1.7.9]# cd /root/haproxy-1.7.9/examples/ 
[root@xuegod110 examples]# ls

配置随机启动
[root@xuegod110 examples]# chkconfig --add haproxy
[root@xuegod110 examples]# chkconfig haproxy on
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值