web负载均衡

4. 负载均衡技术以及HAproxy的安装和基础配置

2021-03-25  本文已影响0人  随便写写咯

1. 负载均衡集群和HAproxy介绍

1. 提供并发支持
2. 高可用
3. 水平动态扩容
1. 在负载均衡器上, 只上线一个Web服务器(Nginx), 没问题, 就上线另一个, 这样可以查出哪个Nginx有问题. 
2. 如果Nginx没问题, 可以让防火墙把流量打到一个四层负载均衡, 进行查看, 再陆续打到其他LB
3. 如果都没有问题, 可以直接让防火墙把流量打到后端的7层Nginx
1. HA支持后台服务器动态上下线, Nginx和LVS不具备. 如果用户正在访问网站时, 把后台服务器重启, 客户端会立即报500错误.
2. HA可以通过socket文件, 直接将后端服务器下线, 而Nginx需要修改配置文件, 注释掉需要下线的服务器, 再reload nginx
3. HA和Nginx支持4层和7层负载均衡, 而LVS只支持四层负载均衡. Nginx1.9开启支持4层, 而HA对于7层的支持没有Nginx功能多, 尤其是动静分离
4. LVS的DR模型需要在后端服务器配置vip, 一旦vip丢失, 用户请求是无法响应的, 另外, 在公有云平台, 有运营商提供的四层负载均衡, 比如阿里云基于LVS的SLB
5. HA支持万兆网卡情况下, 提供百万并发
四层:Redis、Mysql、RabbitMQ、Memcache等需要基于TCP的特殊协议. 应用程序连接负载均衡器vip的域名, 这样一旦vip变化, 后端服务器ip发生变化, 只需要修改DNS或者HA配置即可, 应用程序无需更改
七层:Nginx、Tomcat、Apache、PHP 、图⽚、动静分离、API等
1. 先把后端服务器从HA上下线, 这样用户的请求会转发到其他的服务器
2. 升级或者维护服务器
3. 再添加到调度列表啊中, 上线

2. HAproxy编译安装

编译安装环境: Ubuntu-1804
lua-5.3.5
haproxy-2.2.4

注意: 在HA-1.8版本以后, 必须要先安装lua环境, 再安装HAproxy

  1. 常用Ubuntu基础命令和依赖包安装
apt -y install iproute2 make ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev gcc  iotop unzip zip libreadline-dev libsystemd-dev
  1. 编译安装lua-5.3.5

官网下载地址: http://www.lua.org/ftp/

wget -P /usr/local/src http://www.lua.org/ftp/lua-5.3.5.tar.gz
cd /usr/local/src
tar xvf lua-5.3.5.tar.gz
cd lua-5.3.5
make linux test
  1. 验证lua版本
[root@HAproxy-1:/usr/local/src/lua-5.3.5]# ./src/lua -v
Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio
  1. 编译安装HAproxy-2.2.4
[root@HAproxy-1:/usr/local/src]# ls
haproxy-2.2.4.tar.gz
[root@HAproxy-1:/usr/local/src]# tar xvf haproxy-2.2.4.tar.gz 
[root@HAproxy-1:/usr/local/src]# cd haproxy-2.2.4/
[root@HAproxy-1:/usr/local/src/haproxy-2.2.4]# make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.3.5/src LUA_LIB=/usr/local/src/lua-5.3.5/src PREFIX=/apps/haproxy 
[root@HAproxy-1:/usr/local/src/haproxy-2.2.4]# make install PREFIX=/apps/haproxy
ln -s /apps/haproxy/sbin/haproxy /usr/sbin #设置软连接, 或者直接把haproxy主程序拷贝到Service文件对应的程序的路径
[root@HAproxy-1:~]# haproxy -v
HA-Proxy version 2.2.4-de45672 2020/09/30 - https://haproxy.org/
  1. 准备Service文件和配置文件, 参考apt install的格式

Ubuntu-1804源自带的是1.8.8版本, 和新的版本有可能不兼容, 因此要从HAproxy官网先下载镜像源, 然后安装相同版本的HAproxy后获取Service和配置文件. 只要是同样主版本的Service文件和配置文件一般都是通用的

建议: 另找一个Ubuntu主机利用apt安装HAproxy来获取Service和配置文件

官网下载地址: https://haproxy.debian.net/

image.png

官方安装指导

