Golang 项目部署实战

2023-11-17

一直认为不懂部署的开发工程师不是好的开发工程师,以下以一些实例讲解自己在项目中的 Golang 后端部署的情况。

一般部署脚本应该具有构建、启动、停止、回滚已经查看记录日志等功能,以下分别将这些功能以单个脚本的形式给出,当然也可以写成Makefile 的形式。

单个部署脚本的形式,在一个目录下建立如下文件:

bin # 目录,用于存放每次 build 之后存放的二进制文件
app.log # 用来记录的日志文件
log.sh # 实时查看日志
build.sh # 构建
run.sh # 启动某一次编译版本
start.sh # 启动最新版本,并且备份之前前一次运行的版本
shutdown.sh # 停止
rollback.sh # 回滚到上一版本


本例中的 GOPATH=”/go”

log.sh 具体内容:

tail -f -n 200 app.log # 实时查看最后 200 条日志的情况

build.sh 具体内容:

#!/bin/bash

# 项目地址,/go 在 GOPATH 里面
baseProjectDir="/go/src/monitor"

# targetDir 编译后的二进制文件目录
targetDir="bin"

# branch 编译的分支
branch="master"

pwd=`pwd`
# targetFile 编译后的输出文件名称
targetFile=`basename $pwd`

# buildPkg 编译的包名,main.go 所在的包
buildPkg="monitor"

# buildResult 编译结果
buildResult=""

if [ -n "$1" ]; then
  branch="$1"
  echo "Switch branch to ${branch}"
else
  echo "Building Branch: ${branch}"
fi

gitPull() {
  pushd .

  cd "$baseProjectDir"
  git checkout "$branch"
  git pull

  popd
}

goBuild() {
    buildResult=`go build -o "${targetDir}/${targetFile}" "$buildPkg" 2>&1`

    if [ -z "$buildResult" ]; then
      buildResult="success"
    fi
}

gitPull
goBuild

if [ "$buildResult" = "success" ]; then
  cp ${targetDir}/${targetFile} ${targetFile}-new
  chmod +x ${targetFile}-new
else
  echo "build error $buildResult"
  exit
fi

echo "All Complete"


run.sh 具体内容:

#!/bin/bash

# 以后台方式启动程序,并且将日志记录到 app.log
nohup ./$1 >> app.log &


start.sh 具体内容:

#!/bin/bash

pwd=`pwd`
target=`basename $pwd`
# kill
pid=`ps -C ${target} -o pid=`
if [ -n "$pid" ]; then
  echo "Stopping old version, PID: ${pid}"
  if [ "$1" = "-f" ]; then
    # force shutdown
    echo "Force shutdown..."
    kill -9 $(ps -C ${target} -o pid=)
  else
    kill -s 2 $(ps -C ${target} -o pid=)
  fi
  # wait for program to stop
  pid=`ps -C ${target} -o pid=`
  while [ -n "$pid" ]; do
    sleep 1
  done
fi

# upgrade
if [ -f "${target}-new" ]; then
  echo "Upgrading..."
  if [ -f "${target}-backup" ]; then
    backupdt=`date +%Y%m%d-%H`
    mv "${target}-backup" "${target}-backup-${backupdt}"
  fi

  mv ${target} ${target}-backup
  mv ${target}-new ${target}

  echo "Upgrade Complete"
fi

# run
echo "Starting..."
./run.sh ${target}
echo "Done"


shutdown.sh 具体内容:

#!/bin/bash

pwd=`pwd`
target=`basename $pwd`

# kill
pid=`ps -C ${target} -o pid=`
if [ -n "$pid" ]; then

  echo "Stopping old version, PID: ${pid}"
  if [ "$1" = "-f" ]; then
    # force shutdown
    echo "Force shutdown..."
    kill -9 $(ps -C ${target} -o pid=)
  else
    kill -s 2 $(ps -C ${target} -o pid=)
  fi

  # wait for program to stop
  pid=`ps -C ${target} -o pid=`
  while [ -n "$pid" ]; do
    sleep 1
  done

fi

echo "Done"


需要注意的是 kill -s 2 发送的是 Interrupt 中断信号,在项目中要有监听该信号的处理程序,eg:

package main

import (
    "log"
    "os"
    "os/signal"

    "github.com/robfig/cron"
)

