Huginn 2026.10.14 进阶实战与运维

Huginn 2026.10.14 运维实战:mysqldump 备份与删库恢复实测、Agent 调度排查与失败任务治理、日志体系(journalctl/production.log/Agent 日志)、源码与镜像两种升级路径。

HuginnHuginnsystemdLinux2026/10/17

Huginn 2026.10.14 进阶实战与运维

目标:覆盖 Huginn 日常运维的备份恢复、Agent 调度排查、日志体系与版本升级四大主题,源码部署与镜像部署两种形态的命令分别给出。已在 Ubuntu 22.04 实测通过。

本文覆盖 Huginn 日常运维的四大主题:备份恢复、调度排查、日志体系与版本升级。源码部署(systemd 托管)与镜像部署(Compose)两种形态的命令分别给出,全部操作在 v2026.10.14 实例上实测验证。

一、环境信息

  • 实例版本:Huginn v2026.10.14,全部操作在该版本实例上实测验证;
  • 部署形态:源码部署(systemd 托管 Web 与 Worker)与镜像部署(Docker Compose)两种形态分别实测;
  • 操作系统:沿用前置部署文档的实测环境(Ubuntu 22.04,见《Huginn 2026.10.14 Ubuntu 22.04 安装指南》/《Huginn 2026.10.14 Docker Compose 部署指南》);
  • 源码部署:源码目录 /home/huginn/huginn,数据库 huginn_production(MySQL,127.0.0.1),Web 端口 3000,应用日志 /home/huginn/huginn/log/production.log;
  • 镜像部署:项目目录 /opt/huginn-prod 与 /opt/huginn,镜像 ghcr.io/huginn/huginn-single-process:latest,数据库 huginn(MySQL 容器),数据卷 ./mysql-data。

二、备份与恢复

2.1 备份策略

Huginn 的全部状态(用户、Agent 配置、事件、任务队列)都在数据库里,备份 = 备份数据库。源码部署库名 huginn_production,镜像部署按配置一般是 huginn(或自定义 HUGINN_DATABASE_NAME)。文件系统层面没有需要额外备份的状态(.env 与编排文件建议纳入配置管理)。

2.2 源码部署:mysqldump 备份

root@huginn-server:~# mysqldump -uhuginn -pq1w2e3r4 -h127.0.0.1 huginn_production 2>/dev/null > /tmp/huginn-prod-backup.sql
root@huginn-server:~# ls -lh /tmp/huginn-prod-backup.sql
-rw-r--r-- 1 root root 22K Oct 17 09:27 /tmp/huginn-prod-backup.sql
root@huginn-server:~# grep -c "INSERT INTO" /tmp/huginn-prod-backup.sql
7

生产建议加 --single-transaction(InnoDB 一致性快照不锁表)并 cron 定时:

root@huginn-server:~# crontab -e

加入(每天 02:30 备份到本地并保留文件名日期):

30 2 * * * mysqldump --single-transaction -uhuginn -pq1w2e3r4 -h127.0.0.1 huginn_production 2>/dev/null > /var/backups/huginn-$(date +\%F).sql

(crontab 里 % 必须转义为 \%,这是 cron 的解析规则,不是 mysqld 的。)

2.3 源码部署:恢复实测

实测流程:备份 → 删库 → 重建库 → 导入 → 验证,四步完整走通:

root@huginn-server:~# mysql -uhuginn -pq1w2e3r4 -h127.0.0.1 -e "DROP DATABASE huginn_production;"
root@huginn-server:~# mysql -uhuginn -pq1w2e3r4 -h127.0.0.1 -e "CREATE DATABASE huginn_production CHARACTER SET utf8mb4;"
root@huginn-server:~# mysql -uhuginn -pq1w2e3r4 -h127.0.0.1 huginn_production < /tmp/huginn-prod-backup.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
root@huginn-server:~# mysql -uhuginn -pq1w2e3r4 -h127.0.0.1 -e "SELECT COUNT(*) agents_after FROM huginn_production.agents; SELECT username FROM huginn_production.users;"
agents_after
7
username
admin
root@huginn-server:~# curl -s -o /dev/null -w "post_restore:%{http_code}\n" http://127.0.0.1:3000/users/sign_in
post_restore:200

恢复后 7 个 Agent 与 admin 账号完整回归,服务无重启直接可用。

⚠️ 实测排障:huginn 账号只有 huginn_production 库的权限,DROP/CREATE 同库是可以的;若恢复到新库名,记得先 GRANT ALL PRIVILEGES ON 新库.* TO 'huginn'@'127.0.0.1',并同步改 .env 的 DATABASE_NAME。

2.4 镜像部署:备份与恢复

root@huginn-server:/opt/huginn-prod# docker exec huginn-prod-mysql-1 sh -c "mysqldump --single-transaction -h127.0.0.1 -uroot -pq1w2e3r4 huginn" 2>/dev/null > huginn-backup-2026-10-17.sql
root@huginn-server:/opt/huginn-prod# ls -lh huginn-backup-2026-10-17.sql
-rw-r--r-- 1 root root 22K Oct 17 09:15 huginn-backup-2026-10-17.sql

