ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ARL灯塔部署超时:从axios到Docker/NPM/数据库的完整排查

ARL灯塔部署超时:从axios到Docker/NPM/数据库的完整排查 我先更新一下依赖缓存再把镜像源切成国内节点重新构建的时候报错依然翻来覆去就那么几行最扎眼的还是这句timeout of 12000ms exceeded。这问题在部署灯塔ARL时太典型了前端页面能起来但一调接口就等满 12 秒然后白屏或者安装阶段拉取资源直接断掉。很多人第一反应是“服务器不行”“网络不行”但其实根子往往在前端超时阈值、后端服务响应速度以及 Docker 和 npm 的源配置上。这篇文章我就把 ARL 装不上、跑不起来时遇到timeout of 12000ms exceeded的各种场景、排查方法和根治方案完整拆一遍给正在踩坑的人一个可以直接抄作业的路径。1. 先搞懂 ARL 和这个报错到底是怎么回事1.1 ARL 在安全巡检里到底扮演什么角色ARLAsset Reconnaissance Lighthouse灯塔是一款开源的资产侦察与监控系统用来做企业侧资产发现、子域名收集、端口指纹识别、Web 站点监控等。它的典型使用方式是通过 Docker Compose 一键拉起整套服务前端负责展示任务结果后端负责调度扫描任务底层依赖 MongoDB 和 Redis。部署起来以后日常操作基本就是“添加目标 → 下发任务 → 查看结果”。很多安全团队的日常巡检、SaaS 资产梳理、攻防演练前的资产摸底都会用到它。它的价值在于把分散的测绘能力整合在一个界面里既能做被动信息收集也能联动主动扫描。但它的部署体验并不是零门槛尤其是网络环境不太好时装到一半就报错的情况非常常见。而timeout of 12000ms exceeded正是大家最常撞上的那堵墙。1.2 timeout of 12000ms exceeded 是谁报出来的这句话本身是 axios 的默认超时提示。ARL 的前端页面使用 Vue 生态开发HTTP 请求库就是 axios。当前端调用后端接口时如果 12 秒内没有收到响应axios 就会主动中断请求并在浏览器控制台打印timeout of 12000ms exceeded。它不代表后端程序一定崩溃了只代表“在这段时间内后端没能把处理结果交回给前端”。这个 12 秒不是 ARL 开发者随意定的而是 axios 里timeout参数的一个常见默认值。很多项目图省事直接不配置或者写死在代码里。ARL 的一些接口在处理大量资产数据、调用第三方测绘平台 API、执行复杂的 MongoDB 聚合查询时很容易超过这个阈值。于是你看到的现象就是页面能打开但“添加任务”“查看详情”“同步数据”这些操作频繁转圈最后报超时。1.3 什么场景下最容易触发这个超时结合我自己和身边朋友的实际部署经历最容易报这个错的场景有三类。第一类是安装部署阶段的“假超时”。比如docker pull拉镜像时网络慢或者npm install安装前端依赖时下载卡住某些命令会在超时后直接中断返回类似 timeout 的报错。虽然不完全等同于 axios 的 12000ms 提示但都指向同一个根源资源下载与依赖获取环节耗时过长。第二类是服务刚启动完MongoDB 和 Redis 还没准备好后端接口首次调用极慢前端等不到响应就报超时。这种在低配服务器1 核 2G上尤其明显启动容器后马上打开页面操作十有八九超时。第三类是扫描结果数据量变大以后某些列表页或统计接口要聚合大量数据MongoDB 查询没走索引后端响应超过 12 秒前端又开始报错。不同场景的解决办法不一样但它们之间有很强的关联性。要彻底解决必须从前端配置、后端性能、基础依赖三个层面一起调整缺一个都容易反复踩坑。2. 安装部署阶段的原因分析与临时规避手段2.1 Docker 部署前先把环境底子打牢ARL 官方推荐用 Docker Compose 部署所以 Docker 和 Docker Compose 的安装是第一关。很多人在这里就开始出问题比如 Docker 服务没起来、Compose 版本太老、容器之间网络不通。这里我建议先确认最基础的三件事Docker 版本不低于 20.10Docker Compose 版本不低于 1.29服务器的 CPU 和内存至少 2 核 4G。这几个要求看着简单但确实卡住过不少人。版本太老会导致某些镜像的启动参数不被识别内存太小会导致容器启动后被杀掉表现就是前端页面加载到一半就没反应。曾有朋友在 1 核 1G 的机器上装 ARL启动后前端能打开一点任务列表就卡死查看 Docker 日志发现 MongoDB 反复被杀进程重启。这就是资源不足引起的连锁反应从表面看也是“请求超时”但本质是后端服务根本没稳定运行。安装完 Docker 后最好先验证一下 Docker 是否能正常拉取镜像、运行 hello-world 容器。这一步能排除大部分环境问题避免后面排查时绕远路。2.2 镜像拉取慢的直接处理方式ARL 的 Docker 镜像托管在 Docker Hub国内网络环境拉取时经常出现连接超时、下载中断。你看到的报错可能是net/http: TLS handshake timeout也可能是dial tcp ... i/o timeout虽然文案不是 12000ms但问题本质一样。解决办法是给 Docker 配置镜像加速器。用 Linux 服务器的话编辑/etc/docker/daemon.json填上 registry-mirrors然后重启 Docker{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com ] }sudo systemctl daemon-reload sudo systemctl restart docker配置完成后先用docker info查看 Registry Mirrors 是否生效再重新拉取 ARL 相关镜像。注意网上很多镜像加速地址会不定期调整要是失效了就换一个可用的或者找云厂商提供的加速器地址。实操的小体会是不要只配一个加速地址多填两三个Docker 会按顺序尝试有备无患。还有如果服务器能访问外网但速度很慢也可以考虑在低峰期拉镜像比如凌晨时段会快很多。拉取完成后把镜像保存成本地 tar 包以后在局域网环境部署就能直接导入不用再受网络波动的影响。2.3 npm install 超时的处理除了 Docker 镜像ARL 前端依赖安装也是超时重灾区。前端构建时需要从 npm 官方仓库下载大量包网络波动时很容易卡住。如果你是从源码构建而不是直接用官方镜像遇到npm install卡死或超时要优先切换 npm 源到国内镜像npm config set registry https://registry.npmmirror.com然后删除 node_modules 和 package-lock.json 重新安装rm -rf node_modules package-lock.json npm install --registryhttps://registry.npmmirror.com也可以给 npm 单独加超时时间避免默认配置太短导致误判npm config set fetch-timeout 600000 npm config set fetch-retries 5这里的逻辑是npm 默认的网络超时和重试策略在某些网络环境下过于保守稍微慢一点就断掉。调大超时上限、增加重试次数之后大多数情况都能顺利装完。2.4 安装阶段的“假超时”别硬等如果安装脚本卡在某个步骤超过几分钟不要一味等待先判断是假死还是真慢。最简单的验证方式是用docker ps查看容器状态或者用docker logs看当前容器输出。如果容器状态一直在 restarting说明启动失败等再久也没用。另外Cloning 仓库时如果中途出现stream disconnected before completion之类的提示也说明数据流被中断了。这时建议手动清理一下未完成的下载缓存然后重试。比如 Git 仓库克隆到一半断了可以先删掉目录再重新 cloneDocker 层缓存出错时可以执行docker system prune清理。我自己的习惯是部署新服务时先跑一遍官方脚本但如果发现脚本里有“下载依赖”和“构建镜像”这种容易超时的环节我会拆出来分步执行。这样哪个环节断了直接处理哪个环节比反复跑整套脚本效率高得多。3. 跑起来以后还超时的根治方案3.1 定位真正慢的接口安装阶段的问题处理完毕ARL 能正常启动但使用中依然出现timeout of 12000ms exceeded那就必须进入接口层面排查了。第一步是打开浏览器开发者工具切到 Network 面板刷新页面触发一次报错观察到底哪个请求超时。重点关注状态列为 pending 的请求这些就是超过 12 秒还没返回的接口。通常最容易出问题的集中在/api/asset/、/api/task/、/api/statistics/这些数据聚合类接口。它们背后往往牵扯多张表的关联查询还可能在实时调用外部测绘平台的数据。举个例子你在首页看统计图表时前端会请求一个聚合接口后端需要从 MongoDB 里统计任务总数、资产总数、今日新增资产。数据量小的时候响应很快但资产表过百万行以后如果 status 字段、date 字段没加索引MongoDB 就可能做全表扫描响应时间直线上升。定位到具体接口后去后端容器里查日志docker logs arl-mongodb --tail 200或者看后端容器的日志找到对应接口的响应时长。很多响应慢都有规律比如第一次请求慢、后续请求快那是缓存没命中每次请求都慢那是查询语句或索引问题。3.2 调大前端 axios 超时阈值如果确认接口本身业务逻辑比较复杂短时间内优化不动可以先临时调大前端 axios 的超时时间让前端不再 12 秒就中断请求。ARL 前端源码中axios 实例一般在src/utils/request.js或类似位置。找到 axios.create 的部分把 timeout 从 12000 改成 60000 甚至 120000import axios from axios const service axios.create({ baseURL: /api, timeout: 60000 // 原来是 12000改大后给后端更充裕的处理时间 })如果你用的是官方 Docker 镜像而不是源码构建没法直接改前端文件那就得换一种思路在 Nginx 反向代理层调整超时时间。ARL 的端口映射最终是 Nginx 对外提供服务Nginx 本身也有代理超时限制。在 nginx 配置文件里给 location 加上 proxy_read_timeoutlocation / { proxy_read_timeout 60s; proxy_send_timeout 60s; proxy_connect_timeout 30s; }这种方式不需要重新编译前端只需要改容器内的 Nginx 配置或者挂载自定义配置。扩容超时时间属于“治标”手段能让你先用起来但不要指望改大了就万事大吉。真正要做的还是优化后端响应。3.3 优化后端与数据库解决慢的根本后端慢的常见原因有三个容器资源受限、MongoDB 查询慢、Redis 没有合理利用。容器资源受限方面要检查一下 Compose 文件里有没有给服务配置 mem_limit、cpu_limit。如果资源限制太小后端处理并发请求时就会频繁 GC导致接口超时。建议把资源限制调大或者在测试环境直接去掉限制。MongoDB 查询慢的话最直接的优化是建立索引。比如查询资产列表时会按domain、create_date排序就针对这些字段建索引db.asset.createIndex({ domain: 1 }) db.asset.createIndex({ create_date: -1 }) db.asset.createIndex({ source: 1, create_date: -1 })用 explain 分析慢查询db.asset.find({ source: fofa }).sort({ create_date: -1 }).explain(executionStats)看executionTimeMillis和totalDocsExamined如果扫描的行数远大于返回行数说明索引没有命中。Redis 方面ARL 用 Redis 做缓存和任务队列。检查 Redis 是否有持久化策略、是否设置了内存淘汰策略。如果 Redis 内存满了写入可能会阻塞间接拖慢接口。3.4 外部数据源调用慢怎么处理ARL 会集成 FOFA、Quake、Hunter 等网络空间测绘平台的数据这些外部 API 调用也是超时的常见来源。具体表现是点“同步接口数据”或“导入测绘数据”时长时间无响应最后超时。这类接口慢不一定是 ARL 本身问题而是第三方平台 API 响应慢或者你的网络到第三方平台不够通畅。处理办法是在 ARL 的管理后台里检查第三方平台的 API 配置是否正确如果不需要这些数据源可以先禁用掉避免每次扫描都卡在外部调用上。如果你确实需要外部数据源可以考虑用定时任务预取数据再导入到本地而不是在用户操作时实时同步。这样即使第三方平台响应慢也不影响前端交互体验。3.5 验证调整是否生效改完配置后不要直接关掉控制台就算完。需要完整验证一遍重启相关容器刷新页面再次触发之前超时的接口看 Network 面板里的 Time 是否明显下降页面是否不再报错。如果改了源码并重新构建了前端镜像记得把新镜像重新打 tag并让 Docker Compose 使用新镜像启动docker-compose down docker-compose up -d如果只改了 Nginx 配置执行docker exec进入容器重载 Nginxdocker exec -it arl-nginx nginx -s reload验证超时配置是否生效的最快方法是故意触发一个慢接口看请求是否还能在 12 秒内被中断。如果在 Network 面板里看到请求等待时间超过 12 秒仍未中断说明新的超时阈值已生效。4. 常见问题排查与避坑技巧实录4.1 重启后又变回原样配置没保住这个问题很常见。很多人改完容器里的配置后直接 docker-compose restart发现重启完配置又变回去了。原因是容器本身是临时的修改写在容器可写层里Compose 重建容器时会拋弃这些改动。解决办法是把自定义配置通过 volume 挂载进去。比如 Nginx 配置在 docker-compose.yml 里把宿主机上的配置目录映射到容器内services: nginx: image: arl_nginx:latest volumes: - ./nginx/conf.d:/etc/nginx/conf.d同理MongoDB 的数据也要挂载到宿主机防止容器重建后数据丢失。这些配置在第一次部署时就应该规划好否则后面每次调整都会重复踩坑。4.2 stream disconnected before completion 与超时是什么关系这是个在安装和运行阶段都可能出现的报错。它的含义是HTTP 流式响应在完成之前连接被断开。对比 axios 的 timeout它更像是服务端主动关闭连接或者中间的代理设备断开了连接。如果是在下载镜像或克隆代码时出现通常是网络层的连接被重置。解决办法和前面类似换源、提速、重试。如果是在网页访问时出现通常是 Nginx 的 proxy_buffering 或 proxy_read_timeout 设置不合理。可以关闭 Nginx 的代理缓冲或者调大超时location / { proxy_buffering off; proxy_read_timeout 300s; }stream disconnected这类问题有时候会和idle timeout waiting for sse一起出现后者常见于需要 Server-Sent Events 的长连接场景。ARL 中如果有实时推送任务进度的功能Nginx 默认的空闲超时可能导致 SSE 连接中断。解决办法是在 Nginx 代理配置中加上proxy_set_header Connection ; proxy_http_version 1.1; proxy_buffering off; proxy_read_timeout 3600s;4.3 日志里看不到明显异常页面却一直超时这种情况往往不是后端程序报错而是数据库锁等待、连接数耗尽或 DNS 解析慢。你先检查 MongoDB 的连接数docker exec -it arl-mongodb mongosh --eval db.serverStatus().connections如果连接数接近上限要把连接池调大或者排查是否有慢查询占住了连接。Redis 也可能出现连接数打满的情况看info clients的输出。还有一种隐蔽情况DNS 解析慢。当后端需要查询外部域名时如果服务器的 DNS 解析不稳定每个请求都可能卡在解析阶段。这时可以在容器里手动指定 DNS 服务器或者在 docker-compose.yml 中配置 dnsservices: worker: dns: - 223.5.5.5 - 114.114.114.114这里的思路是把每一步都量化。不要只看“页面超时”要一层层拆是 DNS 慢、TCP 连接慢、还是响应体生成慢。前端 Network 面板能告诉你是 Waiting 时间过长还是 Content Download 时间过长这两个阶段对应的排查方向完全不同。4.4 完整解决路径速查表我把整个排查和解决路径整理成一份速查表方便你对照操作阶段症状可能原因解决动作安装部署docker pull 超时/中断Docker Hub 网络不通畅配置镜像加速器多地址备用安装部署npm install 卡死npm 官方源访问慢切换 npmmirror 源调大 fetch-timeout安装部署git clone 中断网络连接被重置清缓存重试或下载压缩包解压启动运行页面可开接口超时后端容器资源不足调大内存/CPU限制确保 2核4G 以上启动运行首次访问超时后面正常数据库未初始化完成启动后等 1-2 分钟再访问使用过程列表页接口超时MongoDB 缺少索引针对查询字段建索引使用过程接口全超时连接数被打满检查 Mongo/Redis 连接数调连接池使用过程同步外部数据超时第三方 API 慢禁用或定时预取数据使用过程前端 12 秒中断axios timeout 过短改源码或 Nginx 超时阈值这张表是我在多次部署 ARL 的过程中总结出来的覆盖了绝大多数超时场景。遇到问题先按阶段归类再对症处理不要一上来就重装系统或换服务器。5. 部署与调优后的一些个人体会那台一开始频繁报超时的服务器在加了镜像加速、调大前端超时阈值、给 MongoDB 建好索引之后用起来已经非常丝滑了。整个过程里我最大的感受是timeout of 12000ms exceeded这个报错本身并不难解决难的是很多人不知道这个 12 秒是 axios 的默认值于是到处怀疑代码有问题甚至反复重建容器结果越搞越乱。如果你是第一次装 ARL提前把这些超时相关的配置都调整好再去跑可以少走很多弯路。在网上搜索 ARL 部署问题时也经常能看到有人推荐改核心代码、替换组件甚至换操作系统其实多数时候没那个必要。先确认基础环境没问题再考虑调参最后再动代码这个顺序不要颠倒了。还有一点想强调调大超时时间只是缓解手段最好还是要弄清楚后端为什么慢。如果是因为机器配置太差那就升配置或减少并发任务如果是因为数据库没建索引那就老老实实建索引如果是因为外部数据源慢那就把同步逻辑异步化。否则你今天把超时调到 60 秒明天数据量涨上来接口响应变成 80 秒还是会继续报错。ARL 本身是个很实用的系统部署和调优并没有想象中那么复杂。把这些超时问题处理干净之后后续用起来会顺手很多。如果你后续在资产发现、任务调度或者数据展示上遇到其他问题也可以沿着“先定位、再调参、再优化”的思路继续排查大部分坑都能自己踩平。
返回列表