Files
getDomain/docs/17_domainCheck_全流程部署实操手册.md
Your Name 9aa0d87c4a debug
2026-04-16 22:29:58 +08:00

16 KiB
Raw Blame History

17 domainCheck 手工部署实操手册

一、文档目标

这份文档只讲一件事:

不依赖一键脚本,完全手工完成部署、更新、排障和扩容。

它不是设计说明,也不是零散检查单,而是给实际部署时直接照着做的“手工操作手册”。

文档边界:

适用场景:

  • 先在国外机器完成单机部署与联调
  • 后续再扩到“国外控制面 + 大陆执行面”
  • 当前暂时无法把代码真正部署到大陆机器时,先在国外机器模拟多节点联调
  • 最后再把同样的部署方式复制到其他机器

一句话理解:

先把国外主控机部署好,再按同样套路扩第二台、第三台,不靠临场猜。

并发配置补充:

  • 系统支持 默认线程数 + 节点单独覆盖
  • 节点单独覆盖按机器自己的 NODE_CODE 命中
  • 某台机器没配置覆盖值时,自动回退到默认线程数

二、推荐部署形态

1. 当前最推荐起步形态

  • 国外机器 1 台:
    • domain-web
    • domain-api
    • PostgreSQL
    • Redis
    • domaincheck-worker
  • 后续扩容时:
    • 新增大陆 controller
    • 新增大陆 worker

说明:

  • 因为你当前还不能直接把代码稳定部署到大陆机器,所以第一阶段先把国外机器单机跑稳
  • 这台国外机器同时承担:
    • 后台
    • API
    • 数据库
    • Redis
    • Worker
  • 等这套稳定后,再把多机脚本复制到其他机器

2. 最终推荐形态

  • 国外 control
    • domain-web
    • domain-api
    • 主 PostgreSQL
    • 结果归档
  • 大陆 controller
    • Redis
    • 运行态 PostgreSQL
    • domaincheck-worker
    • domaincheck-sync-agent
  • 大陆 worker
    • domaincheck-worker

三、服务器准备

1. 系统要求

  • CentOS Stream 9
  • Python 3.11
  • PostgreSQL 14+
  • Redis 6+
  • Nginx

关键说明:

  • 这里的 Python 不是“系统自带什么就用什么”
  • 必须明确安装 python3.11
  • 不能只装系统默认 python3
  • 因为后续部署命令直接使用的是 python3.11 -m venv .venv

推荐先执行:

dnf install -y python3.11 python3.11-devel
python3.11 --version

期望输出类似:

Python 3.11.x

2. 目录约定

统一使用:

/opt/domaincheck
├── domain-api
├── domain-web
└── domainCheck

3. 当前仓库与运行态关系

如果你像当前测试机一样,用仓库目录做源码源头,也可以用软链接:

ln -s /www/wwwroot/getDomain/domain-api /opt/domaincheck/domain-api
ln -s /www/wwwroot/getDomain/domain-web /opt/domaincheck/domain-web
ln -s /www/wwwroot/getDomain/domainCheck /opt/domaincheck/domainCheck

如果你是完整复制代码到目标机,也可以直接把目录上传到 /opt/domaincheck/

四、第一阶段:国外单机部署

这一阶段的目标是:

  • 后台可访问
  • API 正常
  • 数据库已初始化
  • Worker 可跑
  • 运行中心正常
  • smoke test 通过

1. 拉取代码

当前建议统一走 git 管理和更新,不再手工散传目录。

执行口径:

  • 这里建议直接使用 root
  • 不建议使用 www 用户执行整套部署命令
  • 因为后面还会接着写 systemd/etc/default//opt/domaincheck/ 和服务启停

第一次部署建议:

mkdir -p /www/wwwroot
cd /www/wwwroot
git clone 你的仓库地址 getDomain
cd getDomain
git checkout main
git pull origin main

然后建立运行目录软链接:

mkdir -p /opt/domaincheck
ln -s /www/wwwroot/getDomain/domain-api /opt/domaincheck/domain-api
ln -s /www/wwwroot/getDomain/domain-web /opt/domaincheck/domain-web
ln -s /www/wwwroot/getDomain/domainCheck /opt/domaincheck/domainCheck

后续更新统一使用:

