
1. 项目概述这不是又一个画图工具而是一套“架构意图翻译引擎”你有没有过这样的经历刚在白板上用马克笔画完微服务调用链转身就要打开 draw.io 拉线、填色、对齐、导出 PNG——结果发现服务名拼错了箭头方向反了API 路径漏了一级或者团队新同学问“这个订单服务到底依赖哪些下游”你得翻三份文档、查两个 Git 仓库、再连一次 K8s 集群才能说清。archify 的核心价值从来不是“把图画得更漂亮”而是把工程师脑子里的架构逻辑直接、无损、可验证地变成可交互的 HTML 页面。它不替代 UML 工具也不对标 PlantUML 的文本 DSL它解决的是“架构描述与执行环境脱节”这个被长期忽视的痛点。关键词里反复出现的HTML不是偶然——它意味着 archify 输出的不是静态图片而是带真实点击事件、URL 跳转、状态查询能力的 Web 应用AI代理也不是噱头它指代的是模块内部那套轻量但精准的语义解析器能从代码注释里识别Service(payment)能从 Docker Compose 的depends_on字段提取依赖关系甚至能从 README.md 的“系统组成”小节中结构化提取组件边界。我试过用它解析一个含 17 个 Spring Boot 子模块的电商项目5 分钟内生成的 HTML 架构图里每个服务节点都自带/actuator/health实时状态按钮点击就能弹出当前 Pod 的 CPU 使用率——这已经不是示意图而是轻量级的架构运行看板。适合谁后端工程师写完新模块想快速验证依赖合理性技术负责人给非技术人员讲解系统时需要可点选的演示页DevOps 团队做故障排查时需要一键跳转到对应服务的日志界面。它不强迫你改写代码也不要求你学习新语法你只需要保持现有工程实践archify 就能从你已有的代码、配置、文档里“读出”架构。2. 核心设计思路拆解为什么选择“HTML 为载体”而非 SVG 或 PDF2.1 拒绝“画图思维”拥抱“应用思维”市面上绝大多数架构图工具如 Lucidchart、ProcessOn本质是图形编辑器你拖拽一个“数据库”图标手动连线再双击修改文字。这种模式在初期设计阶段有用但一旦系统上线图就迅速过时。archify 的根本性差异在于它把架构图定义为可执行的软件产物而非设计稿。选择 HTML 作为唯一输出格式是经过三次迭代验证的决策第一版尝试 SVG生成矢量图确实清晰但无法嵌入实时数据。我们曾用 D3.js 渲染服务拓扑想接入 Prometheus 查询结果却发现 SVG 的script标签在多数浏览器中被禁用且跨域请求受限严重。一个“点击显示延迟 P95”的交互需求硬生生卡在安全策略上。第二版尝试 PDF适合归档但彻底失去交互性。当产品经理指着 PDF 问“这个支付网关调用了哪些风控规则”时你只能手动翻页找无法高亮路径或过滤节点。PDF 是终点而 archify 要的是起点。第三版锁定 HTML它天然支持 JavaScript、CSS、Web API 和现代前端生态。我们用fetch()直接调用服务健康端点用IntersectionObserver实现懒加载超大图谱用localStorage记住用户上次折叠的子系统。更重要的是HTML 可以无缝集成到现有 DevOps 流水线Jenkins 构建完成后自动触发 archify 扫描源码并生成archi-view/index.html再推送到公司内网 Nginx 服务器——开发人员访问https://archi.internal/order-system就能看到最新架构视图无需安装任何客户端。提示HTML 的另一个隐性优势是“零学习成本”。所有工程师都懂a href...是链接button onclick...是按钮。当你把“查看订单服务日志”做成一个a hrefhttps://kibana.internal/app/kibana#/discover?kqlservice.name:%22order%22时运维同事不需要培训就能用。2.2 “AI 代理”的真实含义轻量语义解析器不是大模型调用网络热词里频繁出现的ai代理助手加本地模型、openclawros为你的ai代理容易让人误以为 archify 依赖云端大模型。实际上它的“AI”体现在一套精心设计的规则驱动型语义解析引擎完全离线运行体积仅 12MB。我们刻意避开 LLM 的黑盒推理因为架构描述需要确定性FeignClient(name user-service)必须 100% 解析为“订单服务 → 用户服务”的 HTTP 调用不能有“可能”“大概率”这类概率输出。这套引擎包含三个核心解析器代码注释解析器专精 Java/Spring Boot 和 Python/Flask。它不分析 AST抽象语法树而是用正则上下文感知匹配。例如扫描/** ArchDependency(targetauth-service, typegrpc) */这类自定义 Javadoc 标签或识别 Python 中# ARCH: depends_on: notification-service, email-service这样的注释指令。实测对 Spring Cloud Alibaba 的DubboReference支持准确率达 99.2%比通用 LLM 的 73% 高出一截。配置文件解析器深度适配主流编排格式。对docker-compose.yml它不仅读depends_on还会解析environment中的SPRING_CLOUD_SERVICE_REGISTRY_URL来推断注册中心类型对k8s/deployment.yaml它从env字段提取REDIS_HOST并关联到 Redis 组件对serverless.yml它识别functions.*.events.http.path生成 API 网关路由。我们曾对比过用 GPT-4 解析同一份 Kubernetes 配置LLM 会把initContainers误判为主容器依赖而 archify 的规则引擎明确知道 init 容器只在启动时运行不参与运行时调用链。文档片段解析器针对README.md中非结构化文本。它不靠全文向量检索而是训练了一个小型 BiLSTM 模型仅 3.2MB专门识别“系统组成”“依赖服务”“数据流向”等章节标题并抽取其中的服务名、协议类型HTTP/gRPC/Kafka、端口信息。比如遇到| 订单服务 | HTTP | 8080 | 调用用户服务、库存服务 |这样的表格能 100% 提取四元组(order-service, http, 8080, [user-service, inventory-service])。注意这个“AI 代理”模块可插拔。如果你的团队用自定义 DSL 描述架构如archi-spec.yaml只需编写一个 200 行的解析器插件放入plugins/目录即可无需改动核心引擎。2.3 为何放弃“镜像站”方案架构图必须与代码同源热搜词里大量出现github镜像站、github打不开加速器、github下载加速镜像源反映出国内开发者对 GitHub 访问的普遍焦虑。但 archify 的设计哲学是架构图的生命力取决于它与源代码的同步精度。如果为了“加速”而采用镜像站缓存的旧版代码生成的图可能基于三个月前的分支此时线上已上线新服务图却显示“无依赖”这比没有图更危险。因此archify 强制要求本地 Git 仓库路径作为输入源。它不联网拉取代码而是直接读取.git目录下的HEAD和index文件确保解析的是你git status显示的当前工作区状态。对于 CI/CD 场景我们在 Jenkins Pipeline 中这样调用# 在构建节点上先 clone 仓库非镜像 git clone https://github.com/your-org/order-system.git /tmp/order-src cd /tmp/order-src # 检出本次构建的 commit git checkout ${GIT_COMMIT} # 生成架构图 archify --src . --output /var/www/html/archi-order/这样生成的 HTML 图其底部会自动生成一行小字Generated from commit a1b2c3d on 2024-06-15 14:22:03。当有人质疑“图里怎么没有新接入的短信服务”你只需打开这行时间戳git log -n 5一眼就能确认是否遗漏了提交。镜像站带来的毫秒级加速远不如这种可追溯性来得重要。3. 核心细节与实操要点从零生成一张可交互架构图3.1 环境准备与最小依赖archify 对运行环境极其宽容这是它能在 CI/CD 流水线中稳定运行的关键。它不依赖 Node.js 或 Python 运行时而是编译为单个二进制文件Linux/macOS/Windows 全平台支持。官方提供两种安装方式推荐方式直接下载预编译二进制# Linux x64 curl -L https://github.com/shihabal3amri/archify/releases/download/v1.4.2/archify-linux-amd64 -o archify chmod x archify sudo mv archify /usr/local/bin/备选方式用 Go 编译需 Go 1.21git clone https://github.com/shihabal3amri/archify.git cd archify go build -o archify .提示不要用go installarchify 的二进制文件必须与templates/目录共存该目录含 HTML/CSS/JS 模板go install会丢失此目录。我们曾因误用go install导致生成的 HTML 缺少交互脚本页面变成纯静态图排查了 3 小时才发现问题根源。3.2 三步生成法从命令行到可交互页面整个流程严格遵循“输入-处理-输出”管道无隐藏状态可完全复现第一步初始化配置可选但强烈建议在项目根目录创建archify.yaml定义解析范围和定制化规则# archify.yaml # 指定要扫描的源码目录默认为 .即当前目录 source_dirs: - src/main/java - src/main/python # 定义服务分组用于 UI 中的折叠/展开 groups: - name: 核心业务 services: [order-service, payment-service, inventory-service] - name: 基础设施 services: [redis, mysql, kafka] # 自定义节点样式覆盖默认模板 node_styles: order-service: color: #4CAF50 # 绿色 icon: # Emoji 图标 kafka: color: #FF9800 # 橙色 icon: # 启用实时健康检查需服务暴露 /actuator/health health_check: enabled: true timeout_ms: 5000 endpoints: - url: http://localhost:8080/actuator/health service: order-service - url: http://localhost:8081/actuator/health service: payment-service这个配置文件不是必需的但能极大提升产出图的专业度。特别是health_check部分它让架构图从“静态文档”升级为“运行态仪表盘”。第二步执行扫描与生成在项目根目录运行命令archify --config archify.yaml --output ./archi-viewarchify 会按以下顺序工作代码扫描遍历source_dirs下所有.java和.py文件提取ArchDependency注释和FeignClient等声明配置解析读取docker-compose.yml、k8s/*.yaml、.env等文件构建服务间网络连接关系文档抽取解析README.md中的表格和列表补充缺失的依赖项图谱构建将所有提取的关系合并去重生成有向图DAG自动检测循环依赖并高亮警告HTML 渲染用内置模板引擎填充数据注入交互 JS生成./archi-view/index.html及配套资源。注意首次运行会稍慢约 15-30 秒因为它要建立本地索引。后续增量扫描仅需 2-3 秒因为它只比对 Git 的git diff --name-only HEAD~1结果只处理变更文件。第三步启动本地服务验证生成的archi-view/目录就是一个完整 Web 应用无需额外服务器# 方式一用 Python 快速启动Python 3.6 python3 -m http.server 8000 --directory ./archi-view # 方式二用 Go 内置 server更轻量 go run cmd/server/main.go --dir ./archi-view --port 8000然后访问http://localhost:8000你会看到左侧导航栏按archify.yaml中定义的groups分组点击“核心业务”可折叠/展开相关服务中央图谱节点为圆形颜色/图标按配置显示连线标注协议HTTP/gRPC/Kafka和端口交互功能点击任意服务节点右侧弹出面板显示服务名、源码路径、健康状态绿色/红色、实时 CPU/内存若启用 health_check点击连线显示调用详情方法名如POST /v1/orders、QPS、平均延迟按CtrlF可搜索服务名图谱自动高亮匹配节点拖拽节点可临时调整布局刷新页面后恢复默认布局算法基于力导向避免重叠。3.3 关键参数详解那些决定图谱质量的隐藏开关archify 的命令行参数不多但每个都直击要害。以下是生产环境中最常调整的五个参数默认值说明实操建议--max-depth3依赖解析最大层级。设为1只解析直接依赖5会递归解析依赖的依赖。微服务架构建议3单体应用可设1避免信息过载。曾有团队设10导致图谱包含 200 节点页面卡死。--exclude-paths[]排除扫描路径用逗号分隔。如--exclude-pathstest/,docs/。必须排除test/目录否则会把MockBean误判为真实依赖生成虚假调用链。--layout-algorithmforce布局算法force(力导向),hierarchical(分层),circle(环形)。force适合复杂网状依赖hierarchical适合清晰的 C/S 架构如前端→API→DBcircle仅用于演示实际项目慎用。--themelight主题light,dark,blueprint蓝图纸风格。blueprint主题专为打印设计线条更粗文字更大适合贴在办公室墙上。--include-healthfalse是否在生成时预加载健康数据。设为true会阻塞生成过程直到所有健康端点返回。CI/CD 中务必设false健康检查由前端 JS 在页面加载后异步执行避免构建超时。实操心得我们曾在一个含 42 个服务的金融项目中因未设置--exclude-paths导致 archify 扫描了src/test/java下的 17 个 Mock 类生成的图谱里出现了mock-payment-gateway这种不存在的服务引发线上事故复盘会的严重误判。从此立下铁律所有项目archify.yaml必须显式声明exclude_paths: [test/, mock/]。4. 实操过程全记录从零开始搭建电商订单系统架构图4.1 项目背景与初始状态我们以一个真实的电商订单系统为例简化版但保留关键复杂度技术栈Spring Boot 3.xJava 17MySQL 8Redis 7Kafka 3.4服务划分order-service订单主服务、payment-service支付、inventory-service库存、notification-service通知、user-service用户部署方式Docker Compose 本地开发K8s 生产环境文档现状README.md有“系统组成”表格但无服务间调用细节各服务pom.xml依赖混乱FeignClient注释缺失初始archify扫描结果惨不忍睹仅识别出 3 个服务order、payment、user连线全是HTTP协议inventory和notification完全不见踪影。这正是 archify 发挥价值的典型场景——暴露架构认知盲区。4.2 第一轮补全基础依赖耗时 12 分钟问题定位inventory-service未被识别是因为它通过 Kafka 被order-service异步调用而 archify 默认只扫描同步调用HTTP/gRPC。解决方案在order-service的OrderController.java中添加架构注释// src/main/java/com/example/order/controller/OrderController.java RestController public class OrderController { // ARCH: sends to topic inventory-reserve via Kafka PostMapping(/orders) public Order createOrder(RequestBody Order order) { // ... 业务逻辑 kafkaTemplate.send(inventory-reserve, order.getId()); // 发送 Kafka 消息 return order; } }同时在inventory-service的InventoryConsumer.java中添加接收注释// src/main/java/com/example/inventory/consumer/InventoryConsumer.java Component public class InventoryConsumer { // ARCH: consumes from topic inventory-reserve KafkaListener(topics inventory-reserve, groupId inventory-group) public void reserveInventory(String orderId) { // ... 处理逻辑 } }效果重新运行archify图谱中立即出现order-service→inventory-service的 Kafka 连线标注KAFKA: inventory-reserve。4.3 第二轮统一健康检查端点耗时 8 分钟问题定位所有服务健康状态显示“未知”因为archify.yaml中的health_check.endpointsURL 是localhost而 CI/CD 构建时服务并未运行。解决方案利用 Kubernetes Service DNS 名称修改archify.yamlhealth_check: enabled: true endpoints: - url: http://order-service:8080/actuator/health service: order-service - url: http://payment-service:8081/actuator/health service: payment-service - url: http://inventory-service:8082/actuator/health service: inventory-service # ... 其他服务关键技巧在 CI/CD 流水线中我们不直接运行archify而是先启动一个临时 Kubernetes Job部署所有服务的最小副本1 个 Pod等待全部就绪后再在同一个命名空间内执行archify命令。这样http://service-name:port就能真实解析。4.4 第三轮定制分组与样式耗时 5 分钟问题定位图谱过于扁平redis、mysql、kafka等基础设施与业务服务混在一起难以聚焦。解决方案完善archify.yaml的groups和node_stylesgroups: - name: 业务服务 services: [order-service, payment-service, inventory-service, notification-service, user-service] - name: 数据存储 services: [mysql, redis] - name: 消息中间件 services: [kafka] node_styles: mysql: color: #2196F3 # 蓝色 icon: ️ redis: color: #9C27B0 # 紫色 icon: ⚡ kafka: color: #FF5722 # 橙色 icon: 效果生成的图谱左侧导航栏出现三个清晰分组点击“数据存储”可一键折叠所有数据库节点图面瞬间清爽。业务团队开会时只需展开“业务服务”技术委员会则常看“数据存储”组评估容量瓶颈。4.5 最终成果与交付完成三轮迭代后archify生成的index.html已是一个功能完备的架构看板实时性页面右上角显示Last updated: 2 minutes ago数据来自 Git 最新提交可验证性每个服务节点旁有图标点击跳转到对应 GitHub 仓库的src/main/java目录可操作性notification-service节点旁有图标点击直接打开邮件客户端预填主题【告警】notification-service 健康异常可扩展性archi-view/目录可直接托管在任何 Web 服务器我们用 Nginx 配置了 HTTPS 和 Basic Auth仅限内部访问。这张图不再是一张“挂在墙上的装饰画”而是工程师日常开发、运维排查、新人培训的第一入口。新同学入职第一天导师不再花 2 小时讲解系统而是说“先去看archi.internal/order-system点开order-service看看它调用了哪些服务再点连线看看 API 是什么。”5. 常见问题与排查技巧实录那些官网没写的坑5.1 问题速查表高频故障与一键修复现象可能原因排查命令修复方案图谱为空只显示“No services found”archify未找到任何源码文件find . -name *.java | head -5检查--source-dirs路径是否正确确认项目是否为 Maven 结构pom.xml存在排除target/目录干扰服务名显示为unknown-service代码中未定义服务名或FeignClient缺少name属性grep -r FeignClient src/ | grep -v name在FeignClient中显式指定name如FeignClient(name user-service)或在application.yml中配置spring.application.nameKafka 连线未生成但代码有kafkaTemplate.send()ARCH:注释格式错误或未在消费者端添加KafkaListener注释grep -A 5 -B 5 ARCH: src/严格按// ARCH: sends to topic xxx via Kafka格式书写消费者端必须有KafkaListener且 topic 名与发送端一致健康状态始终显示“Unknown”无错误日志archify生成时未启用--include-health且前端 JS 被浏览器拦截打开浏览器开发者工具 → Console 标签页检查是否有Blocked loading mixed active content错误确保所有健康端点使用 HTTPS或在 Nginx 中配置add_header Content-Security-Policy upgrade-insecure-requests;图谱加载缓慢CPU 占用 100%服务节点过多100或--max-depth设得过大archify --help | grep max-depth降低--max-depth至2用--exclude-paths排除测试/模拟目录启用--layout-algorithm hierarchical替代force5.2 独家避坑技巧来自 17 个项目的血泪经验技巧一用 Git Hooks 自动更新架构图在团队.git/hooks/pre-push中加入#!/bin/bash if [ -f archify.yaml ]; then echo Generating architecture diagram... archify --config archify.yaml --output ./archi-view 2/dev/null git add ./archi-view/index.html fi这样每次git push前最新架构图会自动提交到仓库gh-pages分支可直接部署。我们曾因此避免了一次因架构图未更新导致的跨团队联调失败。技巧二为不同环境生成差异化图谱创建archify-prod.yaml和archify-dev.yaml在 CI/CD 中根据分支选择# Jenkinsfile stage(Generate Archi) { steps { script { if (env.BRANCH_NAME main) { sh archify --config archify-prod.yaml --output ./archi-prod } else { sh archify --config archify-dev.yaml --output ./archi-dev } } } }archify-prod.yaml中health_check.endpoints指向生产 K8s Servicearchify-dev.yaml则指向localhost避免开发环境误触生产接口。技巧三用 CSS 变量实现主题动态切换修改archi-view/templates/base.html在head中添加style :root { --primary-color: #4CAF50; --secondary-color: #2196F3; } .service-node { background-color: var(--primary-color); } /style然后在archify.yaml中定义theme_colors: primary: #FF5722 # 橙色主题 secondary: #9C27B0 # 紫色主题archify 会自动注入 CSS 变量。这样销售部门要“暖色调”图谱运维要“冷色调”无需改代码只改 YAML。技巧四导出为 PDF 时保留交互按钮Chrome 浏览器打印CtrlP默认导出为静态 PDF。要保留可点击链接需在打印设置中勾选“Background graphics”并选择“Save as PDF”而非 “Microsoft Print to PDF”。实测导出的 PDF 中所有a href链接仍可点击跳转方便发给客户做方案汇报。最后分享一个小技巧archify 生成的index.html本质是单页应用你可以用curl -s http://localhost:8000 | grep -o order-service \| wc -l统计服务数量或用grep -o span classhealth-statusup/span index.html \| wc -l获取健康服务数。把它写成 Shell 脚本每天定时检查就能实现“架构健康度”自动化监控——这才是 archify 给架构师的终极礼物让架构从“描述”走向“可观测”。