Files
getDomain/docs/17_domainCheck_全流程部署实操手册.md
Your Name e9c0a75b8f debug
2026-04-17 01:04:11 +08:00

735 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 17 domainCheck 手工部署实操手册
## 一、文档目标
这份文档只讲一件事:
> 不依赖一键脚本,完全手工完成部署、更新、排障和扩容。
它不是设计说明,也不是零散检查单,而是给实际部署时直接照着做的“手工操作手册”。
文档边界:
- 这里只讲手工部署
- 不使用 `install_overseas_quick.sh`
- 不使用 `install_mainland_controller_quick.sh`
- 不使用 `install_mainland_worker_quick.sh`
- 如果你想走傻瓜式复制部署,请改看:
- [18_domainCheck_CentOS9一键复制部署与更新文档.md](/www/wwwroot/getDomain/docs/18_domainCheck_CentOS9一键复制部署与更新文档.md:1)
适用场景:
- 先在国外机器完成单机部署与联调
- 后续再扩到“国外控制面 + 大陆执行面”
- 当前暂时无法把代码真正部署到大陆机器时,先在国外机器模拟多节点联调
- 最后再把同样的部署方式复制到其他机器
一句话理解:
> 先把国外主控机部署好,再按同样套路扩第二台、第三台,不靠临场猜。
并发配置补充:
- 系统支持 `默认线程数 + 节点单独覆盖`
- 节点单独覆盖按机器自己的 `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`
推荐先执行:
```bash
dnf install -y python3.11 python3.11-devel
python3.11 --version
```
期望输出类似:
```text
Python 3.11.x
```
### 2. 目录约定
统一使用:
```text
/opt/domaincheck
├── domain-api
├── domain-web
└── domainCheck
```
### 3. 当前仓库与运行态关系
如果你像当前测试机一样,用仓库目录做源码源头,也可以用软链接:
```bash
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/` 和服务启停
第一次部署建议:
```bash
mkdir -p /www/wwwroot
cd /www/wwwroot
git clone 你的仓库地址 getDomain
cd getDomain
git checkout main
git pull origin main
```
然后建立运行目录软链接:
```bash
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
```
后续更新统一使用:
```bash
cd /www/wwwroot/getDomain
git fetch --all
git checkout main
git pull --ff-only origin main
```
### 1.1 先确认 Python 3.11 已安装
如果当前机器还没有 `python3.11`,先执行:
```bash
dnf install -y python3.11 python3.11-devel
python3.11 --version
```
只有确认 `python3.11` 命令存在后,再继续下面的虚拟环境步骤。
### 2. 创建 Python 虚拟环境
```bash
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 依赖:
```bash
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 可用。
建议先确认:
```bash
psql -h 127.0.0.1 -U postgres -d domain -c "select 1;"
redis-cli ping
```
### 4. 配置 `domainCheck/.env`
至少确认这些项:
```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. 初始化数据库
这是最重要的一步,新库必须先做:
```bash
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 地址:
```bash
cd /opt/domaincheck/domain-web
cp .env.production.example .env.production
```
`VITE_API_BASE_URL` 改成目标 API例如
```env
VITE_API_BASE_URL=https://api.domain.com/api/v1
```
然后构建:
```bash
npm install
npm run build
```
### 7. 配置 Nginx
参考:
- `domain-web/deploy/nginx/domain-web.conf`
把静态目录指到:
```text
/opt/domaincheck/domain-web/dist
```
常见做法:
- `admin.domain` 对外提供后台页面
- `api.domain.com` 对外提供 API
### 8. 安装 systemd 服务
复制模板:
```bash
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 环境变量
建议使用:
```bash
cp /opt/domaincheck/domain-api/deploy/multi-region/templates/domaincheck-api.env.example /etc/default/domaincheck-api
```
至少改这些:
```env
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
```
如果你已经固定域名,建议直接改成:
```env
CORS_ORIGINS='["https://admin.domain","http://127.0.0.1:3201","http://localhost:3201"]'
```
### 10. 修正权限
```bash
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. 启动服务
```bash
systemctl daemon-reload
systemctl enable domaincheck-api
systemctl enable domaincheck-worker
systemctl restart domaincheck-api
systemctl restart domaincheck-worker
```
### 12. 检查服务状态
```bash
systemctl status domaincheck-api --no-pager -l
systemctl status domaincheck-worker --no-pager -l
```
## 五、第一阶段验收
### 1. 接口检查
```bash
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
```bash
cd /opt/domaincheck/domain-api/deploy/linux
python3 smoke_test.py --base-url http://127.0.0.1:8100
```
如果要连 Web 一起检查:
```bash
python3 smoke_test.py --base-url http://127.0.0.1:8100 --web-url http://127.0.0.1:3201
```
期望:
- `ok=true`
### 3. 后台页面检查
浏览器打开:
```text
https://admin.domain
```
至少检查:
- 登录
- 运行中心
- 系统设置
- 域名筛选
- 导入
- 导出
## 六、第二阶段:国外机器模拟多机联调
如果你暂时还不能把代码部署到大陆机器,就先在国外机器做这一步。
### 1. 一键多机演练
```bash
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. 通过标准
如果输出里出现:
```text
rehearsal passed
```
说明当前这台国外机器上的多机模拟联调已通过,可以继续部署到其他机器。
### 3. 如果想手工模拟
也可以单独跑:
```bash
cd /opt/domaincheck/domain-api
bash deploy/multi-region/simulate_multi_region.sh http://127.0.0.1:8100
```
停止时按:
```text
Ctrl+C
```
### 4. 清理旧节点残影
如果之前测试过多轮,集群里可能残留老节点:
```bash
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
bash deploy/multi-region/prune_cluster_nodes.sh --node-code mainland-worker-01
```
## 七、第三阶段:部署到其他机器
等国外单机和模拟多机都通过后,就可以把同样的代码与脚本部署到其他机器。
### A. 新海外控制机
在目标机执行:
```bash
cd /opt/domaincheck/domain-api
bash deploy/multi-region/bootstrap_overseas.sh /opt/domaincheck
```
然后完善:
- `/etc/default/domaincheck-api`
- Nginx
- PostgreSQL
- Redis
最后检查:
```bash
bash deploy/multi-region/check_cluster.sh http://127.0.0.1:8100
```
### B. 大陆 controller
在目标机执行:
```bash
cd /opt/domaincheck/domain-api
bash deploy/multi-region/bootstrap_mainland.sh /opt/domaincheck controller
```
然后检查:
```bash
bash deploy/multi-region/check_mainland_controller.sh
```
关键配置是:
```env
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
在目标机执行:
```bash
cd /opt/domaincheck/domain-api
bash deploy/multi-region/bootstrap_mainland.sh /opt/domaincheck worker
```
关键配置是:
```env
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
每接一台都执行:
```bash
curl http://海外控制机:8100/api/v1/runtime/readiness
curl http://海外控制机:8100/api/v1/runtime/cluster
curl http://海外控制机:8100/api/v1/runtime/sync-summary
```
如果海外 API 已经挂到正式域名,建议直接写成:
```bash
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`
## 九、上线前最后检查
按这份文档部署完成后,再回看:
- [14_domainCheck_正式上线前最终检查单.md](/www/wwwroot/getDomain/docs/14_domainCheck_正式上线前最终检查单.md:1)
重点保留:
- `systemctl status`
- `journalctl`
- `/health`
- `/runtime/preflight`
- `/runtime/readiness`
- `/runtime/sync-summary`
- `smoke test`
- 诊断包
## 十、常见问题
### 1. API 启动了,但接口 500
优先检查有没有先执行:
```bash
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
bash deploy/multi-region/prune_cluster_nodes.sh --minutes 30
```
### 4. 模拟多机通过了,真实机器还没接上
这是正常的。
模拟多机的意义是:
- 验证代码、脚本、页面、状态口径一致
- 不代表真实大陆网络、代理、同步链路已经完成
真实机器接入时,重点要再看:
- 节点心跳
- 同步目标地址
- 共享 token
- 真实 Redis / PostgreSQL 连接
## 十一、最短执行版本
如果你只想看最短版,可以照这个跑:
### 国外单机先跑通
```bash
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
```
### 再跑多机模拟验收
```bash
cd /opt/domaincheck/domain-api
bash deploy/multi-region/rehearse_multi_region.sh http://127.0.0.1:8100
```
### 通过后再上其他机器
```bash
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. 最后再做真实跨地域联调
一句话总结:
> 先把单机跑稳,再把多机脚本跑通,最后再扩机器;每一步都有现成脚本,不靠现场猜。