cd /www/wwwroot/getDomain
git fetch --all
git checkout main
git pull --ff-only origin main

1.1 先确认 Python 3.11 已安装

如果当前机器还没有 python3.11,先执行:

dnf install -y python3.11 python3.11-devel
python3.11 --version

只有确认 python3.11 命令存在后,再继续下面的虚拟环境步骤。

2. 创建 Python 虚拟环境

cd /opt/domaincheck/domainCheck
python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
python3.11 - <<'PY'
from pathlib import Path

source = Path("requirements.txt")
target = Path("requirements.linux.txt")
raw = source.read_bytes()
for encoding in ("utf-8", "utf-16", "utf-16-le", "utf-16-be", "gbk"):
    try:
        text = raw.decode(encoding)
        break
    except UnicodeDecodeError:
        continue
else:
    raise SystemExit("无法解析 requirements.txt 编码")

skip_prefixes = (
    "pywin32==",
    "pywin32-ctypes==",
    "twisted-iocpsupport==",
    "win32-setctime==",
)
lines = []
for line in text.splitlines():
    normalized = line.strip().lstrip("\ufeff")
    if normalized.lower().startswith(skip_prefixes):
        continue
    lines.append(normalized)

target.write_text("\n".join(lines) + "\n", encoding="utf-8")
PY
pip install -r requirements.linux.txt

然后补 API 依赖:

cd /opt/domaincheck/domain-api
/opt/domaincheck/domainCheck/.venv/bin/pip install fastapi uvicorn pydantic-settings psycopg2-binary redis openpyxl python-multipart

补充说明:

  • 这里不能直接在 Linux 上裸跑 pip install -r requirements.txt
  • 因为桌面版历史依赖里包含 pywin32 等 Windows-only 包
  • 手工部署时也必须先生成 requirements.linux.txt 再安装

3. 配置数据库和 Redis

确保 PostgreSQL 和 Redis 可用。

建议先确认:

psql -h 127.0.0.1 -U postgres -d domain -c "select 1;"
redis-cli ping

4. 配置 domainCheck/.env

至少确认这些项:

DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=domain
DB_USER=postgres
DB_PASSWORD=你的密码

REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0

5. 初始化数据库

这是最重要的一步,新库必须先做:

cd /opt/domaincheck/domainCheck
python3 init_database.py

如果不先执行,至少这些接口会直接 500

  • /api/v1/dashboard/overview
  • /api/v1/detect/status
  • /api/v1/imports/summary

6. 构建前端

进入 domain-web,配置生产环境 API 地址:

cd /opt/domaincheck/domain-web
cp .env.production.example .env.production

VITE_API_BASE_URL 改成目标 API例如

VITE_API_BASE_URL=https://api.domain.com/api/v1

然后构建:

npm install
npm run build

7. 配置 Nginx

参考:

  • domain-web/deploy/nginx/domain-web.conf

把静态目录指到:

/opt/domaincheck/domain-web/dist

常见做法:

  • admin.domain 对外提供后台页面
  • api.domain.com 对外提供 API

8. 安装 systemd 服务

复制模板:

cp /opt/domaincheck/domain-api/deploy/systemd/domain-api.service /etc/systemd/system/domaincheck-api.service
cp /opt/domaincheck/domain-api/deploy/systemd/domain-worker.service /etc/systemd/system/domaincheck-worker.service

9. 配置 API 环境变量

建议使用:

cp /opt/domaincheck/domain-api/deploy/multi-region/templates/domaincheck-api.env.example /etc/default/domaincheck-api

至少改这些:

WORKER_MODE=linux-systemd
API_HOST=0.0.0.0
API_PORT=8100
DOMAIN_ROOT=/opt/domaincheck/domainCheck
NODE_CODE=overseas-control-01
NODE_REGION=overseas
NODE_ROLE=control
CORS_ORIGINS=http://127.0.0.1:3201,http://localhost:3201,http://你的服务器IP:3201
SYNC_PUSH_ENABLED=false

如果你已经固定域名,建议直接改成:

CORS_ORIGINS=https://admin.domain,http://127.0.0.1:3201,http://localhost:3201

10. 修正权限

