- Rust-based digital asset management system - Video analysis: ASR, OCR, YOLO, Face, Pose - RAG capabilities with Qdrant vector database - Multi-database support: PostgreSQL, Redis, MongoDB - Monitoring system with launchd plists - n8n workflow automation integration
17 KiB
17 KiB
Momentry 服務添加規範 v2.0
一、概述
本文檔定義在 Momentry 系統中添加新服務的標準流程和規範。
重要原則:
- 使用
launchctl管理服務,勿使用brew services - 所有服務使用
com.momentry.*作為 plist Label - 數據存放於
/Users/accusys/momentry/目錄 - 每個服務需提供完整的監控腳本
- 所有服務 Plist 存放於
/Library/LaunchDaemons/ - 所有服務以
accusys用戶運行,確保 accusys 可以管理
二、服務運行方式
2.1 運行分類
| 類型 | 說明 | 示例 |
|---|---|---|
| 開機自動運行 | 電腦開機後立即自動啟動 | PostgreSQL, Redis, n8n, Caddy 等核心服務 |
| 登入時運行 | 用戶登入後才啟動 | 開發工具、臨時服務 |
當前所有服務:均為開機自動運行
2.2 Plist 存放位置
所有 Momentry 服務統一存放於:
/Library/LaunchDaemons/com.momentry.{service_name}.plist
三、服務命名規範
3.1 Plist 文件命名
com.momentry.{service_name}.plist
示例:
com.momentry.redis.plistcom.momentry.n8n.main.plistcom.momentry.rustdesk.hbbs.plist
3.2 目錄命名
服務相關目錄統一放置於:
/Users/accusys/momentry/
├── var/{service_name}/ # 服務數據
├── etc/{service_name}/ # 服務配置
├── log/{service_name}.log # 服務日誌 (stdout)
└── log/{service_name}.error.log # 錯誤日誌 (stderr)
四、Plist 文件模板
4.1 標準服務模板
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.momentry.{service_name}</string>
<key>UserName</key>
<string>accusys</string>
<key>WorkingDirectory</key>
<string>/Users/accusys/momentry/var/{service_name}</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/executable</string>
<string>--arg1</string>
<string>value1</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
<!-- 其他環境變數 -->
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/accusys/momentry/log/{service_name}.log</string>
<key>StandardErrorPath</key>
<string>/Users/accusys/momentry/log/{service_name}.error.log</string>
</dict>
</plist>
4.2 日誌文件規範
每個服務必須創建兩個日誌文件:
| 文件 | 說明 | 路徑 |
|---|---|---|
| StandardOutPath | 標準輸出日誌 | /Users/accusys/momentry/log/{service_name}.log |
| StandardErrorPath | 錯誤輸出日誌 | /Users/accusys/momentry/log/{service_name}.error.log |
創建日誌文件:
touch /Users/accusys/momentry/log/{service_name}.log
touch /Users/accusys/momentry/log/{service_name}.error.log
chmod 644 /Users/accusys/momentry/log/{service_name}.log
chmod 644 /Users/accusys/momentry/log/{service_name}.error.log
五、添加服務步驟
步驟 1:創建目錄結構
# 創建服務目錄
mkdir -p /Users/accusys/momentry/var/{service_name}
mkdir -p /Users/accusys/momentry/etc/{service_name}
# 創建日誌文件
touch /Users/accusys/momentry/log/{service_name}.log
touch /Users/accusys/momentry/log/{service_name}.error.log
步驟 2:創建 Plist 文件
# 複製模板並編輯
cp /Users/accusys/momentry_core_0.1/momentry_runtime/plist/template.service.plist \
/Users/accusys/momentry_core_0.1/momentry_runtime/plist/com.momentry.{service_name}.plist
# 編輯 plist 文件
vim /Users/accusys/momentry_core_0.1/momentry_runtime/plist/com.momentry.{service_name}.plist
步驟 3:複製到系統 LaunchDaemons
# 複製到 /Library/LaunchDaemons/
sudo cp /Users/accusys/momentry_core_0.1/momentry_runtime/plist/com.momentry.{service_name}.plist \
/Library/LaunchDaemons/
步驟 4:載入服務
# 載入服務
sudo launchctl load /Library/LaunchDaemons/com.momentry.{service_name}.plist
# 驗證服務狀態
launchctl list | grep momentry
步驟 5:添加監控
在 monitor/config/monitor_config.yaml 中添加服務配置:
service:
services:
- name: "{service_name}"
type: "http" # 或 "process", "tcp"
port: {port_number}
host: "localhost"
check_url: "http://localhost:{port}/health"
timeout: 5
enabled: true
步驟 6:添加文檔
在 docs/INSTALL_{SERVICE_NAME}.md 中記錄:
- 安裝步驟
- 配置說明
- 健康檢查命令
- 故障排除
六、服務分類
按功能分類
| 類別 | 服務 |
|---|---|
| 資料庫 | PostgreSQL, Redis, MariaDB, MongoDB |
| 應用 | n8n, Gitea, SFTPGo |
| 網頁 | Caddy, PHP-FPM |
| AI/ML | Ollama, Qdrant |
| 遠程 | RustDesk |
按運行方式分類
| 運行方式 | 數量 | 服務 |
|---|---|---|
| 開機自動運行 | 15 | PostgreSQL, Redis, n8n, Caddy, Gitea, SFTPGo, Ollama, Qdrant, MariaDB, PHP-FPM, RustDesk, MongoDB, Agent |
| 登入時運行 | 0 | (暫無) |
七、監控要求
每個服務必須提供:
7.1 健康檢查
在 monitor/service/health_check.sh 中添加檢查函數:
check_{service_name}() {
local start=$(date +%s%N)
if nc -z localhost {port} > /dev/null 2>&1; then
local end=$(date +%s%N)
local ms=$(( (end - start) / 1000000 ))
echo -e "${GREEN}✓${NC} {service_name} ({port}) - ${ms}ms"
record_service "{service_name}" "up" "$ms" ""
return 0
else
echo -e "${RED}✗${NC} {service_name} ({port}) - Down"
record_service "{service_name}" "down" "0" "Connection failed"
return 1
fi
}
7.2 數據庫記錄
-- 添加服務監控記錄函數
record_service() {
local service=$1
local status=$2
local response_time=$3
local error_msg=$4
psql -U accusys -h localhost -d momentry << EOF
INSERT INTO monitor_services (service_name, service_type, status, response_time_ms, error_message, checked_at)
VALUES ('$service', 'service', '$status', $response_time, '$error_msg', NOW());
EOF
}
八、服務管理命令
8.1 基本操作
# 啟動服務
sudo launchctl load /Library/LaunchDaemons/com.momentry.{service}.plist
# 停止服務
sudo launchctl unload /Library/LaunchDaemons/com.momentry.{service}.plist
# 重啟服務
sudo launchctl unload /Library/LaunchDaemons/com.momentry.{service}.plist
sudo launchctl load /Library/LaunchDaemons/com.momentry.{service}.plist
# 查看服務狀態
launchctl list | grep momentry
# 查看服務日誌
tail -f /Users/accusys/momentry/log/{service}.log
tail -f /Users/accusys/momentry/log/{service}.error.log
8.2 故障排除
# 檢查服務是否運行
pgrep -f "{service_process_name}"
# 檢查端口是否監聽
lsof -i :{port}
# 檢查錯誤日誌
tail -100 /Users/accusys/momentry/log/{service}.error.log
九、服務備份作業
9.1 備份內容
每個服務需要備份的內容:
| 類別 | 路徑 | 說明 |
|---|---|---|
| 數據 | /Users/accusys/momentry/var/{service}/ |
服務運行數據 |
| 配置 | /Users/accusys/momentry/etc/{service}/ |
服務配置文件 |
| Plist | /Library/LaunchDaemons/com.momentry.{service}.plist |
啟動配置 |
| 日誌 | /Users/accusys/momentry/log/{service}.log |
運行日誌 |
9.2 備份命名規範
格式: {service}_{type}_{YYYYMMDD}_{HHMMSS}[_{suffix}].{ext}
組成部分:
| 位置 | 說明 | 範例 |
|---|---|---|
{service} |
服務名稱 (小寫) | postgresql, redis, n8n |
{type} |
備份類型 | full, db, cfg, data |
{YYYYMMDD} |
備份日期 | 20260315 |
{HHMMSS} |
備份時間 (24小時制) | 030000 |
{suffix} |
可選標記 | incremental, verified |
{ext} |
檔案擴展名 | sql.gz, tar.gz, rdb, zip |
類型說明:
| 類型 | 說明 | 包含內容 |
|---|---|---|
full |
完整備份 | 數據 + 配置 + 日誌 |
db |
數據庫備份 | 資料庫導出 (sql, rdb) |
cfg |
配置備份 | 配置文件 |
data |
數據備份 | var 目錄 |
範例:
postgresql_db_20260315_030000.sql.gz # PostgreSQL 完整資料庫 (壓縮)
redis_rdb_20260315_030000.rdb # Redis RDB 快照
n8n_full_20260315_030000.tar.gz # n8n 完整備份
mariadb_db_wordpress_20260315_030000.sql.gz # MariaDB WP 資料庫
gitea_full_20260315_030000.zip # Gitea 完整備份
qdrant_snapshot_20260315_030000.tar.gz # Qdrant 向量庫
ollama_cfg_20260315_030000.tar.gz # Ollama 配置
caddy_cfg_20260315_030000.tar.gz # Caddy 配置
可信斷點標記:
- 檔名本身即為可信時間點
- 還原時直接使用檔名中的時間戳
- 建議配合
backup_registry資料庫記錄完整元數據
校驗和命名:
postgresql_db_20260315_030000.sql.gz.sha256
9.3 備份腳本
#!/bin/bash
# 標準化備份腳本範本
# 遵循命名規範: {service}_{type}_{YYYYMMDD}_{HHMMSS}.{ext}
set -e
SERVICE_NAME="{service_name}"
BACKUP_TYPE="{type}" # full, db, cfg, data
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/Users/accusys/momentry/backup/${SERVICE_NAME}"
mkdir -p "$BACKUP_DIR"
# 根據類型執行備份
case "$BACKUP_TYPE" in
full)
echo "[$TIMESTAMP] 執行 $SERVICE_NAME 完整備份..."
tar -czf "$BACKUP_DIR/${SERVICE_NAME}_full_${TIMESTAMP}.tar.gz" \
/Users/accusys/momentry/var/${SERVICE_NAME}/ \
/Users/accusys/momentry/etc/${SERVICE_NAME}/ 2>/dev/null
;;
db)
echo "[$TIMESTAMP] 執行 $SERVICE_NAME 資料庫備份..."
if [ "$SERVICE_NAME" = "postgresql" ]; then
pg_dump -U accusys ${SERVICE_NAME} | gzip > \
"$BACKUP_DIR/${SERVICE_NAME}_db_${TIMESTAMP}.sql.gz"
elif [ "$SERVICE_NAME" = "mariadb" ]; then
mysqldump -u root -p --all-databases | gzip > \
"$BACKUP_DIR/${SERVICE_NAME}_db_${TIMESTAMP}.sql.gz"
elif [ "$SERVICE_NAME" = "redis" ]; then
redis-cli -a accusys SAVE
cp /opt/homebrew/var/db/redis/dump.rdb \
"$BACKUP_DIR/${SERVICE_NAME}_rdb_${TIMESTAMP}.rdb"
fi
;;
cfg)
echo "[$TIMESTAMP] 執行 $SERVICE_NAME 配置備份..."
tar -czf "$BACKUP_DIR/${SERVICE_NAME}_cfg_${TIMESTAMP}.tar.gz" \
/Users/accusys/momentry/etc/${SERVICE_NAME}/ 2>/dev/null
;;
data)
echo "[$TIMESTAMP] 執行 $SERVICE_NAME 數據備份..."
tar -czf "$BACKUP_DIR/${SERVICE_NAME}_data_${TIMESTAMP}.tar.gz" \
/Users/accusys/momentry/var/${SERVICE_NAME}/ 2>/dev/null
;;
esac
# 生成校驗和
if [ -f "$BACKUP_DIR/${SERVICE_NAME}_${BACKUP_TYPE}_${TIMESTAMP}"* ]; then
sha256sum "$BACKUP_DIR/${SERVICE_NAME}_${BACKUP_TYPE}_${TIMESTAMP}"* > \
"$BACKUP_DIR/${SERVICE_NAME}_${BACKUP_TYPE}_${TIMESTAMP}.sha256"
fi
# 清理舊備份 (保留 30 天)
find "$BACKUP_DIR" -name "*_${TIMESTAMP%%_*}_*.tar.gz" -mtime +30 -delete 2>/dev/null
find "$BACKUP_DIR" -name "*_${TIMESTAMP%%_*}_*.sql.gz" -mtime +30 -delete 2>/dev/null
find "$BACKUP_DIR" -name "*_${TIMESTAMP%%_*}_*.rdb" -mtime +30 -delete 2>/dev/null
find "$BACKUP_DIR" -name "*.sha256" -mtime +30 -delete 2>/dev/null
echo "備份完成: ${SERVICE_NAME}_${BACKUP_TYPE}_${TIMESTAMP}"
9.4 備份排程
建議使用 cron 進行自動備份:
# 編輯 crontab
crontab -e
# 添加備份任務 (每天凌晨 3 點)
0 3 * * * /Users/accusys/momentry/scripts/backup_{service}.sh >> /Users/accusys/momentry/log/backup.log 2>&1
# 每週日凌晨 3 點執行完整備份
0 3 * * 0 /Users/accusys/momentry/scripts/backup_{service}.sh full >> /Users/accusys/momentry/log/backup.log 2>&1
9.5 備份驗證
# 查看備份列表 (按時間排序)
ls -lt /Users/accusys/momentry/backup/{service}/
# 驗證備份完整性
# 1. 檢查校驗和
sha256sum -c /Users/accusys/momentry/backup/{service}/*.sha256
# 2. 驗證 tar 壓縮
tar -tzf /Users/accusys/momentry/backup/{service}/{service}_full_20260315_030000.tar.gz
# 3. 驗證 SQL 備份
zcat /Users/accusys/momentry/backup/{service}/{service}_db_20260315_030000.sql.gz | head -5
# 驗證備份完整性
tar -tzf /Users/accusys/momentry/backup/{service}/{service}_var_20260315.tar.gz
十、服務完整刪除作業
10.1 刪除前確認
警告:此操作不可逆,請確保已完成備份!
- 確認服務已停止運行
- 確認數據已備份
- 確認無其他服務依賴此服務
10.2 刪除步驟
步驟 1:停止服務
# 停止服務
sudo launchctl unload /Library/LaunchDaemons/com.momentry.{service}.plist
# 驗證服務已停止
launchctl list | grep momentry.{service}
步驟 2:刪除 Plist
# 刪除系統 Plist
sudo rm /Library/LaunchDaemons/com.momentry.{service}.plist
# 刪除專案 Plist
rm /Users/accusys/momentry_core_0.1/momentry_runtime/plist/com.momentry.{service}.plist
步驟 3:刪除數據和配置
# 刪除數據目錄
sudo rm -rf /Users/accusys/momentry/var/{service}/
# 刪除配置目錄
sudo rm -rf /Users/accusys/momentry/etc/{service}/
# 刪除日誌
rm -f /Users/accusys/momentry/log/{service}.log
rm -f /Users/accusys/momentry/log/{service}.error.log
步驟 4:清理監控配置
# 從監控配置中移除服務
vim /Users/accusys/momentry_core_0.1/monitor/config/monitor_config.yaml
# 刪除該服務的監控配置
# 從監控腳本中移除
vim /Users/accusys/momentry_core_0.1/monitor/service/health_check.sh
# 移除該服務的檢查函數
步驟 5:清理監控數據(可選)
# 保留歷史數據還是刪除?
# 刪除監控數據
psql -U accusys -h localhost -d momentry -c "
DELETE FROM monitor_services WHERE service_name = '{service}';
"
10.3 驗證刪除
# 確認服務已停止
launchctl list | grep momentry.{service}
# 確認目錄已刪除
ls /Users/accusys/momentry/var/{service}/ 2>/dev/null || echo "已刪除"
# 確認 Plist 已刪除
ls /Library/LaunchDaemons/com.momentry.{service}.plist 2>/dev/null || echo "已刪除"
10.4 完整刪除腳本
#!/bin/bash
SERVICE_NAME="{service_name}"
echo "========== 服務完整刪除 =========="
echo "服務: $SERVICE_NAME"
echo "警告:此操作不可逆!"
read -p "確認繼續 (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
echo "取消刪除"
exit 0
fi
# 停止服務
echo "[1/6] 停止服務..."
sudo launchctl unload /Library/LaunchDaemons/com.momentry.${SERVICE_NAME}.plist 2>/dev/null
# 刪除 Plist
echo "[2/6] 刪除 Plist..."
sudo rm -f /Library/LaunchDaemons/com.momentry.${SERVICE_NAME}.plist
rm -f /Users/accusys/momentry_core_0.1/momentry_runtime/plist/com.momentry.${SERVICE_NAME}.plist
# 刪除數據
echo "[3/6] 刪除數據..."
sudo rm -rf /Users/accusys/momentry/var/${SERVICE_NAME}/
# 刪除配置
echo "[4/6] 刪除配置..."
sudo rm -rf /Users/accusys/momentry/etc/${SERVICE_NAME}/
# 刪除日誌
echo "[5/6] 刪除日誌..."
rm -f /Users/accusys/momentry/log/${SERVICE_NAME}.log
rm -f /Users/accusys/momentry/log/${SERVICE_NAME}.error.log
# 清理監控數據
echo "[6/6] 清理監控數據..."
psql -U accusys -h localhost -d momentry -c "
DELETE FROM monitor_services WHERE service_name = '${SERVICE_NAME}';
" 2>/dev/null
echo "========== 刪除完成 =========="
十一、檢查清單
添加新服務時,請確認以下項目:
- 創建服務目錄 (
var/,etc/) - 配置日誌文件 (
.log+.error.log) - 創建 plist 文件,UserName 設為
accusys - 複製到
/Library/LaunchDaemons/ - 使用 launchctl 載入服務
- 驗證服務運行
- 添加監控配置
- 測試監控腳本
- 創建安裝文檔
- 更新 SERVICES.md 服務清單
- 更新 MOMENTRY_INTEGRATION_GUIDE.md
十二、模板文件
Plist 模板位置
/Users/accusys/momentry_core_0.1/momentry_runtime/plist/
├── template.service.plist # 服務模板
├── com.momentry.redis.plist # 服務示例
└── com.momentry.n8n.main.plist # 複雜服務示例
創建模板命令
# 創建服務模板
cat > /Users/accusys/momentry_core_0.1/momentry_runtime/plist/template.service.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.momentry.SERVICE_NAME</string>
<key>UserName</key>
<string>accusys</string>
<key>WorkingDirectory</key>
<string>/Users/accusys/momentry/var/SERVICE_NAME</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/executable</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/accusys/momentry/log/SERVICE_NAME.log</string>
<key>StandardErrorPath</key>
<string>/Users/accusys/momentry/log/SERVICE_NAME.error.log</string>
</dict>
</plist>
EOF
十一、版本歷史
| 版本 | 日期 | 內容 |
|---|---|---|
| 1.0 | 2026-03-15 | 初始版本 |
| 2.0 | 2026-03-15 | 統一 Plist 位置、移除 root/用戶區分、加入運行方式分類 |
| 2.1 | 2026-03-15 | 新增服務備份作業、服務完整刪除作業 |