apt-get install --no-install-recommends software-properties-common
add-apt-repository ppa:vbernat/haproxy-2.2
apt-get -y install haproxy=2.2.\*  #安装最新版HAproxy

也可通过apt-cache来查看可用版本, 来指定安装

[root@HAproxy-2:~]# apt-cache madison haproxy
   haproxy | 2.2.4-1ppa1~bionic | http://ppa.launchpad.net/vbernat/haproxy-2.2/ubuntu bionic/main amd64 Packages
   haproxy | 1.8.8-1ubuntu0.11 | http://mirrors.aliyun.com/ubuntu bionic-updates/main amd64 Packages
   haproxy | 1.8.8-1ubuntu0.10 | http://mirrors.aliyun.com/ubuntu bionic-security/main amd64 Packages
   haproxy |    1.8.8-1 | http://mirrors.aliyun.com/ubuntu bionic/main amd64 Packages
   haproxy |    1.8.8-1 | http://mirrors.aliyun.com/ubuntu bionic/main Sources
   haproxy | 1.8.8-1ubuntu0.10 | http://mirrors.aliyun.com/ubuntu bionic-security/main Sources
   haproxy | 1.8.8-1ubuntu0.11 | http://mirrors.aliyun.com/ubuntu bionic-updates/main Sources
apt -y install haproxy=2.2.4-1ppa1~bionic
[root@HAproxy-2:~]# haproxy -v
HA-Proxy version 2.2.4-1ppa1~bionic 2020/10/02 - https://haproxy.org/

查看apt自带的Service文件

[root@HAproxy-2:~]# vim /lib/systemd/system/haproxy.service 
[Unit]                                                                                                                              
Description=HAProxy Load Balancer
Documentation=man:haproxy(1)
Documentation=file:/usr/share/doc/haproxy/configuration.txt.gz
After=network-online.target rsyslog.service
Wants=network-online.target

[Service]
EnvironmentFile=-/etc/default/haproxy
EnvironmentFile=-/etc/sysconfig/haproxy  #环境变量文件可有可无
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "EXTRAOPTS=-S /run/haproxy-master.sock"  
ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS
ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE $EXTRAOPTS # -Ws表示使用master-worker工作模型, 一个主进程多个子进程
ExecReload=/usr/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed
Restart=always
SuccessExitStatus=143
Type=notify
[Install]
WantedBy=multi-user.target

将Service文件拷到编译安装的Ubuntu主机

[root@HAproxy-2:~]# scp /lib/systemd/system/haproxy.service 10.0.0.19:/lib/systemd/system/haproxy.service

创建配置文件存放路径, 需要和Service文件中定义的路径一致

mkdir -p /etc/haproxy

将apt安装的配置文件拷贝到编译安装的主机上

[root@HAproxy-2:~]# scp /etc/haproxy/haproxy.cfg 10.0.0.19:/etc/haproxy
#拷贝到编译安装的主机后要修改配置文件中admin.sock的路径
/var/lib/haproxy/admin.sock

查看配置文件

[root@HAproxy-1:~]# vim /etc/haproxy/haproxy.cfg 

global                                                                                                                              
    log /dev/log    local0
    log /dev/log    local1 notice
...
  1. 启动后可能遇到的报错和解决方法

编译安装的HAproxy会因为缺少很多信息, 导致启动失败, 可以通过查看/var/log/sysconfig日志进行查看
具体报错和解决方案如下

useradd -r -s /sbin/nologin haproxy
scp -r /etc/haproxy/errors 10.0.0.19:/etc/haproxy  #scp拷贝目录需要加-r
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 408 /etc/haproxy/errors/408.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http
    errorfile 503 /etc/haproxy/errors/503.http
    errorfile 504 /etc/haproxy/errors/504.http  
mkdir -p /var/lib/haproxy

以上问题都解决后, haproxy一般就可以正常启动了

[root@Ubuntu-1804-1:/usr/local/src/haproxy-2.2.4]# systemctl daemon-reload
[root@Ubuntu-1804-1:/usr/local/src/haproxy-2.2.4]# systemctl enable --now haproxy
Created symlink /etc/systemd/system/multi-user.target.wants/haproxy.service → /lib/systemd/system/haproxy.service.

但是此时, 会发现, 虽然haproxy已经正常启动, 但是haproxy并没有监听端口, 因为我们在配置文件中并没有指定

设定监听端口