恢复(容器内 mysql 客户端直接导回):

root@huginn-server:/opt/huginn-prod# docker exec -i huginn-prod-mysql-1 sh -c "mysql -h127.0.0.1 -uroot -pq1w2e3r4 huginn" 2>/dev/null < huginn-backup-2026-10-17.sql

2.5 事件表瘦身

Event 是增长最快的表(keep_events_for 到期后由调度清理,检查周期 EVENT_EXPIRATION_CHECK 默认 6h)。紧急磁盘回收可手动清过期事件:

root@huginn-server:~# mysql -uhuginn -pq1w2e3r4 -h127.0.0.1 -e "SELECT COUNT(*) expired FROM huginn_production.events WHERE expires_at < NOW();"
root@huginn-server:~# mysql -uhuginn -pq1w2e3r4 -h127.0.0.1 -e "DELETE FROM huginn_production.events WHERE expires_at < NOW();"

(先 SELECT 看体量再删;删除前最好做一次 2.2 的备份。)

三、Agent 调度排查

3.1 排查路径

调度异常按「Web 横幅 → Job Management → 数据库队列 → Agent 日志」四步走:

  1. Dashboard 横幅:出现 The Agent job scheduler is not running 说明后台任务线程未存活;
  2. Job Management 页(导航栏 /jobs):看任务总数、失败任务(Error 状态)与下次执行时间;
  3. 数据库队列:delayed_jobs 表是任务真源;
  4. Agent 日志:Agent 详情页 Logs 标签,看单 Agent 的执行与报错明细。

3.2 数据库视角的任务状态

root@huginn-server:~# mysql -uhuginn -pq1w2e3r4 -h127.0.0.1 -e "SELECT COUNT(*) total FROM huginn_production.delayed_jobs; SELECT COUNT(*) locked FROM huginn_production.delayed_jobs WHERE locked_by IS NOT NULL; SELECT COUNT(*) failed FROM huginn_production.delayed_jobs WHERE last_error IS NOT NULL;"
  • total 长时间不减:Worker 没消费(先查 Worker 进程);
  • locked 恒为 0:没有任务在跑(Worker 死了或 DELAYED_JOB_SLEEP_DELAY 过长);
  • failed 持续增长:有 Agent 每次执行都报错,取 last_error 字段看根因。

3.3 Worker 进程与假死处理

源码部署:

root@huginn-server:~# systemctl status huginn-worker.service --no-pager
● huginn-worker.service - Huginn Worker (delayed_job)
     Loaded: loaded (/etc/systemd/system/huginn-worker.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2026-10-17 00:51:15 UTC; 17min ago
   Main PID: 114 (bundle)
      Tasks: 3 (limit: 5753)
     Memory: 197.4M
        CPU: 1.997s

进程活着但任务不消费(假死)时,重启 Worker 立即恢复;反复假死排查 OOM(dmesg | grep -i oom)与 DELAYED_JOB_MAX_MEMORY(512MB 到点自动回收,可调大)。

⚠️ 实测排障:locked_by IS NOT NULL 的行若长时间不释放(Worker 被 SIGKILL 后遗留锁),任务会卡在队列。v2026.10.14 的 DELAYED_JOB_MAX_RUNTIME 与 master worker 机制会处理绝大多数场景,若遇极端遗留,重启 Worker 进程即触发锁回收。

3.4 Agent 执行日志

每 Agent 最多保留 AGENT_LOG_LENGTH(默认 200)行日志。页面入口之外可从 API 取(本例实测):

GET /api/agents/:id  →  agent.last_event_at / agent.last_error_log_at

页面看更直观:Agent 详情页 Logs 标签,实测样例(EmailAgent 的 SMTP 失败记录):

Failed to send EmailAgent notification: Connection refused - connect(2) for "127.0.0.1" port 2525

四、日志体系

4.1 systemd 部署

Web 与 Worker 的标准输出全部进 journal(unit 里 SyslogIdentifier 分别为 huginn-web / huginn-worker):

root@huginn-server:~# journalctl -u huginn-web.service -n 5 --no-pager
Oct 17 00:51:15 huginn-server puma[113]: *      Workers: 2
Oct 17 00:51:15 huginn-server puma[113]: *      Restarts: (✔) hot (✖) phased (✖) refork
Oct 17 00:51:15 huginn-server puma[113]: * Preloading application
Oct 17 00:51:15 huginn-server puma[113]: * Listening on http://0.0.0.0:3000
Oct 17 00:51:15 huginn-server puma[113]: Use Ctrl-C to stop
root@huginn-server:~# journalctl -u huginn-worker.service -n 3 --no-pager
Oct 17 00:50:20 huginn-server systemd[1]: Started Huginn Worker (delayed_job).
Oct 17 00:51:15 huginn-server systemd[1]: Started Huginn Worker (delayed_job).

Rails 应用日志(请求级)同时写在文件里:/home/huginn/huginn/log/production.log,跟踪请求用 tail -f:

root@huginn-server:~# tail -f /home/huginn/huginn/log/production.log

4.2 镜像部署

容器日志即 Rails 标准输出(入口脚本默认 RAILS_LOG_TO_STDOUT=true):

root@huginn-server:/opt/huginn-prod# docker compose logs --tail 20 web
root@huginn-server:/opt/huginn-prod# docker compose logs -f threaded

迁移日志也在这里,升级后 grep Migrating 确认新迁移执行情况(实测样例):

I, [2026-10-17T02:05:31.745424 #413]  INFO -- : Migrating to DeviseCreateUsers (20120728210244)
== 20120728210244 DeviseCreateUsers: migrating ================================
== 20120728210244 DeviseCreateUsers: migrated (0.0169s) =======================

4.3 日志轮转

production.log 会持续增长,用 logrotate 管理,创建 /etc/logrotate.d/huginn:

/home/huginn/huginn/log/*.log {
  daily
  rotate 14
  compress
  missingok
  notifempty
  copytruncate
}

(copytruncate 避免重启进程才能换文件;镜像部署 stdout 日志由容器运行时接管,Docker 默认 json-file 有 max-size/max-file 可配。)

五、版本升级

5.1 源码部署升级路径

以 v2026.10.14 升级到未来新 release 为例,核心三步:换代码 → 装 gem → 迁移:

root@huginn-server:~# systemctl stop huginn-web.service
root@huginn-server:~# systemctl stop huginn-worker.service
root@huginn-server:~# mysqldump --single-transaction -uhuginn -pq1w2e3r4 -h127.0.0.1 huginn_production 2>/dev/null > /var/backups/huginn-pre-upgrade.sql
root@huginn-server:~# su - huginn
huginn@huginn-server:~$ cd /home/huginn/huginn
huginn@huginn-server:~/huginn$ git fetch --tags
huginn@huginn-server:~/huginn$ git checkout v2026.11.14
huginn@huginn-server:~/huginn$ bundle install
huginn@huginn-server:~/huginn$ npm ci
huginn@huginn-server:~/huginn$ bundle exec rake db:migrate
huginn@huginn-server:~/huginn$ bundle exec rake assets:precompile
huginn@huginn-server:~/huginn$ exit
root@huginn-server:~# systemctl start huginn-web.service
root@huginn-server:~# systemctl start huginn-worker.service

(git checkout 的 tag 以官方仓库最新 release 为准,上文 v2026.11.14 仅示意未来版本的写法;实际执行前用 git tag -l | tail -5 确认。)

注意:

  • .env 与 config/database.yml 不在升级覆盖范围(本地未纳管文件),升级后 diff .env.example .env 快速确认新增必填项;
  • 迁移只进不退,回滚版本需配合 5.1 开头的 pre-upgrade 备份恢复数据库;
  • 大版本升级前先在测试机过一遍完整流程。

5.2 镜像部署升级路径

root@huginn-server:/opt/huginn-prod# docker exec huginn-prod-mysql-1 sh -c "mysqldump --single-transaction -h127.0.0.1 -uroot -pq1w2e3r4 huginn" 2>/dev/null > pre-upgrade.sql
root@huginn-server:/opt/huginn-prod# docker pull ghcr.io/huginn/huginn-single-process:latest
root@huginn-server:/opt/huginn-prod# docker compose up -d web threaded
 Container huginn-prod-web-1        Recreated
 Container huginn-prod-threaded-1   Recreated
 Container huginn-prod-web-1        Started

新镜像首次启动自动执行增量迁移(docker compose logs web | grep Migrating 核对),健康检查转 healthy 即升级完成。回滚:把 compose 里 image 改回旧 tag(或 digest)后 docker compose up -d,数据异常时用 pre-upgrade.sql 恢复。

5.3 全功能镜像(方案 A)升级

root@huginn-server:/opt/huginn# docker compose pull
root@huginn-server:/opt/huginn# docker compose up -d

数据在 ./mysql-data,升级前照例先 tar czf 打包一次(见 Compose 指南 4.3 节)。

六、巡检清单

每日/每周建议巡检项(实测命令可直接复制):

root@huginn-server:~# systemctl is-active huginn-web.service
root@huginn-server:~# systemctl is-active huginn-worker.service
root@huginn-server:~# curl -s -o /dev/null -w "login:%{http_code}\n" http://127.0.0.1:3000/users/sign_in
root@huginn-server:~# mysql -uhuginn -pq1w2e3r4 -h127.0.0.1 -e "SELECT COUNT(*) failed FROM huginn_production.delayed_jobs WHERE last_error IS NOT NULL;"
root@huginn-server:~# df -h /var/lib/mysql | tail -1
  • 服务 active + 登录页 200:基础可用;
  • failed 任务数突增:有 Agent 持续报错,进 Job Management 定位;
  • 磁盘水位:events 表与日志是两大增长源(见 2.5 与 4.3)。

七、参考链接