ARTICLE DETAIL

资讯详情

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

代码地图工具Archify:从代码仓库自动生成架构图实战

代码地图工具Archify:从代码仓库自动生成架构图实战 接手一个别人留下的老项目最让人头皮发麻的事情是什么不是代码报错不是文档缺失而是打开仓库发现几千个文件像撒了一地的拼图你却连一张“整体长什么样”的图都没有。这个场景我经历过太多次直到团队里有人开始用代码地图Archify——一个能从代码仓库秒生架构图的工具直接把仓库里的模块关系、服务依赖、调用链路自动变成一张清晰的地图。今天我把这段时间的实操经验整理出来从原理到命令从坑点到技巧一次性说透。1. 先聊清楚代码地图Archify到底解决什么问题1.1 接手陌生代码仓库为什么比写代码还痛苦先描述一个很多人都有过的状态入职第二天leader 丢给你一个仓库地址说“你先熟悉一下”。你git clone下来打开项目目录看到十几层嵌套的文件夹几十个模块密密麻麻的类文件一瞬间不知道从哪里开始读。更现实的是代码仓库里通常没有一份能用的架构设计文档——就算有也大概率是两三年前画的和当前代码结构已经对不上号了。这就像你搬到一个新城市手里只有一本过期地图上面标注的街道一半已经改了名。你只能靠一条条街去走、去问、去试错。读代码也是这样没有全局视图时只能顺着调用关系一层层往下追刚弄清 A 模块调了 B又要去查 B 调了 C、D、E追到后面连自己当初为什么要查这条链路都忘了。这种痛苦的本质是代码仓库里存储的是“怎么做”的细节而不是“是什么”的结构。模块之间的边界、服务之间的依赖、核心业务在哪个包底下这些属于架构层级的信息在源码里分散得极其隐蔽靠人肉梳理效率低到令人绝望。因此当有人告诉我有个叫 Archify 的工具能自动从代码仓库生成架构图时我的第一反应是这种东西早该有了。1.2 Archify 的核心思路把“依赖关系”变成一张地图Archify 做的事情简单说就是三步扫描代码仓库解析文件之间的依赖关系再把依赖关系渲染成架构图。它不是画图软件而是“读懂代码结构之后再自动出图”的工具。它读取的是代码仓库里的静态信息通过解析语法结构、import 语句、函数调用、接口实现、配置注入等关系把代码组织成“节点”和“连线”。节点可以是包、模块、服务或类连线表示它们之间的依赖、调用或继承关系。之后再按照架构的层次逻辑做聚合把同属一个业务域的文件折叠成一个大节点把中间件调用单独聚成一组最终输出一张层次分明、方向明确的架构图。这里有一个关键概念静态分析。它不需要把项目跑起来不需要连数据库也不需要模拟请求而是直接读源码文本生成抽象语法树再从语法树中抽取出依赖信息。正因如此它的速度非常快——一个几万文件的仓库通常几十秒就能完成扫描和关系抽取真正做到了“秒生架构图”的效果。这种处理思路的意义还在于它不依赖于代码是否“能运行”。很多老项目你根本跑不起来环境变量缺失、依赖包版本冲突、数据库连不上但这不妨碍 Archify 分析它的代码结构。只要源码文件是完整的它就能画出架构图。这比那些要求“先启动应用再采集调用链”的方案实用太多。1.3 这活儿适合谁干Archify 不是给某一类人准备的。新入职的工程师可以用它快速了解仓库全局找到业务入口减少“瞎转悠”的时间资深开发在做技术改造前用它做存量系统的依赖梳理搞清楚哪些模块是核心、哪些可以拆分架构师做评审时可以拿它生成的依赖图做佐证比 PPT 里手画的架构图更有说服力就算是在离职交接前把它生成的架构图放进交接文档也能省掉大量口述解释。我自己最常用它的场景是清理技术债。之前有个支付相关的服务模块大家讨论了好几次要不要拆但谁也说不出这个模块到底依赖了多少外部服务、内部耦合有多严重。后来我用 Archify 扫描了一遍把生成的架构图打印出来贴在白板上所有的依赖关系一目了然——连它偷偷反向依赖了一个本该下沉的基础库都被标了出来。这件事让我确信这类工具应该成为开发者的标配。2. 动手前的准备仓库接入与工具选型思考2.1 能扫描哪些代码仓库先确认一个问题Archify 能对接哪些代码仓库根据我目前的使用经验它支持本地目录扫描也支持通过 Git 协议拉取远程仓库。也就是说你本地已经克隆好的项目可以直接指定路径扫描如果项目在 GitLab、GitHub 或者 Gitee 上也可以直接填远程地址它会自动拉取到临时目录再分析。语言支持方面主流的 Java、Python、Go、JavaScript/TypeScript、C、PHP、Ruby 都没有问题。多语言混合的仓库也能处理只不过在聚合层会按语言分开统计模块依赖。这对很多团队来说是刚需——现实中的微服务仓库往往是 Java 写业务、Go 写中间件、前端再塞一个子目录能在一个仓库里统一扫描出整体架构图省事不少。这里顺带说一个相关场景。很多人会用 Gitee 或者 GitLab 管理代码比如把本地代码上传到 Gitee 仓库、在 GitLab 上统计仓库代码量和注释率。这些操作解决的是“代码存在哪、代码有多少”的问题而 Archify 解决的是“代码结构长什么样”的问题。两者配合起来才有完整的仓库健康度视图。2.2 使用 Docker 安装与基础配置我推荐用 Docker 方式安装 Archify原因很简单它省掉了语言运行环境的配置麻烦。这个工具有一定体积内部需要跑多语言解析器如果你的机器上正好缺某个语言的运行时裸机安装很容易中途报错。而官方镜像已经把环境全部打包好了拉下来就能用。安装命令大概是这样的docker pull archify/archify:latest运行的时候我习惯于把数据目录挂载出来这样扫描结果和缓存可以持久化保存。基础命令类似于docker run --rm -v $(pwd):/workspace archify/archify analyze --path /workspace/my-repo --format json --output /workspace/archify-output第一次跑之前建议先在工作目录里生成一份配置文件archify.yml把常用的排除规则和聚合规则写进去。下面是一个最小配置示例project: name: my-service language: java scan: exclude: - **/test/** - **/generated/** - **/target/** branch: main render: theme: light show-details: module-level group-by: package这份配置解决了我之前很头疼的两个问题一是测试代码和自动生成代码会大量增加无效连线必须排除二是默认的类级视图噪声太多直接改成模块级视图图面干净得多。2.3 也有不用 Docker 的裸机玩法如果你的机器环境刚好比较干净或者你需要在某些不能跑 Docker 的 CI 机器上用也可以直接下载编译好的二进制。以 Linux 为例解压后执行./archify version能确认安装是否成功。一般情况下裸机安装需要额外检查三样东西Java 版本如果扫描的仓库包含 Java、Node 版本扫描前端项目时需要、系统是否安装了 Graphviz用于部分依赖图的布局计算。我遇到过在裸机上扫描 TS 项目时因为 Node 版本过低导致解析失败的情况。所以现在我的原则是个人电脑上实验可以直接用 Docker需要在生产 CI 里用的时候再单独准备裸机环境并且一定是固定版本、固定依赖的干净镜像。这样既能灵活调试又能保证结果可复现。注意无论用哪种方式安装都建议把版本固定下来。Archify 的更新频率不低不同版本生成的依赖结构可能有细微差异团队协作时如果各用各的版本对比结果会互相干扰。3. 实操全流程从仓库到架构图的完整链路3.1 第一步准备一个干净的仓库快照开始之前先准备一个干净的仓库。我的习惯是单独建一个目录做浅克隆只拉取默认分支的代码避免本地未提交的改动污染扫描结果。浅克隆还能省时间尤其对大仓库来说全量克隆可能要好几分钟而浅克隆只要几秒。git clone --depth 1 --branch main gitgitlab.com:your-org/service-catalog.git archify-scan如果你要扫描的仓库带有子模块记得在克隆之后执行git submodule update --init --recursive否则子模块目录是空的Archify 会漏掉这部分依赖关系。这一步看起来简单但有个小坑有些团队的仓库分支命名不统一有人推main有人还在用master。克隆前先确认目标分支是谁免得拉下来一个长年没人维护的旧分支生成的架构图不具有参考价值。3.2 第二步执行扫描拿到依赖数据仓库准备好之后执行扫描。这里我会先用 JSON 格式输出原始依赖数据确认数据没问題再生成图片。命令形如archify analyze --path ./archify-scan --config archify.yml --format json --output ./scan-result.json扫描过程中的输出会比较详细包括“解析文件总数”“识别类数”“构建依赖边数”等统计信息。看到这些数字时不要只扫一眼就过去——它们本身就是很有价值的仓库规模指标。比如一个模块文件数不多但依赖边数特别高说明它和其他模块耦合很深这通常是个预警信号。scan-result.json里的核心结构是节点和边。节点信息包括名称、类型module/package/class/service、所属分组边信息包括源节点、目标节点、依赖类型import/call/inherit/bean-ref。我建议在这个阶段花点时间看一眼数据的完整性{ nodes: [ {id: payment-service, type: service, group: core}, {id: account-service, type: service, group: core} ], edges: [ {from: payment-service, to: account-service, type: call} ] }如果 JSON 里只有少量节点先检查是不是配置的排除规则写得太激进把正常代码也过滤掉了。这个阶段发现问题比生成完架构图再发现问题要快得多。3.3 第三步生成架构图并导出确认依赖数据无误后就可以生成架构图了。我一般会输出两种格式SVG 用于文档展示HTML 用于交互式查看。命令如下archify graph --input ./scan-result.json --format svg --output ./architecture.svg archify graph --input ./scan-result.json --format html --output ./architecture.html这种方式很像很多办公场景里“根据 Excel 文件生成组织架构图”的做法——数据是核心绘图是附带操作。你不需要手工拉线、调布局、对齐节点只要数据正确剩下的排版交给工具自动完成。Archify 生成的 HTML 图可以直接在浏览器里缩放、点击节点查看详情比静态图片实用很多。另外Archify 支持导出 Mermaid 和 PlantUML 格式。这是一个很贴心的设计因为很多团队的文档站只认 Mermaid 代码块你可以直接把导出的.mmd文件贴进 Markdown实现“代码即文档”的体验。3.4 第四步把架构图跑进团队日常流程工具只有被日常使用价值才真正释放出来。我见过一个团队的做法是在 GitLab CI 里加一个定时任务每天凌晨自动扫描主干分支生成架构快照然后以评论形式更新到 Merge Request 里任何人在改动依赖关系时都能直观看到架构图的变化。简单来说就是用一条 CI 流水线取代手工执行。GitLab CI 的配置片段大致长这样archify-scan: image: archify/archify:latest script: - archify analyze --path . --config archify.yml --format json --output scan-result.json - archify graph --input scan-result.json --format svg --output architecture.svg - archify graph --input scan-result.json --format html --output architecture.html artifacts: paths: - architecture.svg - architecture.html跑起来之后你会发现架构图的更新频率从“想起来才更新”变成了“每天自动更新”这比任何强制文档规范都有效。毕竟图的产生不再依赖人的自觉而是流水线里的一个环节。提示在 CI 里跑扫描时尽量复用浅克隆也就是只在流水线里拉取当前分支的最新代码不要拉全量历史。这样既能加快扫描速度也能避免分析到已废弃的历史分支。4. 实战效果细节与可视化结果解读4.1 如何读懂生成的“代码地图”得到一个架构图之后真正的重头戏是读图。很多人第一次看到 Archify 生成的图时会觉得线条太多、颜色太杂无从下手。其实它有规律可循节点颜色通常代表模块分层冷色系是基础能力层暖色系是业务应用层连线越密集的地方耦合度越高箭头指向的汇聚点就是被大量依赖的核心模块。我会按三个步骤去看一张图。首先找“被依赖最多”的节点——这些节点往往是基础设施、公共库或核心领域模块如果它们被很多业务模块直接依赖说明分层还算健康但也可能意味着公共层太厚。其次找“环状依赖”结构——在服务之间互相调用的闭环这种循环依赖是重构的重点目标。最后看边界——按聚合分组之后的模块边界看看是否存在一个模块里的内容散落在图的不同角落如果有说明模块划分逻辑已经和代码实际结构脱节了。这种地图还有一个妙用识别“上帝服务”。上帝服务是指那些被大量模块依赖、同时也依赖大量模块的巨型节点。图上一眼就能看出来因为它的连线几乎覆盖半个图面。面对这种服务任何微调都要格外小心因为它牵一发动全身。新版 Archify 在 HTML 视图里支持点击节点高亮关联边我经常通过这个功能快速排查一次改动可能会影响的面。4.2 结合代码量与注释率统计做“复盘校准”只有架构图还不够我在评估仓库健康度时会把它和代码量、注释率这两个指标叠加来看。很多团队在 GitLab 上做过仓库代码量和注释率统计能得出一个系统“有多少行代码、注释占比多少、哪个目录代码增长最快”的汇总。如果把这两个维度和 Archify 生成的架构图结合起来能发现不少有意思的现象。比如某个模块依赖关系并不复杂但代码量却异常庞大大概率是里面堆了大量重复代码另一个模块注释率极低且被依赖方很多说明它是一个“高风险核心点”——人人都离不开它但读它代码的人都得靠猜。这种交叉分析比单看任何一类指标都更有说服力。我自己的实践是在每次大版本评审前把架构图和代码统计报告放在一起过一遍。先看代码量增长趋势再看依赖图关键节点是否有新增连线两者相互印证基本能判断出哪些模块需要优先重构。4.3 微服务架构图绘制的三个微调技巧如果你要画的是微服务架构图直接用默认配置往往会得到一张“毛线球”。这是因为类级别的依赖关系在图里全部展开太多细节反而掩盖了服务间的真实关系。我总结了三个微调技巧可以显著提升图的可用性。第一把展示层级从“类级”提升到“服务级”或“模块级”。对微服务来说类的方法是实现细节服务间的调用关系才是架构重点。第二把数据库、消息队列、Redis 这类中间件节点手工归组。否则每个服务都往同一个数据库节点拉线画面会非常杂乱归组之后一个数据库节点就能代表一类资源依赖。第三过滤掉纯工具类或 DTO 类。这些节点没有业务语义留着只会增加噪音在配置里排除掉就好。做完这三步微服务架构图基本就清爽了。我在一次团队内部分享会上展示过调整前后的对比调整后的图参会者普遍反馈“一眼就能看出哪个服务是核心哪个服务可以独立拆分”。这不是画图技巧的问题而是数据筛选策略的问题。5. 常见问题与排查技巧实录5.1 扫描慢、超时怎么处理仓库特别大的时候扫描慢是正常的。文件数量在十万级别以上首次扫描可能要几分钟。如果超过预期很久还没结束通常原因有三一是把 node_modules、vendor 这类目录也纳入了扫描范围二是网络拉取远程仓库时带宽受限三是同时扫了很多历史分支。我的处理方法是能浅克隆就浅克隆配置里把依赖目录、构建产物目录全部排除如果只有一个分支需要看就明确指定 branch。在 CI 环境里还可以先把仓库打包成 tar 传到执行机上避免反复走网络协议拉对象。还有一个更细致的手段分模块扫描。如果仓库特别庞大可以先用--path指定到某个子目录分别生成子模块架构图再通过提供的合并命令把多份结果拼成整仓架构图。这种方式速度更快而且能让你先聚焦关键模块不会一上来就被全景图淹没。5.2 依赖关系不准、乱线太多怎么办生成出来的图如果线条乱到没法看先别急着断言工具没用。多数情况下是分析策略问题。首先是层级设得太细类级别的依赖天然密集建议改为包级或模块级。其次是扫描范围没有收敛测试代码、代码生成器产物、第三方 SDK 的桥接代码都会引入大量噪音通过 exclude 规则排除。最后是聚合规则没调好不同团队对“模块边界”的定义不一样Archify 提供按包名前缀、按服务名、按仓库子目录三种聚合模式你可以先试一遍选最贴合团队现状的那种。还有一种情况是跨语言调用识别不完整。比如 Java 服务通过 HTTP 调 Go 服务静态分析很难从源码层面精确还原 RPC 调用。这种时候需要你在配置里补充“手动依赖”——把两个服务的关系显式声明进去工具会在最终生成的图上叠加这些边。这不影响自动分析的能力只是作为补充修正。5.3 私库鉴权失败、子模块缺失怎么解决扫描私有仓库时很容易遇到鉴权失败的问题。如果走 HTTPS需要把账号密码或 Token 配置到环境变量里如果走 SSH要保证 runner 的 SSH key 有对应仓库的只读权限。我比较推荐用只读 Token既安全又能避免误推代码。子模块缺失属于“看似报错、实际配置不到位”的典型问题。克隆主仓库后必须主动执行git submodule update --init --recursive否则子模块目录只是空占位。Archify 并不会自动帮你拉子模块它只分析磁盘上已有的文件。还有一个小技巧是如果某个子模块代码不参与架构图的展示直接在配置里排除对应路径即可省掉拉取步骤。5.4 常见问题速查表我整理了这段时间使用 Archify 遇到频率最高的几个问题可以直接对照排查。问题现象可能原因解决办法扫描耗时过长包含依赖目录或历史分支浅克隆、排除依赖目录、指定单分支图中线条杂乱层级过细或范围过宽调整为模块级、排除测试代码生成的依赖图缺少服务间调用静态分析无法识别 RPC在配置中补充手动依赖关系私有仓库拉取失败鉴权配置不正确使用只读 Token 或配置 SSH key子模块结构缺失未初始化子模块执行 submodule update --init --recursiveJSON 输出节点数量异常少排除规则配置过严检查 exclude 是否误伤正常代码生成图片中文字重叠节点太多且布局拥挤放大画布、提高阈值、合并分组不同环境结果不一致二进制版本不同固定同一版本建议用 Docker 镜像遇到问题时最快的排查路径是先看 JSON 输出是否正常再确认配置规则最后检查环境版本。不要一上来就调整渲染参数那是在用错误的方式解决数据问题。6. 最后分享一个我踩坑后的习惯补丁打了几个项目之后我养成了一个习惯每逢新接手仓库第一件事不是读 README而是先跑一遍 Archify把架构图生成出来存到项目 docs 目录下再开始看代码。这个习惯让我在几个大型遗留系统上省下了大量时间。过程中我也踩过不少次坑比如最早用默认配置扫一个多语言仓库生成的图光是打开都要卡几秒后来才意识到是 node_modules 和 vendor 目录没有排除扫描范围和渲染范围都被污染了。现在我的工作流里始终带着三层认知先通过 JSON 数据验证扫描是否准确再通过配置控制图的粒度最后才谈渲染效果。工具再好也要用正确的方式驱动它。如果你所在团队正在为旧系统梳理架构而头疼或者新项目想从一开始就把模块边界之间关系管起来Archify 是个很值得纳入工具箱的选择。它不替代你做架构设计但能帮你把代码仓库真正变成一张随时可查的活地图。
返回列表