目标:将您的 Go 博客应用部署到生产服务器,并配置 systemd 和 endless,以实现服务的稳定运行、开机自启、崩溃自愈,以及最重要的——不中断服务的平滑更新(无缝重启)

技术栈

  • 应用框架: Go + Gin
  • 无缝重启库endless
  • 进程管理器systemd (现代 Linux 发行版标配)
  • 部署路径/home/yys/blog
  • 运行用户yys

第一部分:服务器环境准备

在开始部署之前,请确保您的服务器满足以下条件。

1. 安装 Go 环境

如果您的服务器上还没有安装 Go,请先安装。推荐安装最新稳定版。

2. 安装 Git (用于拉取代码)

3. 准备项目目录

创建您的项目将要存放的目录。

# 创建目录,-p 确保父目录不存在时也会被创建
mkdir -p /home/yys/blog

第二部分:部署与首次启动

现在,我们将把您的代码部署到服务器并进行首次编译和启动。

1. 获取源代码

登录到服务器,进入项目目录,然后使用 git 克隆您的项目。

cd /home/yys/blog
# 将 your_repo_url 替换成您真实的 Git 仓库地址
git clone your_repo_url .

注意:命令最后的 . 表示克隆到当前目录。

2. 安装 Go 依赖

进入项目目录后,endless 库也需要被下载。

# Go Modules 会自动处理 go.mod 文件中定义的依赖
go mod tidy

或者,如果您之前没有 go get 过,可以执行:

go get github.com/fvbock/endless

3. 编译您的应用

我们将源代码编译成一个单一的可执行二进制文件。

# -o blog_server 指定输出文件名为 blog_server
go build -o blog_server .

编译成功后,在 /home/yys/blog 目录下会有一个名为 blog_server 的文件。

授予执行权限 (重要)

chmod +x blog_server

4. 创建 Systemd Service 文件

这是整个部署流程的核心。

  1. 使用 nano 或 vim 创建 service 文件:

    sudo nano /etc/systemd/system/blog.service
  2. 粘贴以下经过优化的配置内容:
    这份配置包含了我们讨论过的所有最佳实践,如用户、路径、重启策略等。

    [Unit]
    Description=My Go Blog Application Service
    After=network.target mysql.service
    
    [Service]
    Type=simple
    
    User=root
    Group=root
    
    WorkingDirectory=/home/yys/blog
    ExecStart=/home/yys/blog/blog_server
    
    ExecReload=/bin/kill -HUP $MAINPID
    
    # --- 关键修改:增强重启策略 ---
    Restart=always
    # 将 on-failure 改为 always。
    # 这会告诉 systemd:除了我手动执行 stop 命令,其他任何情况下的进程退出,都请你给我重启它。
    # 这就完美覆盖了 reload 后新进程启动失败而退出的场景。
    
    RestartSec=5s
    # 重启间隔保持不变,5秒是一个很合理的值。
    
    StandardOutput=journal
    StandardError=journal
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
  3. 保存并退出编辑器

5. 启动并管理您的服务

  1. 重载 systemd 配置使其识别您的新服务文件:
    sudo systemctl daemon-reload
  2. 设置开机自启
    sudo systemctl enable blog.service
  3. 立即启动服务
    sudo systemctl start blog.service
  4. 检查服务状态
    sudo systemctl status blog.service
    仔细观察输出,确保状态是 Active: active (running)。如果有错误,日志中会有提示。

至此,您的博客已经作为后台服务在稳定运行了!


第三部分:不中断服务的平滑更新 (核心操作)

当您未来更新了网站代码后,您不再需要停止服务。只需遵循以下简单的“三步曲”。

步骤 1: 在服务器上更新代码

登录服务器,进入项目目录,拉取最新的代码。

cd /home/yys/blog
git pull

步骤 2: 重新编译

用新代码生成新的 blog_server 二进制文件,它会覆盖掉旧版本。

