73adad97f3
部署仓已改为开箱即用:config/ 直接是配置文件、口令等值内置在
docker-compose.yml、不再有 .env。
同步调整:
- 概览:部署流程改为 git clone + docker compose up -d 三步
- 配置说明:重写为「编排层 + 应用层」,说明为何不用环境变量
(GoFrame 不展开配置文件中的 ${VAR})、改口令需同步三处、
口令不能含 @ : / 等字符
- 启动与验证:去掉准备步骤,schema 脚本数改为 13 个
- 环境准备:镜像仓库改为描述编排文件中的实际地址
- 升级备份/离线/分离/自建镜像:.env 相关操作改为修改编排文件
244 lines
6.6 KiB
Markdown
244 lines
6.6 KiB
Markdown
---
|
||
title: 故障排查
|
||
description: 部署与运行中的常见问题及处理
|
||
outline: deep
|
||
---
|
||
|
||
# 故障排查
|
||
|
||
## 通用排查
|
||
|
||
```bash
|
||
docker compose ps # 容器状态
|
||
docker compose logs --tail=100 <服务> # 最近日志
|
||
docker compose logs -f <服务> # 跟随日志
|
||
docker compose exec <服务> sh # 进容器
|
||
```
|
||
|
||
## 启动类
|
||
|
||
### MySQL 一直不 healthy
|
||
|
||
**现象**:`iotlcm-mysql` 反复重启或一直 `starting`,其余服务不启动。
|
||
|
||
```bash
|
||
docker compose logs mysql | tail -50
|
||
```
|
||
|
||
| 日志关键词 | 原因 | 处理 |
|
||
| --- | --- | --- |
|
||
| `Access denied` | root 口令与旧数据卷不一致 | 改 `docker-compose.yml` 与卷内一致,或清空 `data/mysql` 重建 |
|
||
| `Can't create/write to file` | 目录权限 | `sudo chown -R 999:999 data/mysql` |
|
||
| `No space left on device` | 磁盘满 | 清理磁盘 |
|
||
| `Can't open shared library` | 架构不匹配 | 确认镜像与宿主机架构一致 |
|
||
|
||
### schema 初始化失败
|
||
|
||
```bash
|
||
docker compose logs mysql | grep -iE 'error' | head -30
|
||
```
|
||
|
||
| 原因 | 处理 |
|
||
| --- | --- |
|
||
| `MYSQL_APP_PASSWORD` 未设置,`04-users.sh` 退出 | 补上后清空 `data/mysql` 重建 |
|
||
| `MYSQL_ADMIN_PASSWORD` 未设置,`05-reset-passwords.sh` 退出 | 同上 |
|
||
| SQL 脚本语法问题 | 单独执行该脚本定位 |
|
||
|
||
::: warning 改脚本后必须清空数据卷
|
||
MySQL 只在 `data/mysql` 为空时执行 `schema/`,文件改了不会自动重跑:
|
||
|
||
```bash
|
||
docker compose down && sudo rm -rf ./data/mysql && docker compose up -d
|
||
```
|
||
:::
|
||
|
||
### 业务服务反复重启
|
||
|
||
```bash
|
||
docker compose logs --tail=80 admin-svr
|
||
```
|
||
|
||
| 报错 | 原因 | 处理 |
|
||
| --- | --- | --- |
|
||
| `possible config files "config" not found` | `config/` 不存在或挂载失败 | `cp -r config.example config`,确认 `config/admin-svr/config.yaml` 存在 |
|
||
| `dial tcp mysql:3306: connection refused` | MySQL 未就绪 | 等 MySQL healthy |
|
||
| `Access denied for user 'u_iotlcm'` | 应用账号口令与库内不一致 | 确认 `docker-compose.yml` 的 `MYSQL_APP_PASSWORD` 与初始化时一致 |
|
||
| `panic: unsupported provider xxx` | 通道模板与镜像版本不匹配 | 确认镜像版本与 schema 版本配套 |
|
||
|
||
## 功能类
|
||
|
||
### 登录后提示未授权 / 接口 401
|
||
|
||
**原因**:`JWT_SIGNING_KEY` 在服务间不一致。
|
||
|
||
确认 `admin-svr`、`openapi`、`app-server` 三份配置的 `jwt.signingKey` 都引用 `${JWT_SIGNING_KEY}` 且 `docker-compose.yml` 有值,然后重启:
|
||
|
||
```bash
|
||
docker compose restart admin-svr openapi app-server
|
||
```
|
||
|
||
### 登录成功但页面空白 / 菜单不显示
|
||
|
||
1. 浏览器 F12 看 Network 有无 4xx/5xx
|
||
2. 检查菜单数据:
|
||
|
||
```bash
|
||
docker compose exec mysql sh -c \
|
||
'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" db_iotlcm -e "SELECT COUNT(*) FROM sys_menu WHERE status=0;"'
|
||
```
|
||
|
||
菜单为 0 说明种子数据未导入,需重建库。
|
||
|
||
3. 检查角色菜单关联:
|
||
|
||
```bash
|
||
docker compose exec mysql sh -c \
|
||
'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" db_iotlcm -e "SELECT COUNT(*) FROM sys_role_menu;"'
|
||
```
|
||
|
||
### 卡信息页通道列空白 / 筛选无选项
|
||
|
||
**原因**:Mock 通道未插入。
|
||
|
||
```bash
|
||
docker compose exec mysql sh -c \
|
||
'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" db_iotlcm -e "SELECT channel_id, channel_name FROM t_sim_channels;"'
|
||
```
|
||
|
||
为空则手工执行种子脚本:
|
||
|
||
```bash
|
||
docker compose exec -T mysql sh -c \
|
||
'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" db_iotlcm' < schema/08-seed-mock-channel.sql
|
||
```
|
||
|
||
### 批次执行一直失败
|
||
|
||
按顺序排查:
|
||
|
||
1. **挡板是否启动**(无真实运营商时)
|
||
|
||
```bash
|
||
docker compose ps | grep onelink-mock
|
||
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/api.json
|
||
```
|
||
|
||
未启动则 `docker compose --profile with-mock up -d`。
|
||
|
||
2. **worker-svr 是否连上 RabbitMQ**
|
||
|
||
```bash
|
||
docker compose logs worker-svr | grep -i 'rabbit\|amqp' | tail -20
|
||
```
|
||
|
||
3. **upstream-chan 是否能连到上游**
|
||
|
||
```bash
|
||
docker compose logs upstream-chan --tail=50
|
||
```
|
||
|
||
4. **是否被运营商限流**
|
||
|
||
检查 worker-svr 日志中的 `rate limit`、`429`、`12021`。核对 `batch.inbound.upstreamRateLimit` 的 QPS 是否超过上游配额。
|
||
|
||
### 历史流量查询无数据
|
||
|
||
**原因**:TDengine 未配置或不可达。
|
||
|
||
```bash
|
||
docker compose logs worker-svr | grep -i 'tdengine\|taos' | tail -20
|
||
```
|
||
|
||
确认 `docker-compose.yml` 的 `TDENGINE_*` 已填,且 WebSocket 端口(默认 6041)可达。不用该功能留空即可。
|
||
|
||
### 短信发不出去
|
||
|
||
```bash
|
||
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:11190/healthz
|
||
docker compose logs sms --tail=50
|
||
```
|
||
|
||
| 报错 | 原因 |
|
||
| --- | --- |
|
||
| `InvalidAccessKeyId` | `docker-compose.yml` 中 AK 未填或错误 |
|
||
| `isv.SMS_SIGNATURE_ILLEGAL` | `signName` 与服务商审核签名不一致 |
|
||
| `isv.SMS_TEMPLATE_ILLEGAL` | 模板 ID 未审核通过 |
|
||
| `缺少 config.templateId` | 场景模板库未配置,调用方需自带 templateId |
|
||
|
||
### 图片上传失败 / 不显示
|
||
|
||
```bash
|
||
ls -la data/upload/
|
||
sudo chown -R 1000:1000 data/upload
|
||
docker compose restart admin-svr admin-ui
|
||
```
|
||
|
||
## 性能类
|
||
|
||
### CPU 被 worker-svr 打满
|
||
|
||
**原因**:定时任务开启全量同步,大量卡片并发查询上游。
|
||
|
||
1. 降低并发与限流:
|
||
|
||
```yaml
|
||
batch:
|
||
inbound:
|
||
upstreamConcurrency: 50 # 从 300 降低
|
||
upstreamBatchSize: 1
|
||
```
|
||
|
||
2. 演示 / 试用环境直接停用定时任务:
|
||
|
||
```bash
|
||
docker compose exec mysql sh -c \
|
||
'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" db_iotlcm -e "UPDATE sys_job SET status=1;"'
|
||
```
|
||
|
||
种子数据中定时任务默认已全部停用(`status=1`)。
|
||
|
||
### 磁盘持续增长
|
||
|
||
```bash
|
||
du -sh data/* | sort -rh
|
||
```
|
||
|
||
| 目录 | 处理 |
|
||
| --- | --- |
|
||
| `data/logs` | 清理旧日志,见[升级与备份](operations) |
|
||
| `data/upload` | 检查异常大的上传文件 |
|
||
| `data/mysql` | 数据库增长正常,关注 binlog |
|
||
| `data/redis` | AOF 文件,正常 |
|
||
|
||
## 网络类
|
||
|
||
### 容器间无法互访
|
||
|
||
```bash
|
||
docker network inspect iotlcm-network
|
||
docker compose exec admin-svr sh -c 'nc -zv mysql 3306'
|
||
```
|
||
|
||
配置中应使用 `mysql:3306`、`redis:6379` 这样的服务名,不要写 `127.0.0.1`。
|
||
|
||
### 宿主机访问不了 127.0.0.1 绑定的服务
|
||
|
||
`admin-svr`、`admin-ui`、`openapi`、`app-server`、`app-web`、`docs` 默认只绑 `127.0.0.1`。对外访问需:
|
||
|
||
1. 用 `--profile with-nginx` 启动反向代理,或
|
||
2. 宿主机 nginx 转发到 `127.0.0.1:<端口>`
|
||
|
||
::: danger 不要直接把端口改成 0.0.0.0
|
||
这会把管理端、数据库等内部服务暴露到公网。
|
||
:::
|
||
|
||
## 求助时提供的信息
|
||
|
||
```bash
|
||
docker compose version
|
||
docker version --format '{{.Server.Version}}'
|
||
docker compose ps
|
||
docker compose logs --tail=200 <服务名>
|
||
df -h && free -h
|
||
```
|