1、Haproxy概述;
2、Haproxy原理实现;
3、Nginx、LVS、Haproxy对比;
4、Haproxy配置文件讲解;
5、案例:Haproxy+Nginx+Tomcat搭建高可用集群;css
概述:Haproxy是一个开源的高性能的反向代理或者说是负载均衡服务软件之一,由C语言编写而成,支持会话保持、七层处理、健康检查、故障修复后自动加载、动静分离。HAProxy运行在当前的硬件上,彻底能够支持数以万计的并发链接;
Haproxy软件引入了frontend,backend的功能,frontend(acl规则匹配)能够运维管理人员根据任意HTTP请求头作规则匹配,而后把请求定向到相关的backend(server pools等待前端把请求转过来的服务器组)。html
代理模式:
1.四层tcp代理:例如:可用于邮件服务内部协议通讯服务器、Mysql服务等;
2.七层应用代理:例如:HTTP代理或https代理。在4层tcp代理模式下,Haproxy仅在客户端和服务器之间双向转发流量。可是在7层模式下Haproxy会分析应用层协议,而且能经过运行、拒绝、交换、增长、修改或者删除请求(request)或者回应(reponse)里指定内容来控制协议。
四层代理:
ISO参考模型中的第四层传输层。四层负载均衡也称为四层交换机,它主要是经过分析IP层及TCP/UDP层的流量实现的基于IP加端口的负载均衡。常见的基于四层的负载均衡器有LVS、F5等。以常见的TCP应用为例,负载均衡器在接收到第一个来自客户端的SYN请求时,会经过设定的负载均衡算法选择一个最佳的后端服务器,同时将报文中目标IP地址修改成后端服务器IP,而后直接转发给该后端服务器,这样一个负载均衡请求就完成了。从这个过程来看,一个TCP链接是客户端和服务器直接创建的,而负载均衡器只不过完成了一个相似路由器的转发动做。在某些负载均衡策略中,为保证后端服务器返回的报文能够正确传递给负载均衡器,在转发报文的同时可能还会对报文原来的源地址进行修改。整个过程下图所示。
七层代理:
ISO参考模型中的最高层第七层应用层。七层负载均衡也称为七层交换机,此时负载均衡器支持多种应用协议,常见的有HTTP、FTP、SMTP等。七层负载均衡器能够根据报文内容,再配合负载均衡算法来选择后端服务器,所以也称为“内容交换器”。好比,对于Web服务器的负载均衡,七层负载均衡器不但能够根据“IP+端口”的方式进行负载分流,还能够根据网站的URL、访问域名、浏览器类别、语言等决定负载均衡的策略。例如,有两台Web服务器分别对应中英文两个网站,两个域名分别是A、B,要实现访问A域名时进入中文网站,访问B域名时进入英文网站,这在四层负载均衡器中几乎是没法实现的,而七层负载均衡能够根据客户端访问域名的不一样选择对应的网页进行负载均衡处理。常见的七层负载均衡器有HAproxy、Nginx等。
这里仍以常见的TCP应用为例,因为负载均衡器要获取到报文的内容,所以只能先代替后端服务器和客户端创建链接,接着,才能收到客户端发送过来的报文内容,而后再根据该报文中特定字段加上负载均衡器中设置的负载均衡算法来决定最终选择的内部服务器。纵观整个过程,七层负载均衡器在这种状况下相似于一个代理服务器。整个过程以下图所示。
调度算法:
balance roundrobin:表示简单的轮询,负载均衡基础算法
balance static-rr:表示根据权重
balance leastconn:表示最少链接者先处理
balance source:表示根据请求源IP
balance uri:表示根据请求的URI;
balance url_param:表示根据请求的URl参数来进行调度
balance hdr(name):表示根据HTTP请求头来锁定每一次HTTP请求;
balance rdp-cookie(name):表示根据据cookie(name)来锁定并哈希每一次TCP请求。前端
总结:
大型网站架构:对性能有严格要求的时候可使用lvs或者硬件F5,就单纯从负载均衡的角度来讲,lvs也许会成为主流,更适合如今大型的互联网公司;
中型网站架构:对于页面分离请求由明确规定,而且性能有严格要求时,可使用haproxy;
中小型网站架构:好比日 PV 小于1000万,须要进行高并发的网站或者对网络不太严格的时候,可使用nginx;java
global:全局配置区域参数是进程级的,一般是和操做系统相关。这些参数通常只设置一次,若是配置无误,就不须要再次进行修改;linux
defaults:配置默认参数,这些参数能够被用到frontend,backend,Listen组件;nginx
frontend:处理请求的虚拟节点,Frontend能够将匹配到本地区域的请求交给下边的backend;
backend:后端服务集群的配置,是真实服务器,一个Backend对应一个或者多个实体服务器;web
配置文件样例:正则表达式
案例拓扑:算法
案例步骤:
搭建并配置nginx节点,准备网页,启动服务,测试节点(两台nginx配置相同,在此列出一台的配置);
搭建并配置tomcat节点,准备网页,启动服务,测试节点(两台tomcat配置相同,在此列出一台的配置);
安装Haproxy程序软件;
配置Haproxy服务;
启动Haproxy服务;
客户端访问测试验证集群;
将Haproxy的日志文件分离(便于查看);
配置Haproxy服务的日志管理界面;
客户端访问测试Haproxy的日志管理界面;sql
搭建并配置nginx节点,准备网页,启动服务,测试节点(两台nginx配置相同,在此列出一台的配置); [root@ng1 ~]# yum -y install pcre-devel zlib-devel [root@ng1 ~]# useradd -M -s /sbin/nologin nginx [root@ng1 ~]# tar zxvf nginx-1.12.2.tar.gz -C /usr/src/ [root@ng1 ~]# cd /usr/src/nginx-1.12.2/ [root@ng1 nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module [root@ng1 nginx-1.12.2]# make && make install [root@ng1 nginx-1.12.2]# cd [root@ng1 ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ [root@ng1 ~]# vi /usr/lib/systemd/system/nginx.service [Unit] Description=nginxapi After=network.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStart=/usr/local/nginx/sbin/nginx ExecReload=kill -s HUP $(cat /usr/local/nginx/logs/nginx.pid) ExecStop=kill -s QUIT $(cat /usr/local/nginx/logs/nginx.pid) PrivateTmp=Flase [Install] WantedBy=multi-user.target [root@ng1 ~]# echo "192.168.100.102" >>/usr/local/nginx/html/index.html [root@ng1 ~]# systemctl start nginx [root@ng1 ~]# systemctl enable nginx [root@ng1 ~]# netstat -utpln |grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3538/nginx: master 搭建并配置tomcat节点,准备网页,启动服务,测试节点(两台tomcat配置相同,在此列出一台的配置); [root@tm1 ~]# ls apache-tomcat-9.0.10.tar.gz jdk-8u171-linux-x64.tar.gz [root@tm1~]# rpm -qa |grep java [root@tm1 ~]# tar zxvf jdk-8u171-linux-x64.tar.gz [root@tm1 ~]# mv jdk1.8.0_171/ /usr/local/java [root@tm1 ~]# ls /usr/local/java bin db javafx-src.zip lib man release THIRDPARTYLICENSEREADME-JAVAFX.txt COPYRIGHT include jre LICENSE README.html src.zip THIRDPARTYLICENSEREADME.txt [root@tm1 ~]# cat <<END >>/etc/profile export JAVA_HOME=/usr/local/java export PATH=$PATH:/usr/local/java/bin END [root@tm1~]# source /etc/profile [root@tm1 ~]# java -version java version "1.8.0_171" Java(TM) SE Runtime Environment (build 1.8.0_171-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode) [root@tm1 ~]# tar zxvf apache-tomcat-9.0.10.tar.gz [root@tm1 ~]# mv apache-tomcat-9.0.10 /usr/local/tomcat [root@tm1 ~]# ls /usr/local/tomcat bin conf lib LICENSE logs NOTICE RELEASE-NOTES RUNNING.txt temp webapps work [root@tm1 ~]# vi /usr/local/tomcat/conf/server.xml 150 <Context docBase="/web/webapp" path="" reloadable="false"></Context> :wq [root@tm1 ~]# mkdir -p /web/webapp [root@tm1 ~]# vi /web/webapp/index.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>JSP TEST PAGE1 </title> </head> <body> <% out.println("Welcome to test site;http://192.168.100.104");%> </body> </html> [root@tm1 ~]# /usr/local/tomcat/bin/startup.sh ##启动apache-tomcat [root@tm1 ~]# netstat -utpln |grep 8080 tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 14758/java 安装Haproxy程序软件; [root@ha ~]# yum -y install pcre-devel bzip2-devel ##安装依赖软件包 [root@ha ~]# tar zxvf haproxy-1.4.24.tar.gz -C /usr/src/ [root@ha ~]# cd /usr/src/haproxy-1.4.24/ [root@ha haproxy-1.4.24]# uname -r 3.10.0-693.5.2.el7.x86_64 [root@ha haproxy-1.4.24# make TARGET=linux310 ##make编译,指定系统内核版本为3.10 [root@ha haproxy-1.4.24]# make install [root@ha haproxy-1.4.24]# cd 配置Haproxy服务; [root@ha ~]# mkdir /etc/haproxy ##建立配置文件目录 [root@ha ~]# cp /usr/src/haproxy-1.4.24/examples/haproxy.cfg /etc/haproxy/ [root@ha ~]# vi /etc/haproxy/haproxy.cfg ##修改主配置文件以下 global log 127.0.0.1 local0 info ##定义日志级别; log 127.0.0.1 local1 notice maxconn 4096 ##设定每一个haproxy进程所接受的最大并发链接数 uid 99 ##指定运行服务的用户和组 gid 99 daemon ##指定运行模式为daemon,以守护进程的方式工做在后台 defaults log global ##采起global中的日志配置 mode http ##默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK option httplog ##采用http日志格式记录日志 option dontlognull ##不记录健康检查的日志记录 option httpclose ##关闭保持链接 retries 3 ##检查节点最多失败次数 maxconn 2000 ##最大链接数,定义不得大于global中的值 contimeout 5000 ##链接超时时间,毫秒,在此期间,如若客户端与服务端没法成功创建链接,则断掉 clitimeout 50000 ##设置链接客户端发送数据时的成功链接最长等待时间,单位为毫秒,如若在这期间没法请求成功,则断掉 srvtimeout 50000 ##设置服务器端回应客户端数据发送的最长等待时间,若是在这期间还没法发送成功,则断掉 ##################无分离页面需求的配置############## #listen webcluster 0.0.0.0:80 ##指定haproxy服务监听地址和端口 # option httpchk GET /index.html ##指定http请求方法和默认文件 # balance roundrobin ##指定轮询调度算法 # server inst1 192.168.100.155:80 check inter 2000 fall 3 ##定义web节点,检测心跳频率,单位为毫秒,定义检查节点最多失败次数 # server inst2 192.168.100.156:80 check inter 2000 fall 3 ##################有分离页面需求的配置############## frontend http ##定义名称为http bind *:80 ##指定监听地址和端口 acl linuxfan1 hdr_end(host) -i 192.168.100.101 ##指定类型为访问路径的域名,-i不区分大小写 acl linuxfan2 hdr_end(host) -i www.linuxfan.cn acl linuxfan3 path_end -i .jsp .do .css .js ##指定请求文件格式为.jsp #acl linuxfan3 hdr_reg -i \.(css|png|jpg|jpeg|gif|ico|swf|xml|txt|pdf|do|jsp|js)$ ##调用正则表达式 acl linuxfan4 path_end -i .html .css .png .jpg .jpeg .xml ##指定请求文件格式为.html acl linuxfan5 path_beg -i /WebRoot ##指定访问URL中的路径,如http://www.linuxfan.cn/WebRoot/index.jsp use_backend dongtai if linuxfan1 linuxfan3 use_backend dongtai if linuxfan2 linuxfan3 use_backend dongtai if linuxfan1 linuxfan5 linuxfan3 use_backend dongtai if linuxfan2 linuxfan5 linuxfan3 default_backend jingtai ##默认的请求使用backend dongtai backend jingtai ##定义backend :jingtai mode http ##定义模式 balance roundrobin ##定义调度算法为轮询 server jingtai01 192.168.100.102:80 check inter 2000 fall 3 ##定义节点 server jingtai02 192.168.100.103:80 check inter 2000 fall 3 backend dongtai mode http balance roundrobin server dongtai01 192.168.100.104:8080 check inter 2000 fall 3 server dongtai02 192.168.100.105:8080 check inter 2000 fall 3 启动Haproxy服务; [root@ha ~]# cp /usr/src/haproxy-1.4.24/examples/haproxy.init /etc/init.d/haproxy [root@ha ~]# chmod +x /etc/init.d/haproxy [root@ha ~]# ln -s /usr/local/sbin/haproxy /usr/sbin/ [root@ha ~]# /etc/init.d/haproxy start [root@ha ~]# netstat -utpln |grep haproxy tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1264/haproxy udp 0 0 0.0.0.0:52177 0.0.0.0:* 1264/haproxy
客户端访问测试验证集群;
将Haproxy的日志文件分离(便于查看); [root@ha ~]# vi /etc/rsyslog.conf 15 $ModLoad imudp 16 $UDPServerRun 514 ##打开此配置项的注释,使rsyslog服务能够接受udp协议514端口的系统日志消息 74 local0.* /var/log/haproxy/ha-info.log 75 local1.* /var/log/haproxy/ha-notice.log ##在haproxy主配置文件中所指定的日志设备和日志级别将其输出到不一样的文件中,以方便查看; :wq [root@ha ~]# vi /etc/sysconfig/rsyslog SYSLOGD_OPTIONS="-r -m 0 -c 2" ##-r 接收udp 514号端口的系统日志消息;-m 0 为日志消息添加时间等的标记 ;-c 2表示使用兼容模式 :wq [root@ha ~]# systemctl restart rsyslog [root@ha ~]# /etc/init.d/haproxy restart [root@ha ~]# tail -f /var/log/haproxy/ha-info.log Jul 27 18:14:44 localhost haproxy[1375]: 192.168.100.1:52965 [27/Jul/2018:18:14:44.167] http dongtai/dongtai01 0/0/0/2/3 200 349 - - ---- 0/0/0/0/0 0/0 "GET /index.jsp HTTP/1.1" 配置Haproxy服务的日志管理界面; [root@ha ~]# vi /etc/haproxy/haproxy.cfg ###在后边添加 listen status 0.0.0.0:8080 ##监控8080端口 stats enable ##开启stats的模块 stats uri /stats ##指定访问的url stats auth admin:123456 ##指定登录监控页面的用户名密码 stats realm (Haproxy\ statistic) ##定义页面的提示信息 [root@ha ~]# /etc/init.d/haproxy restart
客户端访问测试Haproxy的日志管理界面;