go build -o blog_server .

步骤 3: 执行无缝重启

这是最神奇的一步。执行 reload 命令,systemd 会向旧进程发送 HUP 信号,endless 会处理剩下的一切,完成新旧版本的平滑交接。

sudo systemctl reload blog.service

您的网站更新就完成了,整个过程对用户零中断!


第四部分:日常维护

查看日志

当您需要排查问题时,journalctl是您的好朋友。

  • 查看服务的实时日志 (类似 tail -f):
    sudo journalctl -u blog.service -f
  • 查看最近的 100 条日志:
    sudo journalctl -u blog.service -n 100 --no-pager

其他常用命令

  • 停止服务sudo systemctl stop blog.service
  • 硬重启服务 (会中断)sudo systemctl restart blog.service

 

 


第五部分:手动更新与部署流程 (通过 Git 同步)

目标:在您本地完成代码修改并推送到 Git 仓库后,通过一系列标准的手动命令,在服务器上安全、无缝地完成应用的更新和部署。

工作流程:

  1. 本地: 开发者 add -> commit -> push 代码。
  2. 服务器: 管理员登录后,依次执行 git pull -> go build -> systemctl reload

场景:您在本地电脑上完成了新的功能开发或 bug 修复

步骤 1: 在本地提交并推送代码

在您的本地开发环境(例如您的 WSL 或 Windows 电脑)的项目根目录下,执行标准的 Git 操作,将您的更改推送到远程仓库(如 GitLab/GitHub)。

  1. 查看更改状态:
    git status
  2. 添加所有更改到暂存区:
    git add .
  3. 提交更改并附上有意义的说明:
    git commit -m "feat: 增加文章详情页的xxx功能"
  4. 推送到远程主分支:
    git push origin main

完成这一步后,您的最新代码就已经安全地保存在远程 Git 仓库中了。


步骤 2: 在服务器上拉取最新代码

现在,切换到您的服务器终端,准备更新正在运行的应用。

  1. 通过 SSH 登录到您的服务器

  2. 进入您的项目部署目录:

    cd /home/yys/blog
  3. 使用 git pull 拉取最新代码:
    这条命令会从远程仓库获取您刚刚推送的最新代码,并与服务器上的本地代码进行合并。

    git pull

    您应该能看到类似 Updating ... 的输出,表明代码已更新。


步骤 3: 在服务器上重新编译应用

现在源代码已经更新,我们需要用它来生成一个新的、包含了新功能的可执行文件。

  1. 确保您仍在项目根目录 (/home/yys/blog)。

  2. 执行编译命令:
    这会生成一个名为 blog_server 的新二进制文件,并覆盖掉旧的那个。

    go build -o blog_server .
  3. (可选但推荐) 检查文件是否更新:
    用 ls -l 命令查看 blog_server 的修改时间,确保它就是您刚刚编译的时间。

    ls -l blog_server

步骤 4: 在服务器上执行无缝重启

新的二进制文件已经准备就绪,现在是时候让正在运行的服务加载它了。

  1. 执行 systemctl reload 命令:
    这个命令会向正在运行的旧进程发送 HUP 信号,触发 endless 库的无缝重启机制。

    sudo systemctl reload blog.service
  2. 验证更新是否成功:
    reload 命令会立即返回,但后台的新旧进程交接需要几秒钟。您可以等待 2-3 秒后,通过以下命令来确认服务状态:

    sudo systemctl status blog.service
    • 观察 Active 状态: 应该显示 active (running)
    • 观察 Main PID: 您会发现 PID 已经变成了一个新的数字,这证明新进程已经成功启动并接管了服务。
  3. 最终测试:
    打开浏览器,访问您的博客网站。刷新页面,您应该就能看到您之前修改的新功能或修复的内容了。

这个“拉取 -> 编译 -> 重载”的三步曲是手动部署中非常标准和专业的实践。