Files
openwrt-build-helper/reports/2026-10-30-cudy-tr3000-adguardhome-memory.md

129 lines
6.1 KiB
Markdown
Raw 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.

# Cudy TR3000:AdGuard Home 查询日志占满内存、限流过严
- 日期:2026-10-30
- 设备:Cudy TR3000 256MB v1(`cudy-tr3000.tail694d4.ts.net`,远程)
- 系统:OpenWrt 25.12.6 r33311-981c978eff,mediatek/filogic
- AdGuard Home:0.107.79
- 相关报告:[`2026-10-28-cudy-tr3000-wwan-watchdog.md`](2026-10-28-cudy-tr3000-wwan-watchdog.md)
## 背景
反馈“AdGuard DNS 好像崩溃了”。排查时 AdGuard Home 进程正常运行,路由器上解析也正常,但发现两个会导致 DNS 不稳定甚至整机卡死的问题:
1. 查询日志写在内存里(tmpfs),6.5 小时涨到 112 MB,可用内存只剩约 20 MB。
2. 限流 `ratelimit: 20` 按网段计算,所有局域网设备共用一个额度,高峰期已超过上限。
## 现象
| 时间 | 可用内存 | `querylog.json` | 说明 |
|---|---|---|---|
| 17:31 | 86 MB | 112 MB | 开机 6.5 小时,负载约 2.9 |
| 17:53 | 20 MB | 121 MB | |
| 17:54 – 17:56 | — | 122 MB | SSH 和 Tailscale ping 均超时约 1 分钟,负载升到 9.9;没有重启 |
| 17:57(修复后) | 234 MB | 0.2 MB | `/tmp` 从 135 MB 降到 5.4 MB |
开机后的 6.5 小时里路由器重启过一次,原因查不到:没有 pstore,当前日志中也没有 OOM 记录。按查询日志的增长速度,内存迟早会被耗尽,那次重启很可能就是这个原因,但没有证据。
17:54 的卡顿还有一个人为因素:排查时一条 `tail -20000 querylog.json` 命令超时被中断,但路由器上的 `tail` 进程没有退出,一直以 R 状态占用 CPU。它还持有已删除的 `querylog.json`,导致删除后约 112 MB 内存迟迟没有释放。手动 `kill` 后内存才回来。以后在路由器上分析大文件,要先复制一小段出来再处理,并确认远端进程已退出。
## 原因
### 1. 查询日志:几乎都是 EasyTier 解析对端域名
开机至 17:30 共 166000 条查询:
| 域名 | 次数 |
|---|---|
| `cloud.zhe-yuan.top` | 119301 |
| `home.zhe-yuan.top` | 18438 |
| `backup.zhe-yuan.top` | 16155 |
| 其他所有域名 | 约 12100 |
| 客户端 | 次数 | 设备 |
|---|---|---|
| `fd84:1963:e466::7c3` | 100529 | intel-nuc8i5beh |
| `127.0.0.1` / `::1` | 29596 / 29520 | 路由器自身 |
| `fd84:…:ec56:…` | 6148 | Windows-Dev-Kit |
| `fd84:…:ed94:…` | 207 | Galaxy-Z-Fold8 |
这三个域名正是 EasyTier 的对端地址(`/etc/easytier/config.toml` 的 `[[peer]]`)。`easytier-cli connector` 显示这些连接器一直处于 `Connecting`,每次重试都会重新解析域名。NUC 上的 EasyTier 应该也是同样情况。
上游 TTL 正常(`cloud` 约 300 s,`home` 约 250 s),AdGuard 都是从缓存回答,所以对上游没有压力。问题在于每条查询都写进了日志:
- `querylog.interval: 90d`:查询日志保留 90 天,实际上不会轮转。
- 日志目录在 `/var/lib/adguardhome`,也就是 tmpfs(内存)。
- 每条记录约 700 字节(包含完整的 base64 应答)。
平均每秒约 7 条,每小时约 17 MB。
### 2. 限流:所有局域网客户端共用一个额度
```yaml
ratelimit: 20
ratelimit_subnet_len_ipv4: 24
ratelimit_subnet_len_ipv6: 56
```
限流按 IPv4 /24 或 IPv6 /56 计算,整个局域网(`192.168.156.0/24`、`fd84:1963:e466::/48` 内的 /56)只有每秒 20 次的共用额度。抽样的 3000 条记录里,局域网客户端的高峰是每秒 24 次,主要来自 NUC 的 EasyTier 解析。被限流的查询直接丢弃且不写日志,其他设备会偶尔解析失败而查不到记录。
## 修改内容
备份:`/root/adguardhome.yaml.bak`
`/etc/adguardhome/adguardhome.yaml`:
```diff
dns:
- ratelimit: 20
+ ratelimit: 0
querylog:
- ignored: []
- interval: 90d
+ ignored:
+ - cloud.zhe-yuan.top
+ - home.zhe-yuan.top
+ - backup.zhe-yuan.top
+ interval: 6h
- ignored_enabled: false
+ ignored_enabled: true
```
另外停止 AdGuard Home 后删除了旧的 `querylog.json`,然后重启服务。
- **`interval: 6h`**:AdGuard Home 轮转时保留 `querylog.json` 和 `querylog.json.1` 两个文件,最多约 12 小时的记录。去掉 EasyTier 的查询后,每 6.5 小时约 12000 条、约 9 MB,最坏情况约 20 MB。
- **忽略三个 EasyTier 对端域名**:只是不写入查询日志,统计和解析不受影响。
- **`ratelimit: 0`**:关闭限流。防火墙 `wan` 区(`wan`、`wan6`、`wwan2`、`wwan5`、`wwan26`、`wwan56`)的入站是 `REJECT`,外网访问不到 53 端口;能访问的只有 `lan` 和 `meshvpn`(Tailscale、ZeroTier),都是自己的设备。
`/etc/adguardhome/adguardhome.yaml` 在软件包的 conffiles 里,sysupgrade 会保留,不需要加进 `/etc/sysupgrade.conf`。
## 验证
```
$ nslookup example.com 127.0.0.1
Address: 104.20.23.154
$ nslookup google.com 192.168.156.65
Address: 2607:f8b0:4009:812::200e
$ df -h /tmp
tmpfs 242.7M 5.4M 237.3M 2% /tmp
$ free
Mem: total 497044 used 207988 free 216488 shared 5568 available 233988
```
AdGuard Home 重启后约 15 秒才开始监听 53 端口(当时负载较高),这期间 DNS 不可用。
## 未处理
- **EasyTier 连接器反复重连**:路由器和 NUC 上的 EasyTier 一直在重试连接 `wss://*.zhe-yuan.top:0/easytier/` 等对端,持续占用 CPU(`easytier-core` 约 30%)。组网本身可用(各对端都已 p2p 直连),所以这次只是不记日志,没有改 EasyTier。后续可以查一下这几个对端为什么连不上。
- **iPad 显示“无互联网连接”**:iPad 能正常关联(-44 dBm,HE-MCS 11)、拿到 DHCP(换了私有地址后是 `192.168.156.123`),路由器也能 ping 通它。但在观察的时间里,conntrack 里没有它发起的任何连接,也没有 DNS 查询,nft 计数 20 秒内只有 7 个包。也就是说 iPad 没有在尝试上网,原因还没查清,不确定和本次问题有关。需要在 iPad 上实际打开网页时同步抓包,并检查是否有 VPN、DNS 描述文件或 iCloud 专用代理。
## 回滚
```sh
/etc/init.d/adguardhome stop
cp /root/adguardhome.yaml.bak /etc/adguardhome/adguardhome.yaml
/etc/init.d/adguardhome start
```