func main() {
    i := 0
    c := cron.New()
    spec := "*/3 * * * * ?"
    c.AddFunc(spec, func() {
        i++
        log.Println("cron running:", i)
    })
    c.Start()

    go signalListen()

    select {}
}

func signalListen() {
    c := make(chan os.Signal)
    // 监听 os.Interrupt 并且退出程序
    signal.Notify(c, os.Interrupt, os.Kill)
    for {
        <-c
        os.Exit(0)
    }
}


rollback.sh 具体内容:

#!/bin/bash

pwd=`pwd`
target=`basename $pwd`

# Kill running program
pid=`ps -C ${target} -o pid=`
if [ -n "$pid" ]; then

  echo "Stopping old version, PID: ${pid}"
  if [ "$1" = "-f" ]; then
    # force shutdown
    echo "Force shutdown..."
    kill $(ps -C ${target} -o pid=)
  else
    kill -s 2 $(ps -C ${target} -o pid=)
  fi

  # wait for program to stop
  pid=`ps -C ${target} -o pid=`
  while [ -n "$pid" ]; do
    sleep 1
  done
fi

# Rollback
if [ -f "${target}-backup" ]; then
  echo "Rolling back..."
  if [ -f "${target}" ]; then
    rm "${target}"
  fi
  mv ${target}-backup ${target}
  echo "Rollback Complete"
fi

# run
echo "Starting..."
./run.sh ${target}
echo "Done"


--------------------- 
作者:极客Geek 
来源:CSDN 
原文:https://blog.csdn.net/netdxy/article/details/79431415 
版权声明:本文为博主原创文章,转载请附上博文链接!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Golang 项目部署实战 的相关文章

  • 使用Docker registry镜像创建私有仓库

    2015 01 25 wcdj 摘要 安装Docker后 可以通过官方提供的registry镜像来简单搭建一套本地私有仓库环境 本文记录简单的搭建过程 1 使用registry启动私有仓库的容器 docker run d p 5000 50
  • Go开发命令行程序指南

    近期在Twitter上看到一个名为 Command Line Interface Guidelines 的站点 1 这个站点汇聚了帮助大家编写出更好命令行程序的哲学与指南 这份指南基于传统的Unix编程原则 2 又结合现代的情况进行了 与时
  • Go项目部署及所遇问题

    小聊 本次小白给大家带来Golang项目部署操作以及个人所遇问题和解决它们的方法 依然是一边实操演示一边写文稿 如遇相似问题却存有疑惑可留言 开发环境是Window 部署环境是Linux 开发工具为GoLand 部署服务器为阿里云 1 打包
  • golang: Logrus实现日志打印

    Github https github com sirupsen logrus golang标准库的日志框架非常简单 仅仅提供了print panic和fatal三个函数 对于更精细的日志级别 日志文件分割以及日志分发等方面并没有提供支持
  • Golang-使用 goroutine 运行闭包的“坑”

    介绍 在 Go 语言中 函数支持匿名函数 闭包就是一种特殊的匿名函数 它可以用于访问函数体外部的变量 需要注意的是 在 for range 中 使用 goroutine 执行闭包时 经常会掉 坑 因为匿名函数可以访问函数体外部的变量 而 f
  • golang sleep

    golang的休眠可以使用time包中的sleep 函数原型为 func Sleep d Duration 其中的Duration定义为 type Duration int64 Duration的单位为 nanosecond 为了便于使用
  • 权重实现随机抽奖

    一般抽奖是怎么实现的 在实习期间学会了一种通用的写法 在这里记录一下 最近在学Golang语法基础 这里就用Golang来写 package main import fmt time math rand func main r rand N
  • golang:环境变量GOPROXY和GO111MODULE设置

    我们安装完golang后 我们在windows的cmd命令下就可以直接查看和使用go命令和环境变量了 同样的在linux下可以在控制台使用 如下图所示 C Users lijie1 gt go env set GO111MODULE set
  • Golang连接Jenkins获取Job Build状态及相关信息

    文章目录 1 连接Jenkins 2 controller 3 module 4 router 5 效果展示 第三方包 gojenkins 方法文档 gojenkins docs 实现起来很简单 利用第三方库 连接jenkins 调用相关方
  • goland环境配置

    goland modules环境配置 下载和安装goland 环境配置 配置环境变量GOPATH 配置go modules GOPROXY代理的系统变量 工程目录中新建三个工作目录 goland中启用go modules 新建一个go程序
  • 基于Go语言实现简易Web应用

    目录 前言 Go语言特点 写在使用Go语言实现Web应用前面 创建Web服务器 声明一个结构体操作 加入中间件的使用 使用静态文件服务器 最后 前言 在编程语言中 近几年问世的几个新语言都是非常不错的 比如Go Python Rust等等
  • 【go语言开发】loglus日志框架的使用

    本文将简单介绍loglus框架的基本使用 并给出demo 文章目录 前言 Loglus常见用法 自定义日志级别 使用字段钩子 输出到多个位置 使用钩子实现自定义日志处理 demo
  • go-zero开发入门之网关往rpc服务传递数据2

    go zero 的网关服务实际是个 go zero 的 API 服务 也就是一个 http 服务 或者说 rest 服务 http 转 grpc 使用了开源的 grpcurl 库 当网关需要往 rpc 服务传递额外的数据 比如鉴权数据的时候
  • go-zero开发入门之gateway深入研究1

    创建一个 gateway 示例 main go package main import flag fmt gateway middleware github com zeromicro go zero core conf github co
  • go-zero 的 etcd 配置

    实现代码在 core discov config go 文件中 type EtcdConf struct Hosts string Key string ID int64 json optional User string json opt
  • GoLong的学习之路,进阶,微服务之序列化协议,Protocol Buffers V3

    这章是接上一章 使用 RPC包 序列化中没有详细去讲 因为这一块需要看的和学习的地方很多 并且这一块是RPC中可以说是最重要的一块 也是性能的重要影响因子 今天这篇主要会讲其使用方式 文章目录 Protocol Buffers V3 背景以
  • go语言实现文件夹上传前后端代码案例

    go语言实现文件夹上传前后端代码案例 前端用于上传的测试界面 如果上传的文件夹有子文件要遍历子文件夹创建出子文件夹再进行拷贝 需要获取文件名和对应的路径 将文件的相对路径和文件对象添加到FormData中 这几行代码很关键 for let
  • golang 生成一年的周数

    GetWeekTimeCycleForGBT74082005 获取星期周期 中华人民共和国国家标准 GB T 7408 2005 参数 year 年份 GB T 7408 2005 func GetWeekTimeCycleForGBT74
  • go cannot find package “github.com/gorilla/websocket“解读

    Go无法找到包 github com gorilla websocket 的解决方案 在Go开发过程中 我们经常会依赖第三方库来简化开发工作 而使用 go get 命令安装这些库时 有时候我们可能会遇到类似于以下错误的情况 plaintex
  • 【go语言】AST抽象语法树详解&实践之扫描代码生成错误码文档

    背景 为了能识别出代码中抛出错误码的地址和具体的错误码值 再根据错误码文件获取到错误码的具体值和注释 方便后续的排错 这里使用AST进行语法分析获取到代码中的目标对象 一 编译过程 在开始解析代码之前先补充了解一下编译过程 编译过程是将高级