mkdir -p /opt/domaincheck/domain-api/runtime
touch /opt/domaincheck/domainCheck/detect_worker.log
chown -R www:www /opt/domaincheck/domain-api/runtime
chown www:www /opt/domaincheck/domainCheck/detect_worker.log
chmod 664 /opt/domaincheck/domainCheck/detect_worker.log

11. 启动服务

systemctl daemon-reload
systemctl enable domaincheck-api
systemctl enable domaincheck-worker
systemctl restart domaincheck-api
systemctl restart domaincheck-worker

12. 检查服务状态

systemctl status domaincheck-api --no-pager -l
systemctl status domaincheck-worker --no-pager -l

五、第一阶段验收

1. 接口检查

curl http://127.0.0.1:8100/health
curl http://127.0.0.1:8100/api/v1/runtime/preflight
curl http://127.0.0.1:8100/api/v1/runtime/status
curl http://127.0.0.1:8100/api/v1/runtime/readiness

期望:

  • /health.status=ok
  • /health.worker_mode=linux-systemd
  • /runtime/preflight.ok=true
  • /runtime/status.worker.running=true
  • /runtime/readiness.status 至少不是 blocking

2. smoke test

cd /opt/domaincheck/domain-api/deploy/linux
python3 smoke_test.py --base-url http://127.0.0.1:8100

如果要连 Web 一起检查:

python3 smoke_test.py --base-url http://127.0.0.1:8100 --web-url http://127.0.0.1:3201

期望:

  • ok=true

3. 后台页面检查

浏览器打开:

https://admin.domain

至少检查:

  • 登录
  • 运行中心
  • 系统设置
  • 域名筛选
  • 导入
  • 导出

六、第二阶段:国外机器模拟多机联调

如果你暂时还不能把代码部署到大陆机器,就先在国外机器做这一步。

1. 一键多机演练

cd /opt/domaincheck/domain-api
bash deploy/multi-region/rehearse_multi_region.sh http://127.0.0.1:8100

它会自动模拟:

  • 一个大陆 controller
  • 两个大陆 worker

并自动检查:

  • runtime/readiness
  • runtime/cluster
  • online control / online worker 数量
  • 节点状态是否符合预期

2. 通过标准

如果输出里出现:

rehearsal passed

说明当前这台国外机器上的多机模拟联调已通过,可以继续部署到其他机器。

3. 如果想手工模拟

也可以单独跑:

cd /opt/domaincheck/domain-api
bash deploy/multi-region/simulate_multi_region.sh http://127.0.0.1:8100

停止时按:

Ctrl+C

4. 清理旧节点残影

如果之前测试过多轮,集群里可能残留老节点:

cd /opt/domaincheck/domain-api
bash deploy/multi-region/prune_cluster_nodes.sh --minutes 30 --dry-run
bash deploy/multi-region/prune_cluster_nodes.sh --minutes 30

如果只删某个旧节点:

bash deploy/multi-region/prune_cluster_nodes.sh --node-code mainland-worker-01

七、第三阶段:部署到其他机器

等国外单机和模拟多机都通过后,就可以把同样的代码与脚本部署到其他机器。

A. 新海外控制机

在目标机执行:

cd /opt/domaincheck/domain-api
bash deploy/multi-region/bootstrap_overseas.sh /opt/domaincheck

然后完善:

  • /etc/default/domaincheck-api
  • Nginx
  • PostgreSQL
  • Redis

最后检查:

bash deploy/multi-region/check_cluster.sh http://127.0.0.1:8100

B. 大陆 controller

在目标机执行:

cd /opt/domaincheck/domain-api
bash deploy/multi-region/bootstrap_mainland.sh /opt/domaincheck controller

然后检查:

bash deploy/multi-region/check_mainland_controller.sh

关键配置是:

NODE_CODE=mainland-controller-01
NODE_REGION=mainland
NODE_ROLE=control
SYNC_PUSH_ENABLED=true
SYNC_SOURCE_REGION=mainland
SYNC_TARGET_REGION=overseas
SYNC_TARGET_API_BASE_URL=http://海外控制面IP:8100/api/v1
SYNC_SHARED_TOKEN=你自己的共享令牌

C. 大陆 worker

在目标机执行:

cd /opt/domaincheck/domain-api
bash deploy/multi-region/bootstrap_mainland.sh /opt/domaincheck worker