listen admin                                                                                                                        
    bind 0.0.0.0:80

重启服务, 可以看到haproxy监听在了80端口上

LISTEN          0                128                                0.0.0.0:80                               0.0.0.0:*

到此haproxy编译安装就部署完毕了

配置文件模板

global                                                                                                                                                                                            
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /var/lib/haproxy/admin.sock mode 660 level admin expose-fd listeners
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

    # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
    log global
    mode    http
    option  httplog
    option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 408 /etc/haproxy/errors/408.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http
    errorfile 503 /etc/haproxy/errors/503.http
    errorfile 504 /etc/haproxy/errors/504.http
listen admin
    bind 0.0.0.0:80

3. HAproxy基础功能及配置

HAproxy的配置文件由两大部分组成, 分别是global和proxies部分

global: 全局配置段

针对haproxy全局生效, 
定义主进程配置及安全配置相关参数
性能调优相关参数
Debug参数
HAproxy日志, 无论请求是由哪个HAproxy进程处理的, 都会记录到一起

proxies: 代理配置段

defaults: 为frontend, backend, listen提供默认配置, 如果frontend, backend, listen定义了配置, 那么优先生效
frontend: 前端, 相当于nginx中的server语句块, 让haproxy监听在某个ip和端口上. 提供客户端访问的虚拟主机, 指定监听端口
backend: 后端, 相当于nginx中的upstream语句块, 定义后端服务器组
listen: 定义监听的虚拟主机的配置, 同时拥有前端和后端配置
#listen和F&B同时用一个即可, 要么只用lisnte, 要么frontend和backend一起用

3.1 global配置参数

chroot: 锁定运行目录, 让HA只能在这个目录运行, 即使HA被攻击, 也只能在这个目录里做操作, 一般配置为HA的安装目录, 或者自定义的权限限制比较高的目录
daemon: 以守护进程方式运行
stats socket /var/lib/haproxy/admin.sock mode 600 level admin: 通过socket文件与haproxy服务器进行非交互配置, 包括服务器上线,下线, mode表示文件的权限是600, level admin, 管理员权限, 文件路径和名字可以自定义, 只给属主和属组读写权限
user|group: 指定HA以哪个身份运行, 如果后期修改了运行用户, 重启服务可能会报错, 因为首次启动时, 会用当前的用户权限来生成对应的pid等文件, 一旦用户名改了, 很可能导致重启后, 因此新的用户对于这些文件没有权限, 导致HA无法启动

apt -y install socat
[root@Haproxy-1:~]# echo "show info" | socat stdio /var/lib/haproxy/admin.sock 
Name: HAProxy
Version: 2.2.4-de45672
Release_date: 2020/09/30
...

nbproc: 开启的haproxy子进程数(工作进程), 和CPU核数保持一致, 最大利用haproxy性能, 充分利用cpu. 另外需要开启-Ws, master和woker模型, 来提高HA性能

   #nbproc 4  #开启4个haproxy进程
   #cpu-map 1 0  #第一个进程, 和第0个cpu绑定, 以此类推
   #cpu-map 2 1
   #cp-map  3 2
   #cpu-map 4 3

nbthread: 指定每个haproxy进程开启的线程数. haproxy多进程和多线程是相斥的,要么单进程里开多个线程, 要么多个进程, 每个进程里开一个线程. 一般建议开多个进程, 每个进程开一个线程
maconn: 每个haproxy进程的最大并发连接数, 建议设置大点, 10万, 或者100万, 配置多进程提供并发
maxsslconn: 每个haproxy进程ssl最大连接数, 用在haproxy配置了证书的场景下, 只在haproxy配了证书的情况下才使用, 一般haproxy不会配置证书
maxconnrate: 每个进程每秒创建的最大连接数量, 指的是新的连接数量, 收到新的用户请求后, haproxy每秒钟能创建多个少tcp连接, 生产中需要调大
spread-checks: 后端server状态check随机提前或延长百分比时间, 建议2-5(20%-50%)之间. haproxy会对后端服务器进程周期性检测
pidfile: 指定pid文件路径
log 127.0.0.0.1 local3 info: 定义全局的syslog服务器, 最多可以定义两个

3.2 proxies配置参数

