当前位置: 首页 > article >正文

golang linux快速启动 一键重启脚本

需求背景

  • 我使用本地编译,复制到 linux 上运行的方式部署 go 项目
  • 单体部署,如果是集群部署可以依赖 nginx 做无感切换

痛点

  1. 正在运行的 go 项目文件不能被覆盖,我需要先使用脚本停止项目,然后覆盖,然后再用脚本运行起来。 这会造成显著的服务中断。
  2. 单体运行多个 go项目时,需要明确区分项目名称,不然终止脚本可能会误杀

原脚本

启动

nohup /全路径/项目名称 >> nohup.out &
tail -f /全路径/nohup.out

终止

kill -15 `ps -ef | grep 项目名称 | grep -v grep | awk '{print $2}'`

新思路

  • 每次还是编译成相同名称的文件。
  • 脚本将新的可执行文件复制为一个新的名称,此名称确保和原来名称不重复。
  • 如果需要更新项目包,脚本先复制新项目,然后终止原项目,然后运行新项目,可以最大程度缩小服务中断时间。
  • 需要有个文件存储上一次运行的项目被改成了什么名字,以方便需要终止他的时候能找到他。

新脚本

代码如下

#!/bin/bash
#项目路径
PROJECT_PATH="/opt/my_project/"
# 配置文件名称
CONFIG_FILE="shell_info.ini"
# 目标文件路径
TARGET_FILE="my_golang_app"
# 日志文件路径
LOG_FILE="nohup.log"

# 生成随机字符串
generate_random_string() {
    cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1
}

# 根据日期和随机数生成新文件名
generate_new_filename() {
    local date_str=$(date +"%Y%m%d")
    local random_str=$(generate_random_string)
    echo "${date_str}_${random_str}"
}

# 启动服务
start_service() {
    local new_filename=$(generate_new_filename)
    cp $PROJECT_PATH$TARGET_FILE "$PROJECT_PATH$new_filename"
    echo "Starting service with filename: $PROJECT_PATH$new_filename"
    nohup "$PROJECT_PATH$new_filename" >> $PROJECT_PATH$LOG_FILE 2>&1 &
    echo "current=$PROJECT_PATH$new_filename" > $PROJECT_PATH$CONFIG_FILE
    tail -f $PROJECT_PATH$LOG_FILE
}

# 重新加载服务
reload_service() {
    local current=$(grep '^current=' $PROJECT_PATH$CONFIG_FILE | cut -d'=' -f2)
    if [ -z "$current" ]; then
        echo "No current service to reload."
        return
    fi
    local new_filename=$(generate_new_filename)
    cp $PROJECT_PATH$TARGET_FILE "$PROJECT_PATH$new_filename"
    echo "Reloading service from $current to $PROJECT_PATH$new_filename"
    local pid=$(ps -ef | grep "$current" | grep -v grep | awk '{print $2}')
    if [ -n "$pid" ]; then
        kill -9 $pid
        echo "Service $current stopped."
    fi
    nohup "$PROJECT_PATH$new_filename" >> $PROJECT_PATH$LOG_FILE 2>&1 &
    rm "$current"
    echo "current=$PROJECT_PATH$new_filename" > $PROJECT_PATH$CONFIG_FILE
    tail -f $PROJECT_PATH$LOG_FILE
}

# 停止服务
stop_service() {
    local current=$(grep '^current=' $PROJECT_PATH$CONFIG_FILE | cut -d'=' -f2)
    if [ -z "$current" ]; then
        echo "No current service to stop."
        return
    fi
    local pid=$(ps -ef | grep "$current" | grep -v grep | awk '{print $2}')
    if [ -n "$pid" ]; then
        kill -9 $pid
        echo "Service $current stopped."
    fi
}

case $1 in
    start)
        start_service
        ;;
    reload)
        reload_service
        ;;
    stop)
        stop_service
        ;;
    *)
        echo "Usage: $0 {start|reload|stop}"
        exit 1
        ;;
esac

exit 0

使用方法:

#运行项目
sh runner.sh start
#使用新包覆盖原运行项目
sh runner.sh reload
#终止运行
sh runner.sh stop

使用说明:

如果你第一次查阅相关内容,就看到了我的文章,那么你在复制 linux 可执行文件后,可能需要修改其权限。建议将脚本和 linux 可执行文件放在同一文件夹下。

#赋予当前路径下所有文件执行权限
chmod 777 ./*

修改脚本头部配置,其中项目路径填你存放脚本和 linux 可执行文件的路径,配置文件不用管,不要手欠误删了就没事。删了也没事,只是你得自己终止进程了。

目标文件路径填 linux 可执行文件的名称即可。.

脚本会复制原可执行文件,生成的新文件名称是:原名称+时间日期+乱码

在使用 reload 命令时,会自动清除上次复制出来的文件。


http://www.kler.cn/a/370684.html

相关文章:

  • 【SPIE出版|EI、Scopus双检索】2025年绿色能源与环境系统国际学术会议(GEES 2025)
  • 【Unity3D】利用Hinge Joint 2D组件制作绳索效果
  • 蓝桥杯刷题第二天——背包问题
  • 19. C语言 共用体(Union)详解
  • 【ArcGIS微课1000例】0140:总览(鹰眼)、放大镜、查看器的用法
  • HBase实训:纸币冠字号查询任务
  • 跟着小土堆学习pytorch(二)——TensorBoard和Transform
  • C语言——数组、指针、函数
  • 外媒软文宣发:海外发稿-英国金融时报FT-大舍传媒
  • 总结性标题:高效导入文本数据,探索 MySQL 与 Java 的最佳实践
  • 【矩阵理论常见符号说明】
  • echarts自适应浏览器缩放代码
  • Redis与MySQL双写一致性的缓存模式
  • LeetCode 热题 100 之链表2
  • 三款计算服务器配置→如何选择科学计算服务器?
  • C++第八讲:STL--stack和queue的使用及模拟实现
  • 基于现代 C++17 的模块化视频质量诊断处理流程设计
  • Python入门:学会Python装饰器让你的代码如虎添翼!(Python如何不改动原有函数代码添加一些额外的功能)
  • 嵌入式linux系统中实现MPU6050的控制方法
  • Python OpenCV图像复原
  • HCIP 路由控制
  • GRE VPN(H3C)
  • node.js学习Day2
  • asp.net WebForm GridView高级应用
  • 精选免费剪辑软件,为你的视频创作添彩
  • 排序(一)插入排序,希尔排序,选择排序,堆排序,冒泡排序