一、Haproxy概述;
概述:Haproxy是一个开源的高性能的反向代理或者说是负载均衡服务软件之一,由C语言编写而成,支持会话保持、七层处理、健康检查、故障修复后自动加载、动静分离。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接;
Haproxy软件引入了frontend,backend的功能,frontend(acl规则匹配)可以运维管理人员根据任意HTTP请求头做规则匹配,然后把请求定向到相关的backend(server pools等待前端把请求转过来的服务器组)。
二、Haproxy原理实现;
代理模式:
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请求。
三、常见的代理了解
1、lvs和硬件F5,是基于IP的三层负载,硬件适配性能好,处理性能强。
2、haproxy,可以适配三层负载均衡,同样可以适配七层。对于页面明确有请求分离的时候,可以使用haproxy。
3、nginx,对于日PV小于500万,对于需要进行高并发的站点,可以使用nginx代理
四、haproxy配置文件讲解
global:全局配置区域参数是进程级的,通常是和操作系统相关。这些参数一般只设置一次,如果配置无误,就不需要再次进行修改;
defaults:配置默认参数,这些参数可以被用到frontend,backend,Listen组件;
frontend:处理请求的虚拟节点,Frontend可以将匹配到本地区域的请求交给下边的backend;
backend:后端服务集群的配置,是真实服务器,一个Backend对应一个或者多个实体服务器;
五、案例:Haproxy+Nginx+Tomcat搭建高可用集群
系统类型 | IP地址 | 主机名 |
---|---|---|
Centos 7.5.1804 | ens36-192.168.137.111/24: | keepliv |
Centos 7.5.1804 | ens36-192.168.137.112/24: | nginx1 |
Centos 7.5.1804 | ens36-192.168.137.113/24: | nginx2 |
Centos 7.5.1804 | ens36-192.168.137.114/24: | tomcat1 |
Centos 7.5.1804 | ens36-192.168.137.115/24: | tomcat2 |
实例步骤
用到的安装包
安装包链接
配置nginx节点nede1、node2,准备网页,测试节点
配置参照lnmp配置
测试[root@keepliv init.d]# curl 192.168.137.112
node1
[root@keepliv init.d]# curl 192.168.137.113
node2
配置tomcat节点,准备网页启动服务,测试节点(
俩台tomcat)
安装配置haproxy程序
1、配置tomcat服务器
[root@tomcat1 ~]# ls
anaconda-ks.cfg apache-tomcat-9.0.14.tar.gz jdk-11.0.1_linux-x64_bin.tar.gz
tar zxvf jdk-11.0.1_linux-x64_bin.tar.gz
mkdir /usr/localjava
mv jdk-11.0.1 /usr/local/java
ls /usr/local/java
cat <<END >> /etc/profile
export JAVA_HOME=/usr/local/java
export PATH=$PATH:/usr/local/java/bin
END
source /etc/profile
java -version
tar zxvf apache-tomcat-9.0.14.tar.gz
mkdir /usr/local/tomcat
mv apache-tomcat-9.0.14 /usr/local/tomcat
ls /usr/local/tomcat/
/usr/local/tomcat/bin/startup.sh
netstat -lntup |grep java
[root@tomcat1 ~]# netstat -lntup |grep java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 4062/java
tcp6 0 0 :::8009 :::* LISTEN 4062/java
tcp6 0 0 :::8080 :::* LISTEN 4062/java
##tomcat2和tomcat1配置思路相同
##配置俩个的站点目录和内容
mkdir -p /web/webapp
[root@tomcat1 ~]# cat /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://tomcat1");%>
</body>
</html>
[root@tomcat1 ~]# cat -n /usr/local/tomcat/conf/server.xml
...
150 <Context docBase="/web/webapp" path="" reloadable="false"></Context> #添加了站点根目录
...
##测试
[root@keepliv init.d]# curl 192.168.137.114:8080
<html>
<head>
<title>JSP TEST PAGE1 </title>
</head>
<body>
Welcome to test site;http://tomcat1
</body>
</html>
[root@keepliv init.d]# curl 192.168.137.115:8080
<html>
<head>
<title>JSP TEST PAGE1 </title>
</head>
<body>
Welcome to test site;http://tomcat2
</body>
</html>
2、安装haproxy
yum -y install pcre-devel bzip2-devel ##安装依赖软件包
tar zxvf haproxy-1.7.9.tar.gz -C /usr/src/
cd /usr/src/haproxy-1.7.9/
uname -r #查看内核版本
make TARGET=linux310 #编译时需要指定内核版本
make install
3、配置haproxy服务:
mkdir /etc/haproxy
vim /etc/haproxy/haproxy.cfg
[root@keepliv init.d]# cat /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.137.111 ##指定类型为访问路径的域名,-i不区分大小写
acl linuxfan2 hdr_end(host) -i 192.168.137.111
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.137.112:80 check inter 2000 fall 3 ##定义节点
server jingtai02 192.168.137.113:80 check inter 2000 fall 3
backend dongtai
mode http
balance roundrobin
server dongtai01 192.168.137.114:8080 check inter 2000 fall 3
server dongtai02 192.168.137.115:8080 check inter 2000 fall 3
##启动haproxy服务
148 cp /usr/src/haproxy-1.7.9/examples/haproxy.init /etc/init.d/haproxy
149 chmod +x /etc/init.d/haproxy
150 ln -s /usr/local/sbin/haproxy /usr/sbin/
151 /etc/init.d/haproxy start
152 netstat -lntup
153 firewall-cmd --add-port=80/tcp --permanent
154 firewall-cmd --add-port=80/tcp
4、测试集群
5、配置haproxy的日志文件分离(查看haproxy日志)
[root@keepliv init.d]# cat /etc/rsyslog.conf |egrep -v '^#|^$'
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imjournal # provides access to the systemd journal
$ModLoad imudp ##接收udp系统日志
$UDPServerRun 514 ##开启udp514端口
$WorkDirectory /var/lib/rsyslog
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$IncludeConfig /etc/rsyslog.d/*.conf
$OmitLocalLogging on
$IMJournalStateFile imjournal.state
*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.* /var/log/secure
mail.* -/var/log/maillog
cron.* /var/log/cron
*.emerg :omusrmsg:*
uucp,news.crit /var/log/spooler
local7.* /var/log/boot.log
local0.* /var/log/haproxy/haproxy-info.log #指定了俩个日志级别的文件,方便查看
local1.* /var/log/haproxy/haproxy-notice.log
[root@keepliv init.d]# cat /etc/sysconfig/rsyslog
# Options for rsyslogd
# Syslogd options are deprecated since rsyslog v3.
# If you want to use them, switch to compatibility mode 2 by "-c 2"
# See rsyslogd(8) for more details
SYSLOGD_OPTIONS=""
SYSLOGD_OPTIONS="-r -m 0 -c 2"
#-r 接收udp 514号端口的系统日志消息;-m 0 为日志消息添加时间等的标记 ;-c 2表示使用兼容模式
systemctl restart rsyslog
/etc/init.d/haproxy restart
#刷新测试页面,查看日志
[root@keepliv init.d]# tail -n 5 /var/log/haproxy/haproxy-info.log
Dec 24 22:19:24 localhost haproxy[5489]: 192.168.137.1:55899 [24/Dec/2018:22:19:24.521] http dongtai/dongtai02 0/0/1/3/4 200 340 - - ---- 1/1/0/0/0 0/0 "GET /index.jsp HTTP/1.1"
Dec 24 22:19:24 localhost haproxy[5489]: 192.168.137.1:55900 [24/Dec/2018:22:19:24.679] http dongtai/dongtai01 0/0/0/3/3 200 340 - - ---- 1/1/0/0/0 0/0 "GET /index.jsp HTTP/1.1"
Dec 24 22:19:24 localhost haproxy[5489]: 192.168.137.1:55901 [24/Dec/2018:22:19:24.831] http dongtai/dongtai02 0/0/0/3/4 200 340 - - ---- 1/1/0/0/0 0/0 "GET /index.jsp HTTP/1.1"
Dec 24 22:19:25 localhost haproxy[5489]: 192.168.137.1:55902 [24/Dec/2018:22:19:25.000] http dongtai/dongtai01 0/0/1/2/4 200 340 - - ---- 1/1/0/0/0 0/0 "GET /index.jsp HTTP/1.1"
Dec 24 22:19:25 localhost haproxy[5489]: 192.168.137.1:55903 [24/Dec/2018:22:19:25.145] http dongtai/dongtai02 0/0/1/1/3 200 340 - - ---- 1/1/0/0/0 0/0 "GET /index.jsp HTTP/1.1"
[root@keepliv init.d]# tail -n 5 /var/log/haproxy/haproxy-notice.log.log
tail: 无法打开"/var/log/haproxy/haproxy-notice.log.log" 读取数据: 没有那个文件或目录
[root@keepliv init.d]# tail -n 5 /var/log/haproxy/haproxy-notice.log
Dec 24 22:18:33 localhost haproxy[5160]: Proxy jingtai stopped (FE: 0 conns, BE: 22 conns).
Dec 24 22:18:33 localhost haproxy[5160]: Proxy dongtai stopped (FE: 0 conns, BE: 19 conns).
Dec 24 22:18:33 localhost haproxy[5488]: Proxy http started.
Dec 24 22:18:33 localhost haproxy[5488]: Proxy jingtai started.
Dec 24 22:18:33 localhost haproxy[5488]: Proxy dongtai started.
6、配置haproxy服务器的日志管理web界面
[root@keepliv init.d]# firewall-cmd --add-port=9090/tcp
success
[root@keepliv init.d]# firewall-cmd --add-port=9090/tcp --permanent
success
[root@keepliv init.d]# vim /etc/haproxy/haproxy.cfg
##在最后追加
listen admin
bind :9090
server web6c 192.168.137.111:9090 check
stats enable #开启监听
stats uri /status #设置监听的url
stats auth admin:123 #认证信息
stats auth qq:123
stats realm admin\ xxx #设置认证的默认提示
stats hide-version #隐藏版本
stats refresh 10s
stats admin if TRUE #TRUE这个关键字表示只有经过认证成功后才能被管理
[root@keepliv init.d]# /etc/init.d/haproxy restart
Restarting haproxy (via systemctl): [ 确定 ]
测试
看到以上界面实验就做完了