第十八周作业

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

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