关键配置是:

NODE_CODE=mainland-worker-01
NODE_REGION=mainland
NODE_ROLE=worker
SYNC_PUSH_ENABLED=true
SYNC_SOURCE_REGION=mainland
SYNC_TARGET_REGION=overseas
SYNC_TARGET_API_BASE_URL=http://海外控制面IP:8100/api/v1

八、部署到其他机器后的联调顺序

建议按这个顺序,不容易乱:

  1. 先让海外控制机稳定
  2. 再接大陆 controller
  3. 再接第一台大陆 worker
  4. 再接第二台、第三台 worker

每接一台都执行:

curl http://海外控制机:8100/api/v1/runtime/readiness
curl http://海外控制机:8100/api/v1/runtime/cluster
curl http://海外控制机:8100/api/v1/runtime/sync-summary

如果海外 API 已经挂到正式域名,建议直接写成:

curl https://api.domain.com/api/v1/runtime/readiness
curl https://api.domain.com/api/v1/runtime/cluster
curl https://api.domain.com/api/v1/runtime/sync-summary

联调通过标准

  • runtime/cluster 能看到新节点
  • last_heartbeat_at 持续刷新
  • 大陆 controller 为 role=control
  • 大陆 worker 为 role=worker
  • 执行任务时 worker 状态能变成 busy
  • runtime/readiness 至少不是 blocking
  • runtime/sync-summary 能看到 detect_result_batches

九、上线前最后检查

按这份文档部署完成后,再回看:

重点保留:

  • systemctl status
  • journalctl
  • /health
  • /runtime/preflight
  • /runtime/readiness
  • /runtime/sync-summary
  • smoke test
  • 诊断包

十、常见问题

1. API 启动了,但接口 500

优先检查有没有先执行:

cd /opt/domaincheck/domainCheck
python3 init_database.py

2. Worker 一直重启

优先检查:

  • /opt/domaincheck/domainCheck/detect_worker.log 权限
  • /opt/domaincheck/domain-api/runtime/ 权限
  • domainCheck/.env 数据库和 Redis 配置

3. readiness 一直是 attention

优先检查:

  • 集群里是否残留旧离线节点
  • 是否还没接入大陆 controller
  • 是否还没有在线 worker

必要时先清理旧节点:

bash deploy/multi-region/prune_cluster_nodes.sh --minutes 30

4. 模拟多机通过了,真实机器还没接上

这是正常的。

模拟多机的意义是:

  • 验证代码、脚本、页面、状态口径一致
  • 不代表真实大陆网络、代理、同步链路已经完成

真实机器接入时,重点要再看:

  • 节点心跳
  • 同步目标地址
  • 共享 token
  • 真实 Redis / PostgreSQL 连接

十一、最短执行版本

如果你只想看最短版,可以照这个跑:

国外单机先跑通

cd /opt/domaincheck/domainCheck
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python3 init_database.py

cd /opt/domaincheck/domain-api
/opt/domaincheck/domainCheck/.venv/bin/pip install fastapi uvicorn pydantic-settings psycopg2-binary redis openpyxl python-multipart

systemctl daemon-reload
systemctl enable domaincheck-api domaincheck-worker
systemctl restart domaincheck-api domaincheck-worker

curl http://127.0.0.1:8100/health
curl http://127.0.0.1:8100/api/v1/runtime/preflight
curl http://127.0.0.1:8100/api/v1/runtime/readiness

再跑多机模拟验收

cd /opt/domaincheck/domain-api
bash deploy/multi-region/rehearse_multi_region.sh http://127.0.0.1:8100

通过后再上其他机器

bash deploy/multi-region/bootstrap_overseas.sh /opt/domaincheck
bash deploy/multi-region/bootstrap_mainland.sh /opt/domaincheck controller
bash deploy/multi-region/bootstrap_mainland.sh /opt/domaincheck worker

十二、最终结论

当前最稳的推进方式是:

  1. 先在国外机器完成单机部署
  2. 再在国外机器完成多机模拟演练
  3. 演练通过后,再复制到其他机器
  4. 最后再做真实跨地域联调

一句话总结:

先把单机跑稳,再把多机脚本跑通,最后再扩机器;每一步都有现成脚本,不靠现场猜。