LVS+Keepalived+Nginx+Tomcat群集环境搭建 项目描述: 由于公司业务的不断扩展,网站并发量不断增大,现有部署的(Apache+Tomcat)网站环境提供的服务无法满足实际需求——存在单节点故障、响应延迟等突出问题,因此,需要设计出具有可扩展的、高可用性负载均衡Web群集架构,以满足公司业务不断扩展的需求。 项目拓扑设计: file:///C:\Users\ADMINI~1.PC-\AppData\Local\Temp\ksohtml\wps8B7D.tmp.png 项目实施: 一、 基础环境 1、 操作系统——RHEL6.5或CentOS6.5 2、 负载调度器层部署2节点——主、备调度器,采用DR模式 3、 服务器池层部署2节点——Nginx+Tomcat 4、 关闭Iptables防火墙、禁用SELinux 5、 IP地址规划——略。 二、 项目实施步骤 1、部署负载调度器层(2节点)——VIP:172.16.1.200 1)主调度器(LVS-DR-Master)IP:172.16.1.18 A.调整内核/proc响应参数 [iyunv@localhost ~]# vim /etc/sysctl.conf net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.eth0.send_redirects = 0 B.配置虚拟IP地址(VIP)和配置负载分配策略,均由keepalived根据配置文件自动配置和管理。 [iyunv@localhost ~]# vim /etc/keepalived/keepalived.conf global_defs { router_id LVS_MASTER # 设置lvs的id,在一个网络应该是唯一的 } vrrp_instance VI_1 { state MASTER # 指定keepalived的角色,MASTER为主,BACKUP为备 interface eth0 # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) virtual_router_id 66 # 虚拟路由编号,主从要一直 priority 100 # 优先级,数值越大,获取处理请求的优先级越高 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.1.200 # 定义虚拟ip(VIP),可多设,每行一个 } } # 定义对外提供的LVS的VIP以及port virtual_server 172.16.1.200 80 { delay_loop 6 # 设置健康检查时间,单位为秒 lb_algo wrr # 设置负载调度的算法为wrr lb_kind DR # 设置lvs实现负载的机制,有NAT、TUN、DR三个模式 #nat_mask 255.255.255.0 #persistence_timeout 0 # 同一IP 0秒内的请求都发到同个real server protocol TCP real_server 172.16.1.19 8080 { # 指定real server1的ip地址 weight 3 # 配置节点权值,数值越大权重越高 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 } } real_server 172.16.1.12 8080 { weight 3 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 } } } C.启动Keepalived服务,并设置为系统服务,实现开机自启动! [iyunv@localhost ~]# chkconfig --level 35 keepalived on D.查看VIP地址 [iyunv@localhost ~]# ip addr show dev eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:01:31:a1 brd ff:ff:ff:ff:ff:ff inet 172.16.1.18/16 brd 172.16.255.255 scope global eth0 inet 172.16.1.200/32 scope global eth0 inet 172.16.1.201/32 scope global eth0 inet6 fe80::20c:29ff:fe01:31a1/64 scope link valid_lft forever preferred_lft forever E. 查看节点负载分配情况 [iyunv@localhost ~]# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.1.200:80 wrr -> 172.16.1.12:8080 Route 3 0 0 -> 172.16.1.19:8080 Route 3 0 0 2)备调度器(LVS-DR-Slave)IP:172.16.1.20 A.调整内核/proc响应参数 [iyunv@localhost ~]# vim /etc/sysctl.conf net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.eth0.send_redirects = 0 B.配置虚拟IP地址(VIP)和配置负载分配策略,均由keepalived根据配置文件自动配置和管理。 [iyunv@localhost ~]# vim /etc/keepalived/keepalived.conf global_defs { router_id LVS_BACKUP # 设置lvs的id,在一个网络应该是唯一的 } vrrp_instance VI_1 { state BACKUP # 指定keepalived的角色,MASTER为主,BACKUP为备 interface eth0 # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) virtual_router_id 66 # 虚拟路由编号,主从要一直 priority 95 # 优先级,数值越大,获取处理请求的优先级越高 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.1.200 # 定义虚拟ip(VIP),可多设,每行一个 } } # 定义对外提供的LVS的VIP以及port virtual_server 172.16.1.200 80 { delay_loop 6 # 设置健康检查时间,单位为秒 lb_algo wrr # 设置负载调度的算法为wrr lb_kind DR # 设置lvs实现负载的机制,有NAT、TUN、DR三个模式 #nat_mask 255.255.255.0 #persistence_timeout 0 # 同一IP 0秒内的请求都发到同个real server protocol TCP real_server 172.16.1.19 8080 { # 指定real server1的ip地址 weight 3 # 配置节点权值,数值越大权重越高 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 } } real_server 172.16.1.12 8080 { weight 3 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 } } } C.启动Keepalived服务,并设置为系统服务,实现开机自启动! [iyunv@localhost ~]# chkconfig --level 35 keepalived on D.查看VIP地址 [iyunv@localhost ~]# ip addr show dev eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:27:3d:8b brd ff:ff:ff:ff:ff:ff inet 172.16.1.20/16 brd 172.16.255.255 scope global eth0 inet6 fe80::20c:29ff:fe27:3d8b/64 scope link valid_lft forever preferred_lft forever E. 查看节点负载分配情况 [iyunv@localhost ~]# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.1.200:80 wrr -> 172.16.1.12:8080 Route 3 0 0 -> 172.16.1.19:8080 Route 3 0 0 2、部署服务器池层——Nginx+Tomcat(2节点) 1)搭建Tomcat+Nginx环境(192.168.1.12) ####先部署Tomcat环境#### A.安装java环境 [iyunv@localhost 桌面]# yum -y remove java [iyunv@localhost 桌面]# cd /usr/src [iyunv@localhost src]# tar xf jdk-7u65-linux-x64.gz [iyunv@localhost src]# mv jdk1.7.0_65/ /usr/local/java [iyunv@localhost src]# vi /etc/profile.d/java.sh \\建立java脚本 export JAVA_HOME=/usr/local/java export PATH=$PATH:$JAVA_HOME/bin [iyunv@localhost src]# source /etc/profile.d/java.sh [iyunv@localhost src]# java -version B.安装tomcat [iyunv@localhost ~]# cd /usr/src [iyunv@localhost src]# tar xf apache-tomcat-7.0.54.tar.gz [iyunv@localhost src]# mv apache-tomcat-7.0.54 /usr/local/tomcat7 [iyunv@localhost src]# /usr/local/tomcat7/bin/startup.sh [iyunv@localhost src]# netstat -anpt | grep 8080 打开浏览器验证tomcat http://127.0.0.1:8080 [iyunv@localhost conf]#cd /usr/local/tomcat7/conf [iyunv@localhost conf]# vi server.xml \\tomcat的配置文件,内容保持默认 C.建立java的web站点 [iyunv@localhost conf]# mkdir -pv /web/webapp1 [iyunv@localhost conf]# vi /web/webapp1/index.jsp 添加网页代码 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>JSP test1 page</title> </head> <body> </body> </html> [iyunv@localhost conf]# vi server.xml \\cd /usr/local/tomcat7/conf 找到host name位置,添加红色代码,注意大小写(124行) <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context docBase="/web/webapp1" path="" reloadable="false"> </Context> 解释: Reloadable:是否开启类的监控功能,如果为true ,则tomcat 会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes 目录的变化,自动装载新的应用程序,我们可以在不重起tomcat 的情况下改变应用程序 [iyunv@localhost conf]# /usr/local/tomcat7/bin/shutdown.sh [iyunv@localhost conf]# /usr/local/tomcat7/bin/startup.sh ####再部署Nginx环境#### A.环境准备 [iyunv@localhost yum.repos.d]# yum list [iyunv@localhost yum.repos.d]# yum clean all \\清除yum缓存 [iyunv@localhost yum.repos.d]# yum -y install gcc* \\GNU编译器套件,用以支持C语言等的编译环境 [iyunv@localhost yum.repos.d]# yum remove httpd [iyunv@localhost yum.repos.d]# rpm -qa httpd B.安装Nginx a)安装支持的软件 [iyunv@localhost ~]# yum -y install pcre-devel zlib-devel \\有些系统会提示已经安装过了 注释: PCRE(Perl Compatible Regular Expressions即:perl语言兼容正则表达式)是一个用C语言编写的正则表达式函数库。zlib:应用程序依靠zlib压缩函式库 b)创建运行用户和组 [iyunv@localhost ~]# useradd -M -s /sbin/nologin nginx C.编译安装Nginx [iyunv@localhost ~]# cd /usr/src [iyunv@localhost src]# tar zxvf nginx-1.6.0.tar.gz [iyunv@localhost nginx-1.6.0]# cd nginx-1.6.0 [iyunv@localhost nginx-1.6.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module 注释:--with-http_stub_status_module:负责监控并统计http的运行状态和访问情况 [iyunv@localhost nginx-1.6.0]# make && make install [iyunv@localhost nginx-1.6.0]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin [iyunv@localhost nginx-1.6.0]# ls -l /usr/local/sbin/nginx [iyunv@localhost nginx-1.6.0]# nginx -t \\对配置文件进行检测 [iyunv@localhost nginx-1.6.0]# nginx \\启动nginx [iyunv@localhost nginx-1.6.0]# netstat -anpt | grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 31930/nginx [iyunv@localhost nginx-1.6.0]# yum -y install elinks [iyunv@localhost nginx-1.6.0]# elinks http://localhost [iyunv@localhost nginx-1.6.0]# killall -s HUP nginx \\重载nginx [iyunv@localhost nginx-1.6.0]# killall -s QUIT nginx \\退出nginx进程 D.编辑服务控制脚本 [iyunv@localhost ~]# vi /etc/init.d/nginx #!/bin/bash # chkconfig: - 99 20 # description: Nginx Server Control Script PROG="/usr/local/nginx/sbin/nginx" PIDF="/usr/local/nginx/logs/nginx.pid" case "$1" in start) $PROG ;; stop) kill -s QUIT $(cat $PIDF) ;; restart) $0 stop $0 start ;; reload) kill -s HUP $(cat $PIDF) ;; status) [ -f $PID ] &> /dev/null if [ $? -eq 0 ] then netstat -anpt | grep nginx else echo "Nginx is not running." fi ;; *) echo "Usage: $0 {start|stop|restart|reload|status}" esac exit 0 E.添加为系统服务 [iyunv@localhost ~]# nginx -t \\语法检查 [iyunv@localhost ~]# chmod +x /etc/init.d/nginx [iyunv@localhost ~]# chkconfig --add nginx ####调整Nginx主配置文件####(172.16.1.12和172.16.1.19主配置文件一样) [iyunv@localhost ~]# vim /usr/local/nginx/conf/nginx.conf user nginx; #运行用户 worker_processes 1; #启动进程,通常设置成和cpu的数量相等 #全局错误日志及PID文件 error_log /usr/local/nginx/logs/error.log; error_log /usr/local/nginx/logs/error.log notice; error_log /usr/local/nginx/logs/error.log info; pid /usr/local/nginx/logs/nginx.pid; # 工作模式及连接数上线 events { use epoll; #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的>性能 worker_connections 1024; #单个后台worker process进程的最大并发链接数 } #设定http服务器,利用它的反向代理功能提供负载均衡支持 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; #设定请求缓冲 server_names_hash_bucket_size 128; client_header_buffer_size 32K; large_client_header_buffers 4 32k; # client_max_body_size 8m; #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用, #必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime. sendfile on; tcp_nopush on; tcp_nodelay on; #连接超时时间 #keepalive_timeout 0; keepalive_timeout 65; #开启gzip压缩,降低传输流量 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; #添加tomcat列表,负载均衡的服务器都放在这 upstream tomcat_server { #server tomcat地址:端口号 weight表示权值,权值越大,被分配的几率越大; server 172.16.1.19:8080 weight=4 max_fails=2 fail_timeout=30s; server 172.16.1.12:8080 weight=4 max_fails=2 fail_timeout=30s; } server { listen 80; #监听端口 server_name 172.16.1.200; #对外提供服务的网址(域名或者ip) #默认请求设置 location / { index index.jsp index.html index.htm; #设定访问的默认首页 root /web/webapp1; #站点根目录,此目录下存放我们的web项目 } #charset koi8-r; #access_log logs/host.access.log main; #所有的jsp页面均由tomcat处理 location ~ \.(jsp|jspx|dp)?$ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://tomcat_server; #转向tomcat处理 } #所有的静态文件直接读取不经过tomcat,nginx自己处理 location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 1h; } #log_format access '$remote_addr - $remote_user [$time_local] "$request" '$status $body_bytes_sent "$http_referer"' '"$http_user_agent" $http_x_forwarded_for'; #access_log /usr/local/nginx/logs/ubitechtest.log access;#设定访问日志的存放路径 # redirect server error pages to the static page /50x.html # #定义错误提示页面 error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } } ####配置群VIP/添加内核参数/添加路由#### 以上内容均通过编写脚本realserver实现,具体内容如下: [iyunv@localhost ~]# vim /etc/init.d/realserver #!/bin/bash #chkconfig: - 85 80 # description: Config realserver lo and apply noarp SNS_VIP=172.16.1.200 . /etc/rc.d/init.d/functions case "$1" in start) ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP /sbin/route add -host $SNS_VIP dev lo:0 echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce sysctl -p >/dev/null 2>&1 echo "RealServer Start OK" ;; stop) ifconfig lo:0 down route del $SNS_VIP >/dev/null 2>&1 echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce echo "RealServer Stoped" ;; *) echo "Usage: $0 {start|stop}" exit 1 esac exit 0 [iyunv@localhost ~]# chmod +x /etc/init.d/realserver [iyunv@localhost ~]# chkconfig --level 35 realserver on [iyunv@localhost ~]# chkconfig --list realserver realserver 0:关闭 1:关闭 2:关闭 3:启用 4:关闭 5:启用 6:关闭 [iyunv@localhost ~]# service realserver stop RealServer Stoped [iyunv@localhost ~]# ip addr show dev lo 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever [iyunv@localhost ~]# service realserver start RealServer Start OK [iyunv@localhost ~]# ip addr show dev lo 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet 172.16.1.200/32 brd 172.16.1.200 scope global lo:0 inet6 ::1/128 scope host valid_lft forever preferred_lft forever [iyunv@localhost ~]# 2)搭建Tomcat+Nginx环境(192.168.1.19) 配置过程和172.16.1.12一样,详细过程略。 1、####先部署Tomcat环境#### 2、####再部署Nginx环境#### 3、####调整Nginx主配置文件####(1.12和1.19主配置文件内容一样) 4、####配置群VIP/添加内核参数/添加路由#### 三、 测试验证——详细过程略 1、 日志验证——/var/log/message。 2、 PING 172.16.1.200验证。 3、 负载均衡验证——节点是否可以快速切换。 4、 高可用性验证——模拟一台Nginx宕机,是否影响正常访问。 5、 节点的健康监测验证——停止一个Tomcat服务,是否影响正常访问。 知识拓展: 1、 LVS+Keepalived+Nginx+Tomcat+Mysql主主复制高可用性群集架构,其负载调度器主配置文件内容如下: [iyunv@localhost ~]# vim /etc/keepalived/keepalived.conf global_defs { # notification_email { # } # smtp_server 192.168.1.114 # smtp_connection_timeout 30 router_id LVS_MASTER # 设置lvs的id,在一个网络应该是唯一的 } vrrp_instance VI_1 { state MASTER # 指定keepalived的角色,MASTER为主,BACKUP为备 interface eth0 # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) virtual_router_id 66 # 虚拟路由编号,主从要一直 priority 100 # 优先级,数值越大,获取处理请求的优先级越高 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.1.200 # 定义虚拟ip(VIP),可多设,每行一个 172.16.1.201 } } # 定义对外提供的LVS的VIP以及port virtual_server 172.16.1.200 80 { delay_loop 6 # 设置健康检查时间,单位为秒 lb_algo wrr # 设置负载调度的算法为wrr lb_kind DR # 设置lvs实现负载的机制,有NAT、TUN、DR三个模式 #nat_mask 255.255.255.0 #persistence_timeout 0 # 同一IP 0秒内的请求都发到同个real server protocol TCP real_server 172.16.1.19 8080 { # 指定real server1的ip地址 weight 3 # 配置节点权值,数值越大权重越高 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 } } real_server 172.16.1.12 8080 { weight 3 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 } } } virtual_server 172.16.1.201 3306 { delay_loop 6 # 设置健康检查时间,单位为秒 lb_algo wrr # 设置负载调度的算法为wrr lb_kind DR # 设置lvs实现负载的机制,有NAT、TUN、DR三个模式 #nat_mask 255.255.255.0 #persistence_timeout 0 # 同一IP 0秒内的请求都发到同个real server protocol TCP real_server 172.16.1.16 3306 { # 指定real server1的ip地址 weight 3 # 配置节点权值,数值越大权重越高 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } real_server 172.16.1.17 3306 { weight 3 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } } 查看节点负载分配新情况 [iyunv@localhost ~]# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.1.200:80 wrr -> 172.16.1.12:8080 Route 3 0 1 -> 172.16.1.19:8080 Route 3 1 0 TCP 172.16.1.201:3306 wrr -> 172.16.1.16:3306 Route 3 0 2 -> 172.16.1.17:3306 Route 3 1 2 [iyunv@localhost ~]# 2、Nginx/LVS/HAProxy负载均衡软件的优缺点详解
一般对负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术。具体的应用需求还得具体分析,如果是中小型的Web应用,比如日PV小于1000万,用Nginx就完全可以了;如果机器不少,可以用DNS轮询,LVS所耗费的机器还是比较多的;大型网站或重要的服务,且服务器比较多时,可以考虑用LVS。一种是通过硬件来进行进行,常见的硬件有比较昂贵的F5和Array等商用的负载均衡器,它的优点就是有专业的维护团队来对这些服务进行维护、缺点就是花销太大,所以对于规模较小的网络服务来说暂时还没有需要使用;另外一种就是类似于Nginx/LVS/HAProxy的基于Linux的开源免费的负载均衡软件,这些都是通过软件级别来实现,所以费用非常低廉。 目前关于网站架构一般比较合理流行的架构方案:Web前端采用Nginx/HAProxy+Keepalived作负载均衡器;后端采用MySQL数据库一主多从和读写分离,采用LVS+Keepalived的架构。当然要根据项目具体需求制定方案。 下面说说各自的特点和适用场合。 NginxNginx的优点是: 1. 工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是它目前广泛流行的主要原因之一,Nginx单凭这点可利用的场合就远多于LVS了。 2. Nginx对网络稳定性的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势之一;相反LVS对网络稳定性依赖比较大,这点本人深有体会; 3. Nginx安装和配置比较简单,测试起来比较方便,它基本能把错误用日志打印出来。LVS的配置、测试就要花比较长的时间了,LVS对网络依赖比较大。 4. 可以承担高负载压力且稳定,在硬件不差的情况下一般能支撑几万次的并发量,负载度比LVS相对小些。 5. Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx会把上传切到另一台服务器重新处理,而LVS就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而不满。 6. Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP也是近几年非常流行的web架构,在高流量的环境中稳定性也很好。 7. Nginx现在作为Web反向加速缓存越来越成熟了,速度比传统的Squid服务器更快,可以考虑用其作为反向代理加速器。 8. Nginx可作为中层反向代理使用,这一层面Nginx基本上无对手,唯一可以对比Nginx的就只有lighttpd了,不过lighttpd目前还没有做到Nginx完全的功能,配置也不那么清晰易读,社区资料也远远没Nginx活跃。 9. Nginx也可作为静态网页和图片服务器,这方面的性能也无对手。还有Nginx社区非常活跃,第三方模块也很多。 Nginx的缺点是: 1. Nginx仅能支持http、https和Email协议,这样就在适用范围上面小些,这个是它的缺点。 2. 对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测。不支持Session的直接保持,但能通过ip_hash来解决。 LVSLVS 是使用Linux内核集群实现的一个高性能、高可用的负载均衡服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。 LVS的优点是: 1. 抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的,对内存和cpu资源消耗比较低。 2. 配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率。 3. 工作稳定,因为其本身抗负载能力很强,自身有完整的双机热备方案,如LVS+Keepalived,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived。 4. 无流量,LVS只分发请求,而流量并不从它本身出去,这点保证了均衡器IO的性能不会收到大流量的影响。 5. 应用范围比较广,因为LVS工作在4层,所以它几乎可以对所有应用做负载均衡,包括http、数据库、在线聊天室等等。 LVS的缺点是: 1. 软件本身不支持正则表达式处理,不能做动静分离;而现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。 2. 如果是网站应用比较庞大的话,LVS/DR+Keepalived实施起来就比较复杂了,特别后面有Windows Server的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived就简单多了。 HAProxyHAProxy的特点是: 1. HAProxy也是支持虚拟主机的。 2. HAProxy的优点能够补充Nginx的一些缺点,比如支持Session的保持,Cookie的引导;同时支持通过获取指定的url来检测后端服务器的状态。 3. HAProxy跟LVS类似,本身就只是一款负载均衡软件;单纯从效率上来讲HAProxy会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。 4. HAProxy支持TCP协议的负载均衡转发,可以对MySQL读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,大家可以用LVS+Keepalived对MySQL主从做负载均衡。 5. HAProxy负载均衡策略非常多,HAProxy的负载均衡算法现在具体有如下8种:
0. roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的; 1. static-rr,表示根据权重,建议关注; 2. leastconn,表示最少连接者先处理,建议关注; 3. source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解决session问题的一种方法,建议关注; 4. ri,表示根据请求的URI; 5. rl_param,表示根据请求的URl参数’balance url_param’ requires an URL parameter name; 6. hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求; 7. rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。 Nginx和LVS对比的总结:Nginx工作在网络的7层,所以它可以针对http应用本身来做分流策略,比如针对域名、目录结构等,相比之下LVS并不具备这样的功能,所以Nginx单凭这点可利用的场合就远多于LVS了;但Nginx有用的这些功能使其可调整度要高于LVS,所以经常要去触碰触碰,触碰多了,人为出问题的几率也就会大。 Nginx对网络稳定性的依赖较小,理论上只要ping得通,网页访问正常,Nginx就能连得通,这是Nginx的一大优势!Nginx同时还能区分内外网,如果是同时拥有内外网的节点,就相当于单机拥有了备份线路;LVS就比较依赖于网络环境,目前来看服务器在同一网段内并且LVS使用direct方式分流,效果较能得到保证。另外注意,LVS需要向托管商至少申请多一个ip来做Visual IP,貌似是不能用本身的IP来做VIP的。要做好LVS管理员,确实得跟进学习很多有关网络通信方面的知识,就不再是一个HTTP那么简单了。 Nginx安装和配置比较简单,测试起来也很方便,因为它基本能把错误用日志打印出来。LVS的安装和配置、测试就要花比较长的时间了;LVS对网络依赖比较大,很多时候不能配置成功都是因为网络问题而不是配置问题,出了问题要解决也相应的会麻烦得多。 Nginx也同样能承受很高负载且稳定,但负载度和稳定度差LVS还有几个等级:Nginx处理所有流量所以受限于机器IO和配置;本身的bug也还是难以避免的。 Nginx可以检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点。目前LVS中 ldirectd也能支持针对服务器内部的情况来监控,但LVS的原理使其不能重发请求。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx会把上传切到另一台服务器重新处理,而LVS就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而恼火。 Nginx对请求的异步处理可以帮助节点服务器减轻负载,假如使用apache直接对外服务,那么出现很多的窄带链接时apache服务器将会占用大 量内存而不能释放,使用多一个Nginx做apache代理的话,这些窄带链接会被Nginx挡住,apache上就不会堆积过多的请求,这样就减少了相当多的资源占用。这点使用squid也有相同的作用,即使squid本身配置为不缓存,对apache还是有很大帮助的。 Nginx能支持http、https和email(email的功能比较少用),LVS所支持的应用在这点上会比Nginx更多。在使用上,一般最前端所采取的策略应是LVS,也就是DNS的指向应为LVS均衡器,LVS的优点令它非常适合做这个任务。重要的ip地址,最好交由LVS托管,比如数据库的 ip、webservice服务器的ip等等,这些ip地址随着时间推移,使用面会越来越大,如果更换ip则故障会接踵而至。所以将这些重要ip交给 LVS托管是最为稳妥的,这样做的唯一缺点是需要的VIP数量会比较多。 Nginx可作为LVS节点机器使用,一是可以利用Nginx的功能,二是可以利用Nginx的性能。当然这一层面也可以直接使用squid,squid的功能方面就比Nginx弱不少了,性能上也有所逊色于Nginx。Nginx也可作为中层代理使用,这一层面Nginx基本上无对手,唯一可以撼动Nginx的就只有lighttpd了,不过lighttpd目前还没有能做到 Nginx完全的功能,配置也不那么清晰易读。另外,中层代理的IP也是重要的,所以中层代理也拥有一个VIP和LVS是最完美的方案了。具体的应用还得具体分析,如果是比较小的网站(日PV小于1000万),用Nginx就完全可以了,如果机器也不少,可以用DNS轮询,LVS所耗费的机器还是比较多的;大型网站或者重要的服务,机器不发愁的时候,要多多考虑利用LVS。 现在对网络负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术: 第一阶段:利用Nginx或HAProxy进行单点的负载均衡,这一阶段服务器规模刚脱离开单服务器、单数据库的模式,需要一定的负载均衡,但是仍然规模较小没有专业的维护团队来进行维护,也没有需要进行大规模的网站部署。这样利用Nginx或HAproxy就是第一选择,此时这些东西上手快, 配置容易,在七层之上利用HTTP协议就可以。这时是第一选择。 第二阶段:随着网络服务进一步扩大,这时单点的Nginx已经不能满足,这时使用LVS或者商用Array就是首要选择,Nginx此时就作为LVS或者Array的节点来使用,具体LVS或Array的是选择是根据公司规模和预算来选择,Array的应用交付功能非常强大,本人在某项目中使用过,性价比也远高于F5,商用首选!但是一般来说这阶段相关人才跟不上业务的提升,所以购买商业负载均衡已经成为了必经之路。 第三阶段:这时网络服务已经成为主流产品,此时随着公司知名度也进一步扩展,相关人才的能力以及数量也随之提升,这时无论从开发适合自身产品的定制,以及降低成本来讲开源的LVS,已经成为首选,这时LVS会成为主流。 最终形成比较理想的基本架构为:Array/LVS — Nginx/Haproxy — Squid/Varnish — AppServer。
|