defaults [<name>]: 默认配置项, 针对以下的frontend, backend和listen生效, 可以多个name, 也可以没有
frontend <name>: 前端servername, 类似于Nginx的一个虚拟主机server, 指定前端配置, 也就是haproxy监听哪个地址和端口号
backend <name> #后端服务器组,等于nginx的upstream
listen <name> #将frontend和backend合并在⼀起配置
frontend web1
    bind 10.0.0.19:80
    mode http|tcp  #如果是代理数据库类的服务, 要用tcp, 如果是web服务器,用http. 但是tcp的性能是最高的, 一般除了有特殊要求, 否则走tcp即可

注意: 所有proxies中defaults, frontend, backend和listen的name都是严格区分大小的, 只能包含大写, 小写, 数字, -, _, "."和":". 并且name不能重复, 可以在name后面加端口号, 或使用目的以及作用描述来区分, 比如listen web_port_80, web_port_crm

四层和七层区别:

七层代理: 用户请求到达负载均衡器后, 负载均衡器会修改请求报文的源目ip地址, 源ip换成自己的ip, 目标ip换成后端服务器的ip, 代替用户向后端的服务器发起请求. 从用户到负载均衡器和从负载均衡器到后端服务器是两个不同的tcp连接. 后端服务器处理完请求后将响应报文发给负载均衡器, 负载均衡器再修改响应报文的源目ip地址, 源变为自己的ip, 目标ip变为客户端的ip, 将响应报文发给客户. 因此, 七层代理模式下, 负载均衡器要代替用户发起请求, 并且将响应报文修改源目ip后还给用户

四次代理: 负载均衡器工作在透明模式, 只是转发用户的请求和服务器回复的响应报文. 比如LVS-DR模型不会修改三层地址, 服务器看到的就是客户端的ip地址

HAproxy和Nginx无论工作在四层还是七层, 都会修改请求和响应报文的源目ip地址, 支持端口映射
而LVS-DR模型的的端口和后端服务器的端口必须一致

frontend & backend配置范例

frontend web1  #frontend和backend都可以定义多个, 只要不重名, 符合命名规范即可, frontend和backend配套使用, 一般一个frontend可以监听多个backend
    bind 10.0.0.19:80  #haproxy本地监听ip和端口号
    mode http  #7层代理
    use_backend web1-node #该frontend负责代理web1-node的backend, 通过backend名称来调用                                                                                                           

backend  web1-node #后端服务器组
    mode http #支持http
    server 10.0.0.39(servername, 自定义) 10.0.0.39:8080 check inter 3000 fall 3 rise 5 #后端服务器信息

backend  web2-node
    mode http
    server 10.0.0.49 10.0.0.49:8080 check inter 3000 fall 3 rise 5

此时如果通过客户端访问haproxy的10.0.0.19地址, 会显示503 Service Unavaiable报错, 因为 此时后端没有正常运行的服务器. 如果遇到503报错, 一般是调度的后端服务器挂了, 或者haproxy在对后端服务器进行检测时, 由于网络等原因导致超时, 因此haproxy也会认为后端服务器挂了

图片.png

web-1: 10.0.0.39
web-2: 10.0.0.49

yum -y install httpd

按照上面的端口映射, 修改apache监听端口为8080

Listen 8080

启动apache

systemctl start httpd

添加了后端服务器, 再次访问haproxy, 就可以看到后端服务器页面了, 因为frontend只配置调度了web1-node, 因此只会调度到web-1, 10.0.0.39上


图片.png

并且通过查看apache的日志可以看到, 请求是从10.0.0.19 haproxy发过来的

10.0.0.19 - - [08/Nov/2020:14:52:45 +0800] "GET /noindex/common/images/centos-header.png HTTP/1.1" 200 28888 "http://10.0.0.11/noindex/common/css/styles.css" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36 Edg/86.0.622.63"
图片.png

除了使用frontend和backend来定义监听和转发, 也可以只使用listen, 这样配置代码更简洁

listen web1
    bind 10.0.0.19:80
    mode http
    server 10.0.0.39 10.0.0.39:8080 check inter 3000 fall 3 rise 5
    server 10.0.0.49 10.0.0.49:8080 check inter 3000 fall 3 rise 5 

3.2.1 Proxies配置-defaults

defaults配置参数

3.2.2 Proxies配置-frontend

示例:

frontend WEB_PORT
  bind 80, :8080
  bind 192.168.7.102:10080, :8801-8810, 192.168.7.101:9001-9010
  mode tcp|http
  use_backend backend_name #调用的后端服务器组名称