随机推荐

  • 用Python爬虫接私活,赚了32K!

    网络爬虫 很多人觉得这是技术控的专属 实际上爬虫是人人都能掌握的技能 爬虫到底能干什么 基本你所能看到的全部信息 它都能抓取 例如 收集并批量下载某音乐软件付费歌曲 某视频软件的付费视频 采集北京所有小区的信息及北京所有小区的所有历史成交记
  • centos7 lvm 创建脚本

    centos7 lvm 创建脚本 Centos7 lvm创建 适用场景只有一块新加的磁盘 且未分区 挂载目录为riva 可自定义 date 2023 bin bash 注意此处变量 Disk dev sd 不同的平台会有差异 比如腾讯云为
  • Attempted to load tokenizers/punkt/PY3/english.pickle

    分明已经把punkt放到服务器相应文件下 但是还是显示没成功 错误原因是解压得时候文件目录有两个punkt
  • VUE之自定义插件

    index js文件 import promptBox from prompt box vue 定义插件对象 const PromptBox vue的install方法 用于定义vue插件 PromptBox install functio
  • rocketMq介绍和安装

    rocketMq介绍和安装 Mq介绍 MQ MessageQueue 消息队列 队列 是一种FIFO 先进先出的数据结构 消息由生产者发送到MQ进行排队 然后按原来的顺序交由消息的消费者进行处理 QQ和微信就是典型的MQ MQ的作用 主要有
  • Vue项目中如何引入外部js文件,并使用其中定义的函数

    Vue项目中如何引入外部js文件 并使用其中定义的函数 一些常用的功能函数 我们希望将其封装起来放入一个外部JS文件中 好方便我们在需要的时候使用 vue可以使用import指令引入外部文件 但是作为新手 在使用过程中难免会导致很多错误 这
  • maven导入依赖失败问题——最系统、最彻底的解决方案

    目录 一 idea配置maven 1 配置maven版本及本地仓库 二 清理Local Repository的 lastUpdated文件 三 在idea中重新导入依赖 一 idea配置maven 1 配置maven版本及本地仓库 关于项目
  • 排序算法之堆排序(Heap Sort)——C语言实现

    堆排序 Heapsort 是指利用堆积树 堆 这种数据结构所设计的一种排序算法 它是选择排序的一种 算法分析 在学习堆排序之前我们要先了解堆这种数据结构 堆的定义如下 n个元素的序列 k1 k2 kn 当且满足以下关系时 称之为堆 若将此序
  • 短视频平台-小说推文(知乎)推广任务详情

    知乎会员 知乎日结内测中 可能暂只对部分优质会员开放 2023 03 29通知 知乎拉新项目 由于内部测试转化较低 暂时下线 原有关键词出单不受影响 1 关键词 1 1 选择会员文 在知乎 首页 或者 会员 里面选取 需要选取文章链接 点进
  • 二.centos7和主机实现xftp传文件,包含解决一些主机虚拟机互联的问题

    首先打开安装好的centos7 一 需要获取的信息 虚拟机 ifconfig 信息 主要是ensxx的信息 主机 ipconfig 信息 主要是vm8的信息 虚拟机点 编辑 虚拟网络编辑器 界面 查看虚拟机右下是否连接 点虚拟机右上角 看有
  • Nacos启动: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorExceptionTable nacos_config.config_inf

    把nacos 1 1 4 server下载到本地之后 然后直接在bin目录下启动startup cmd报错 本地Mysql版本 5 6 44 nacos server版本 1 1 4 我找了很多解决办法 更多的说的是nacos自带的mysq
  • vue 实时往数组里追加数据

    使用Vue set 以下来解读一下 Vue set this tableDatas this selected obj 1 this tableDatas是我们声明好的数组 以下是自定义数据 tableDatas id 1 caseName
  • Python之数据分析(三维立体图像、极坐标系、半对数坐标)

    文章目录 写在前面 一 三维立体图像 1 三维线框 2 三维曲面 3 三维散点 二 极坐标系 三 半对数坐标 写在前面 import numpy as np import matplotlib pylab as mp 因此文章中的np就代表
  • Linux学习大纲

  • 以太网设计FAQ:以太网MAC和PHY

    问 如何实现单片 以太网 微控制器 答 诀窍是将微控制器 以太网媒体接入控制器 MAC 和物理接口收发器 PHY 整合进同一芯片 这样能去掉许多外接元器件 这种方案可使MAC和PHY实现很好的匹配 同时还可减小引脚数 缩小芯片面积 单片以太
  • MySQL第一讲 一遍让你彻底掌握MVCC多版本并发控制机制原理

    Mysql在可重复读隔离级别下 同样的sql查询语句在一个事务里多次执行查询结果相同 就算其它事务对数据有修改也不会影响当前事务sql语句的查询结果 这个隔离性就是靠MVCC Multi Version Concurrency Contro
  • Python爬虫入门8:BeautifulSoup获取html标签相关属性

    前往老猿Python博客 https blog csdn net LaoYuanPython 一 引言 在上节 https blog csdn net LaoYuanPython article details 113091721 Pyth
  • 【神经网络搜索】DARTS: Differentiable Architecture Search

    GiantPandaCV DARTS将离散的搜索空间松弛 从而可以用梯度的方式进行优化 从而求解神经网络搜索问题 本文首发于GiantPandaCV 未经允许 不得转载 1 简介 此论文之前的NAS大部分都是使用强化学习或者进化算法等在离散
  • io回顾

    package test import java io 读取一个文件 并打印在控制台上 class FileReaderTest public static void main String args throws IOException
  • Golang 项目部署实战

    一直认为不懂部署的开发工程师不是好的开发工程师 以下以一些实例讲解自己在项目中的 Golang 后端部署的情况 一般部署脚本应该具有构建 启动 停止 回滚已经查看记录日志等功能 以下分别将这些功能以单个脚本的形式给出 当然也可以写成Make