第十八周作业

1、简述keepalived工作原理

keepalived能够为很多不支持HA功能的程序填补HA的空缺,它对外提供一个虚拟的VIP,这个VIP并不是固定在某台机器的,而是可以根据状态或事件在多台主机之间依靠优先级进行浮动。

主机将根据配置决定以什么样的角色上线,上线后,主机将开始对外以单播方式,或组播(224.0.0.18,默认)地址发送VRRP消息,携带了VRRP的优先级等信息,其他主机监听后如果判断自己的优先级较低,将被阻塞,不会发送自己的VRRP消息,此时通过优先级就决定了主备关系,VIP则浮动在主设备上。

当主设备故障时,主设备停止,或发送被降低了优先级的VRRP报文,其他备机根据超时时间,或报文的优先级,判断主设备失效,它们会开始发送自己的VRRP消息,此时网络将发生主备切换,VIP将浮动到新的主设备。

当主设备从故障中恢复后,它的优先级可能也会恢复,此时默认情况下,主设备会抢占为新的MASTER,同时导致网络出现切换,通常为了避免这样的问题需要关闭主设备的抢占功能。

如果备设备因为某种原因无法收到主设备的VRRP通告,此时备设备会认为主设备故障,会切换到Master状态,这时两台主机都会变为Master,也就是脑裂现象,此时需要人为干涉以避免误导客户端,导致网络中断。

除了上述VRRP Stack提供的功能外,Keepalived还通过checkers组件提供对后端RS的状态监控,弥补LVS的不足。

keepalived也支持system call,能够调用脚本,判断并执行状态的通知、切换等功能。

keepalived也能作为IPVS的用户空间程序,不需要依赖ipvsadm,直接下发IPVS规则。

2、编译安装haproxy

#!/bin/bash
#****************************************************************************************#
#Author:                        Yabao11
#QQ:                            what QQ,no QQ
#Date:                          2022-01-04
#FileName:                      nginx.sh
#URL:                           https://github.com/yabao11
#Description:                   Test Script
#Copyright (C):                 2022 All rights reserved
#*******************************定义颜色*************************************************#
RED="\e[1;31m"
GREEN="\e[1;32m"
SKYBLUE="\e[1;36m"
YELLOW="\e[1;43m"
BLUE="\e[1;44m"
END="\e[0m"
RandomColor="\e[1;32m"
#****************************************************************************************#
function Ostype {
    if grep -i -q "release 6" /etc/centos-release;then
      echo Centos6
    elif grep -i -q Centos-8 /etc/os-release;then
      echo Centos
    elif grep -i -q Centos-7 /etc/os-release;then
      echo Centos7
    elif grep -i -q Ubuntu /etc/os-release;then
      echo Ubuntu
    elif grep -i -q "RedHat" /etc/os-release;then
      echo Redhat
    fi
}

function color {
  RES_COL=60
  MOVE_TO_COL="echo -en \E[${RES_COL}G"
  SETCOLOR_SUCCESS="echo -en \E[1;32m"
  SETCOLOR_FAILURE="echo -en \E[1;31m"
  SETCOLOR_WARNING="echo -en \E[1;33m"
  SETCOLOR_NORMAL="echo -en \E[0m"
  echo -n "$1" && $MOVE_TO_COL
  echo -n "["
  if [[ $2 = "success" || $2 = "0" ]]; then
    ${SETCOLOR_SUCCESS}
    echo -n "  OK  "
  elif [[ $2 = "failure" || $2 = "1" ]]; then
    ${SETCOLOR_FAILURE}
    echo -n "FAILED"
  else
    ${SETCOLOR_WARNING}
    echo -n "WARNING"
  fi
  ${SETCOLOR_NORMAL}
  echo -n "]"
  echo
}

function inputerror {
    echo -en "输入错误!"
    echo -e "\E[${RES_COL}G["$RED"退出"$END"]"
}

lua_file=${2:-lua-5.3.5}
haproxy_file=${1:-haproxy-2.4.12}
local_ip=(`hostname -I`)