3.2.3 Proxies配置-backend

定义一组后端服务器, backend服务器将被HA调度.

mode http|tcp #指定负载协议类型
option #配置选项
server #定义后端real server

注意: option后面加httpchk, smtpchk, mysql-check, pgsql-check, ssl-hello-chk, 可用于实现更多应用层检测功能

# 当后端代理的服务存在依赖关系时, 可以开启, 比如, 后端是Nginx反向代理php或tomcat, 再将请求转发给Nginx前, HA可以先对后端的php或tomcat做健康检查, 如果检查失败, 那么也就没有必要给Nginx转发请求了
check #对指定的后端服务器进行健康状态检查, 默认不开启. 如果不开启, 那么haproxy就不会对该后端服务器做健康检查, 这时一旦默认后端服务器挂了, 那么HAproxy还是会往其调度, 就会造成503 Service Unavilable报错
  addr IP #可指定的健康状态监测IP, 如果服务器上有多个服务是一起为用户提供服务的, 并且ip或者端口号不一样, 那么就要明确指定 addr 和 port. 比如, nginx和php-fpm如果跑在同一个服务器上, 那么haproxy就要同时检测它们俩, 以确保用户的请求能正常有响应. 
  port num #指定的健康状态检测端口, 如果服务器上有多个服务是一起为用户提供服务的, 并且ip或者端口号不一样, 那么就要明确指定 addr 和 port. 比如, nginx和php-fpm如果跑在同一个服务器上, 那么haproxy就要同时检测它们俩, 以确保用户的请求能正常有响应. 
# 示例: 该案例表面, 当HA的10.0.0.19:80手动请求时, 会先对192.1681.1 port 80这台服务器做状态检查, 只有检测通过, 才会把请求转发给10.0.0.39这个服务器, 否则即使转发给了10.0.0.39, 但是, 其它依赖的服务是不可用的, 也不会处理成功
listen web1
    bind 10.0.0.19:80
    mode http
    server 10.0.0.39 10.0.0.39:8080 check 192.1681.1 port 80 inter 3000 fall 3 rise 5
  inter num #健康状态检查间隔时间, 默认2000 ms
  fall num #后端服务器失效检查次数, 默认为3, 三次内只要成功一次, 就认为没有问题, 一旦连续失败3次, 就会踢出去
  rise num #后端服务器从下线恢复检查次数, 默认为2, 后端服务器上线后, 连续检查2次, 都成功就把它加到调度列表里
  weight #服务器权重, 默认为1, 最大为256, 0表示不参与负载均衡, 不会向其转发请求, 相当于手动把服务器从负载均衡列表踢出去. 当后端服务器配置不一样时, 把性能好配置高的服务器的权重设置大一些
  backup #将后端服务器标记为备份状态, 标记为backup后不会处理请求, 而是当所有的服务器的挂了,才会由它来处理请求.
  disabled #将后端服务器标记为不可用状态, 下线服务器
  redirect prefix http://www.xxx.yyy #将请求临时重定向至其他URL, 只适用于http模式. 因为要修改用户请求报文中的目的地址, 302临时跳转, 用户访问到haproxy时, haproxy会把请求临时重定向到指定的URL. 用户先向haproxy发起请求, haproxy在response报文中给用户回一个location URL, 提醒用户去访问另一个URL. 用户之后再请求这个URL
  maxconn <maxconn> #当前后端server的最大并发连接数, 除非后端服务器性能很差, 否则一般不设置, 这里的maxconn就是后端服务器告诉haproxy我自己最多能接受多少连接, 超出了haproxy就不会向其调度请求了. 一般不设置
  backlog <backlog> #当server的连接数达到上限后的后援队列长度, 当后端服务器达到上线了, 设置一个队列长度让请求等待. 一般不设置. 比如设置上限为10000请求, 一旦达到了10000, 后续请求就要排队

3.2.4 Proxies-listen代替frontend-backend

#使用listen替换frontend-backend的配置方式
listen WEB_PORT_80
  bind 10.0.0.11:80
  mode http
  option forwardfor
  server web1 192.168.7.101:80 check inter 3000 fall 3 rise 5
  server web2 192.168.7.102:80 check inter 3000 fall 3 rise 5

会做很多组服务器, 不能用listen.

上一篇 下一篇

猜你喜欢

热点阅读