• 基于SLB实现滚动发布


    一、滚动发布介绍

    滚动发布(rolling update)是最常见的一种发布模式。比如我有10台机器,一台一台的进行部署。每台机器进行部署时,需要保证没有请求会派发到该机器,否则用户就会看到502的错误。所以需要有一个“下线”的操作,把当前机器从负载均衡中摘除,然后在部署完成之后,再把自己挂回到负载均衡中,这个过程称为“上线”。接下来会讲解,配合阿里云SLB如何做上线/下线操作。

    二、SLB配置

    image

    配置SLB监听端口:

    image

    创建虚拟服务器组:

    image

    配置健康检查(很重要,可以在后端服务器上配置好nginx后再来配置):

    image

    image

    image

    相关说明:图中的关键点:

    1. 健康检查路径,需要由实例上的web服务器提供,在本例中是/nginx-status.html
    2. 健康检查间隔,配置为2S。
    3. 健康阈值,配置为2,也就说2次健康检查失败,则认为该后端服务器不可用。同样的,两次连续的健康检查成功,就会认为该后端服务器可用。
    4. 按照这个配置,如果/nginx-status.html这个URL不可用超过4S,则SLB会把该服务器摘除。在这4S内,应用服务仍需要是可用的,因为还会有请求派发过来。可以通过如下方式达到这个效果。

    三、后端服务器配置

    3.1、安装应用服务

    此服务以tomcat为例,两台都需要安装

    image

    3.2、配置nginx

    yum安装nginx参考文档:https://www.cnblogs.com/songxingzhu/p/8568432.html

    配置nginx并启动:

    [root@test-mysqldb ~]# vim /etc/nginx/conf.d/test.conf 
    server {
        listen      80;
        server_name  localhost default;
        location ~ ^/(nginx-status) {
            root /usr/java/tomcat/status;
        }
        #location / {
        #    proxy_pass http://127.0.0.1:8080;
        #}
    }
    
    #创建相关文件及目录
    [root@test-mysqldb ~]# mkdir -p /usr/java/tomcat/status/
    [root@test-mysqldb ~]# touch /usr/java/tomcat/status/nginx-status.html
    
    #另一台可以做相同的配置

    相关说明:

    1)在机器上放置文件:/usr/java/tomcat/status/nginx-status.html 。当该文件被删除时候,/nginx-status.html这个请求会返回404,4S之后,该实例就会被从SLB中摘除。这个过程也就是“下线”的过程。

    2)与之对应,touch /usr/java/tomcat/status/nginx-status.html 这个操作就是上线的过程,也是4S之后生效。

    配置好SLB,访问SLB的ip地址是可以负载均衡的

    image

    3.3、服务启动脚本

    [root@jdk-76 status]# cat appctl.sh 
    #!/bin/bash
    
    PROG_NAME=$0
    ACTION=$1
    ONLINE_OFFLINE_WAIT_TIME=8  # 实例上下线的等待时间
    APP_START_TIMEOUT=50     # 等待应用启动的时间
    APP_PORT=9001          # 应用端口
    HEALTH_CHECK_URL=http://127.0.0.1:${APP_PORT}  # 应用健康检查URL
    HEALTH_CHECK_FILE_DIR=/usr/java/tomcat/status   # 脚本会在这个目录下生成nginx-status.html文件
    APP_HOME=/usr/java/tomcat/appboss-tomcat
    #JAR_NAME=app-0.1.0.jar # jar包的名字
    #APP_LOG=${APP_HOME}/logs/app.log # 应用的日志文件
    PID_FILE=${APP_HOME}/tomcat.pid   # 应用的pid会保存到这个文件中
    # 创建出相关目录
    #mkdir -p ${HEALTH_CHECK_FILE_DIR}  
    #mkdir -p ${APP_HOME}
    #mkdir -p ${APP_HOME}/logs
    
    usage() {
        echo "Usage: $PROG_NAME {start|stop|online|offline|restart}"
        exit 2
    }
    online() {
        # 挂回SLB
        touch -m $HEALTH_CHECK_FILE_DIR/nginx-status.html || exit 1
        echo "wait app online in ${ONLINE_OFFLINE_WAIT_TIME} seconds..."
        sleep ${ONLINE_OFFLINE_WAIT_TIME}
    }
    offline() {
        # 摘除SLB
        rm -f $HEALTH_CHECK_FILE_DIR/nginx-status.html || exit 1
        echo "wait app offline in ${ONLINE_OFFLINE_WAIT_TIME} seconds..."
        sleep ${ONLINE_OFFLINE_WAIT_TIME}
    }
    health_check() {
        exptime=0
        echo "checking ${HEALTH_CHECK_URL}"
        while true
        do
            status_code=`/usr/bin/curl -L -o /dev/null --connect-timeout 5 -s -w %{http_code}  ${HEALTH_CHECK_URL}`
            if [ x$status_code != x200 ];then
                sleep 1
                ((exptime++))
                echo -n -e "
    Wait app to pass health check: $exptime..."
            else
                break
            fi
            if [ $exptime -gt ${APP_START_TIMEOUT} ]; then
                echo
                echo 'app start failed'
                exit 1
            fi
        done
        echo "check ${HEALTH_CHECK_URL} success"
    }
    start_application() {
        echo "start tomcat"
        if [ -f "$PID_FILE" ] && kill -0 "$(cat ${PID_FILE})"; then
            echo "Application is running, exit"
            exit 0
        fi
        #rm -rf ${APP_HOME}/${JAR_NAME}
        #tar -zxvf /home/admin/package.tgz -C ${APP_HOME}
        #java -jar ${APP_HOME}/${JAR_NAME} > ${APP_LOG} 2>&1 &
        #echo $! > ${PID_FILE}
        ${APP_HOME}/bin/startup.sh
    }
    stop_application() {
        echo "stop tomcat"
        if [ -f "$PID_FILE" ]; then
            kill -9 `cat $PID_FILE`
            rm $PID_FILE
        else
            echo "pid file $PID_FILE does not exist, do noting"
        fi
    }
    start() {
        start_application
        health_check
        online
    }
    stop() {
        offline
        stop_application
    }
    case "$ACTION" in
        start)
            start
        ;;
        stop)
            stop
        ;;
        online)
            online
        ;;
        offline)
            offline
        ;;
        restart)
            stop
            start
        ;;
        *)
            usage
        ;;
    esac

    参考文档:

    https://helpcdn.aliyun.com/document_detail/57399.html

  • 相关阅读:
    实例代码讲解_Person
    推荐一个小工具:LINQ to JavaScript (jslinq)
    AJAX跨域问题解决一:使用web代理
    JQuery常用方法总结(2)
    对IEnumerable<T>,IDictionary<Tkey,TValue>,ICollection<T>,IList<T>的总结
    C#补零
    JQuery常用方法总结(1)
    单一模式(Singleton)的学习
    .net core 和 WPF 开发升讯威在线客服系统:调用百度翻译接口实现实时自动翻译
    在“宝塔”中部署升讯威在线客服系统教程来了,只需10分钟,确实方便!
  • 原文地址:https://www.cnblogs.com/hujinzhong/p/12066156.html
Copyright © 2020-2023  润新知