一、 使用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定向到同一个后端服务器,后端服务器为缓存时比较有效
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
生成图片文件
上传图片到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
[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
测试转发图片
[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负载均衡动静分离实验已经配好了。
注:
相关配置文件和启动脚本可以从这个配置模版中获得
[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