function haproxy_install {
    echo -e $GREEN"关闭防火墙和selinux"$END
    systemctl disable --now firewalld
    setenforce 0
    echo -e $GREEN"开始编译lua"$END
    yum -y install gcc readline-devel > /dev/null
    [ -e ${lua_file}.tar.gz ] || ( wget http://www.lua.org/ftp/${lua_file}.tar.gz || { color "文件下载失败.." 1;exit; } )
    [ -e ${lua_file} ] && rm -rf /usr/local/src/${lua_file}
    [ -e /usr/local/src ] && tar xvf ${lua_file}.tar.gz -C /usr/local/src || color "解压失败.." 1
    cd /usr/local/src/${lua_file}
    make linux test && color "make成功" 0 || { color "make失败" 1;exit; }
    echo -e $GREEN"开始编译HAProxy"$END
    yum -y install gcc openssl-devel pcre-devel systemd-devel > /dev/null
    cd /root
    [ -e /root/${haproxy_file}.tar.gz ] || wget http://www.haproxy.org/download/2.4/src/${haproxy_file}.tar.gz -P /root/ -t 3
    [ -e /root/${haproxy_file}.tar.gz ] || read -p "文件下载失败,请自行下载后将文件放到/root目录下,然后按回车继续.."
    [ -e /root/${haproxy_file}.tar.gz ] || { color "找不到文件,请确认你已将正确的文件放到正确的路径.." 1;exit; }
    tar xvf /root/${haproxy_file}.tar.gz -C /usr/local/src || { color "解压缩文件失败.." 1;exit; }
    cd /usr/local/src/${haproxy_file}/ || { color "目录不存在" 1;exit; }
    echo -e $GREEN"开始执行程序编译安装"$END
    make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.3.5/src/ LUA_LIB=/usr/local/src/lua-5.3.5/src/ && color "make成功!" 0 || { color "make失败.." 1;exit; }
    make install PREFIX=/data/haproxy && color "make install成功!" 0 || { color "make install失败.." 1;exit; }
    echo -e $GREEN"创建软链接"$END
    [ -e /usr/sbin/haproxy ] && rm -rf /usr/sbin/haproxy
    ln -s /data/haproxy/sbin/haproxy /usr/sbin && color "软链接创建成功" 0 || color "软链接创建失败" 1
    echo -e $GREEN"复制man帮助"$END
    tar czf /usr/share/man/man1/haproxy.1.gz -P /data/haproxy/share/man/man1/haproxy.1
    echo 'OPTIONS=""' >> /etc/sysconfig/haproxy
    mkdir /etc/haproxy
    mkdir /var/lib/haproxy
    useradd -r -M -s /usr/nologin haproxy
    chown haproxy.haproxy /etc/sysconfig/haproxy
    chown haproxy.haproxy /var/lib/haproxy -R
    chown haproxy.haproxy /etc/haproxy -R
    chown haproxy.haproxy /data/haproxy -R
    cat > /usr/lib/systemd/system/haproxy.service <<\EOF
[Unit]
Description=HAProxy Load Balancer
After=network-online.target
Wants=network-online.target
 
[Service]
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid"
EnvironmentFile=/etc/sysconfig/haproxy
ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q $OPTIONS
ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE $OPTIONS                                     
ExecReload=/usr/sbin/haproxy -f $CONFIG -c -q $OPTIONS
ExecReload=/bin/kill -USR2 $MAINPID
SuccessExitStatus=143
KillMode=mixed
Type=notify
 
[Install]
WantedBy=multi-user.target
EOF
    echo -e $GREEN"创建初始配置文件,仅提供一个简单的上线配置文件"$END
    cat > /etc/haproxy/haproxy.cfg <<EOF
#---------------------------------------------------------------------
# Example configuration for a possible web application.  See the
# full configuration options online.
#
#   https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2 info

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    nbproc 2
    #stats socket /var/lib/haproxy/socket.sock mode 600 level admin
    stats socket /var/lib/haproxy/socket1.sock mode 600 level admin process 1
    stats socket /var/lib/haproxy/socket2.sock mode 600 level admin process 2
    spread-checks 2

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

    # utilize system-wide crypto-policies
    ssl-default-bind-ciphers PROFILE=SYSTEM
    ssl-default-server-ciphers PROFILE=SYSTEM

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000


listen stats
    mode http
    bind *:9000
    stats enable
    log global
    stats uri   /stats
    stats auth  admin:123
    stats auth  mxx:123
    stats refresh 3
    stats admin if TRUE

# listen www
#     bind ${local_ip[0]}:80
#     server rs1  192.168.32.212:80
#     server rs2  192.168.32.213:80

frontend www
    log global
    option httplog
    bind ${local_ip[0]}:80
    use_backend aaa
    mode http 
    capture request header Host len  256
    capture request header User-Agent len 512
    capture request header Referer len 15
    capture request header X-Forwarded-For len 15

backend aaa
    server rs1 192.168.32.212:80 check inter 3000 fall 2 rise 5
    server rs2 192.168.32.213:80 check inter 3000 fall 2 rise 5
EOF
    echo -e $GREEN"提前开启日志功能,本脚本为测试环境"$END
    sed -i.bak -r -e '/local7/a\local2.*                                                /var/log/haproxy.log' \
                  -e 's/#(module\(load=\"imudp\"\).*)/\1/' \
                  -e 's/#(input\(type=\"imudp\".*)/\1/' /etc/rsyslog.conf
    systemctl restart rsyslog
}

#exec
haproxy_install $1 $2

测试结果:

image.png

3、总结haproxy各调度算法的实现方式及其应用场景

static-RR:属于静态算法,不支持运行时修改权重以及后端服务器的慢启动,基于预先定义好的权重进行调度;

  • 通常使用在做了session共享的web集群

first:静态算法,权重的设置无效,只有当第一台服务器连接数达到上限,新的请求才会分配给下一台服务器;

  • 主要目的是使用最少的服务器提供业务支持,其他服务器可以执行停机维护等。

roundrobin:动态算法,支持慢启动和运行中通过socat调整权重;是默认的调度算法,按照权重的值进行调度;

  • 默认调度算法

leastconn:权重次优于连接数,根据当前连接最少的后端服务器,而非权重进行优先调度;

  • 长连接应用常用的调度算法,比如数据库

random:基于随机数作为一致性hash的key,支持weight的动态调整,weight大的有更大几率获取新请求。

source、URL、URL_PARAM、hdr等,根据hash-type来决定动态或静态的算法,分为取模和一致性hash两种:

  • 取模是静态算法,对source、URL、URL_PARAM、hdr、rdp-cookie等执行HASH运算后,与服务器的总权重进行取模运算,根据得到的值来选取一台服务器,但会因为服务器的增加减少,导致总权重出现变化,而出现调度结果的整体改变。
  • 一致性hash是动态算法,和nginx一样,构建hash环,服务器和请求计算的结果都会落在hash环上,然后通过顺时针查找,第一个匹配的服务器就是该请求发送的服务器。
  • uri常用于缓存服务器场景
  • url_param常用于实现会话保持
  • hdr基于客户端请求报文头部做下一步处理
  • rdp-cookie,基于windows主机

4、使用haproxy的ACL实现基于文件后缀名的动静分离

  • HAproxy上添加ACL,匹配文件后缀,指向后端不同的服务器;可以只添加动态的.php和/,静态的设置为default:
frontend www
    log global
    option httplog
    bind 192.168.32.197:80
    use_backend dynamic if { path_end -i .php / } 
    default_backend static
    mode http 
    capture request header Host len  256
    capture request header User-Agent len 512
    capture request header Referer len 15
    capture request header X-Forwarded-For len 15
    #http-request deny if { src 192.168.32.82 }
    #http-request deny if { hdr_sub(User-Agent) -i curl }


backend static
    server rs1 192.168.32.212:80 check inter 3000 fall 2 rise 5

backend dynamic
    server rs2 192.168.32.213:80 check inter 3000 fall 2 rise 5
  • 后端服务器dynamic那台需要配置fastcgi,动静两台服务器之间通过rsync同步wordpress数据,这部分是之前的作业内容;
#212服务器,配置add_header X-Via,方便判断资源从哪台服务器响应
[root@centos8mini 01]# cat /data/nginx/conf/conf.d/server1.conf 
server {
    listen 80;
    server_name www.mxx.com;
    access_log logs/www-access.log main;
    client_max_body_size 10m;
    location / {
        add_header X-Via $server_addr;
        root /data/server1/wordpress;
    }
}

#213服务器同样配置add_header X-Via
[root@centos8mini wp-content]# cat /data/nginx/conf/conf.d/server1.conf 
server {
    listen 80;
    server_name www.mxx.com;
    access_log logs/www-access.log main;
    client_max_body_size 10m;
    index index.php;
    location ~ \.php$|ping|status|/ {
        root /data/server1/wordpress;
        add_header X-Via $server_addr;
        fastcgi_index index.php;
        fastcgi_pass unix:/var/run/php.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

}

#213上的php-fpm配置文件
[root@centos8mini wp-content]# cat /data/php74/etc/php-fpm.d/www.conf | grep -E -v "^;|^$"
[www]
php_value[session.save_handler] = files
user = nginx
group = nginx
listen = /var/run/php.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.status_path = /status
ping.path = /ping
ping.response = pong
access.log = /data/php74/var/log/access.log
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
php_value[session.save_path] = /data/php74/log/session

  • 访问测试

静态CSS资源通过212获取

image.png

动态php通过213获取:

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、运用haproxy实现nginx服务负载均衡 测试环境: Nginx1: 172.16.100.151 por...
    卫清华阅读 358评论 0 0
  • 1、总结mysql常见的存储引擎以及特点。 1、MyISAM存储引擎MyISAM引擎特点:● 不支持事务● 表级锁...
    紫火红云阅读 172评论 0 0
  • 1、总结mysql常见的存储引擎以及特点。 存储引擎:负责把具体SQL语句的结果完成对磁盘上文件路径访问的转换,数...
    陌路残蝉阅读 177评论 1 0
  • 一、实现基于MYSQL验证的vsftpd虚拟用户访问 主机:两台,一台为FTP服务器,一台为MySQL服务器 1、...
    毅_阅读 292评论 0 0
  • 1、实现基于MYSQL验证的vsftpd虚拟用户访问 主机:两台,一台为FTP服务器,一台为MySQL服务器 (1...
    Gustav_man阅读 216评论 0 0