Service Catalog

Polar Sponsor
爱发电 赞助
.NET 9.0

自动发现并编目代码库或组织中的所有服务——扫描 Dockerfile、docker‑compose、Kubernetes 资源清单、package.json、systemd 单元、P...

Service Catalog. 通过扫描基础设施的现成代码、配置文件和项目元数据来构建和维护一个综合服务目录

功能概述

Service Catalog. 通过扫描基础设施的现成代码、配置文件和项目元数据来构建和维护一个综合服务目录是一项面向实际任务的技能,主要用于回答“我们运行哪些服务,谁拥有,什么服务”。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。

核心要点

  • 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。
  • 该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。
  • 从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。

使用与执行

实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。

结果检查与注意事项

执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。

服务目录(Service Catalog)

通过扫描基础设施即代码(IaC)文件、配置文件及项目元数据,构建并持续维护一份全面的服务目录。回答以下关键问题:“我们运行了哪些服务?谁负责这些服务?它们依赖哪些组件?当前健康状态如何?”

适用场景包括:“列出我们所有的服务”、“我们有哪些微服务?”、“服务资产清单”、“该服务由谁负责?”、“绘制我们的基础设施拓扑图”、“服务间依赖关系分析”、“平台工程审计”,或搭建内部开发者门户(Internal Developer Portal)。

命令

1. discover — 自动发现服务

在工作区(workspace)中扫描所有常见模式下的服务定义。

Docker 服务

# Docker Compose 服务
find . -maxdepth 4 \( -name "docker-compose.yml" -o -name "docker-compose.yaml" -o -name "compose.yml" -o -name "compose.yaml" \) 
  -not -path '*/node_modules/*' -not -path '*/.git/*' 2>/dev/null | while read f; do
  echo "=== $f ==="
  # 提取服务名称
  python3 -c "
import sys
in_services = False
indent = 0
for line in open('$f'):
    stripped = line.rstrip()
    if stripped == 'services:':
        in_services = True
        continue
    if in_services:
        if stripped and not stripped.startswith(' ') and not stripped.startswith('#'):
            break
        if stripped and not stripped.startswith('  ') or (len(stripped) > 0 and stripped[0] != ' ' and stripped != ''):
            break
        if stripped.endswith(':') and stripped.startswith('  ') and not stripped.startswith('    '):
            name = stripped.strip().rstrip(':')
            print(f'  Service: {name}')
" 2>/dev/null || grep -E '^  \w+:' "$f" | grep -v '^    ' | sed 's/://;s/^  */  Service: /'
done

# Dockerfile(每个通常对应一个服务)
find . -maxdepth 4 \( -name "Dockerfile" -o -name "Dockerfile.*" -o -name "*.Dockerfile" \) 
  -not -path '*/node_modules/*' -not -path '*/.git/*' 2>/dev/null | while read f; do
  DIR=$(dirname "$f")
  BASE=$(head -5 "$f" | grep -oP '(?<=FROM )\S+' | head -1)
  echo "Dockerfile: $f (base: ${BASE:-unknown}) — dir: $DIR"
done

Kubernetes 清单文件(Manifests)

# K8s Deployment、StatefulSet、Service、CronJob 等资源
find . -maxdepth 5 -name "*.yaml" -o -name "*.yml" | 
  xargs grep -l "kind:\s*(Deployment|StatefulSet|Service|CronJob|DaemonSet|Job)" 2>/dev/null | 
  grep -v node_modules | while read f; do
  echo "=== $f ==="
  grep -E "^\\s*(kind|name|namespace|image):" "$f" | head -10
done

# Helm Chart
find . -maxdepth 4 -name "Chart.yaml" -not -path '*/node_modules/*' 2>/dev/null | while read f; do
  echo "=== Helm Chart: $f ==="
  grep -E "^(name|version|description|appVersion):" "$f"
done

应用配置文件

# Node.js 服务(含 start 脚本的 package.json)
find . -maxdepth 3 -name "package.json" -not -path '*/node_modules/*' 2>/dev/null | while read f; do
  HAS_START=$(python3 -c "import json; d=json.load(open('$f')); print('yes' if 'start' in d.get('scripts',{}) else 'no')" 2>/dev/null)
  if [ "$HAS_START" = "yes" ]; then
    NAME=$(python3 -c "import json; print(json.load(open('$f')).get('name','unknown'))" 2>/dev/null)
    echo "Node service: $NAME ($f)"
  fi
done

# Python 服务(含主入口点)
find . -maxdepth 3 -name "pyproject.toml" -not -path '*/vendor/*' 2>/dev/null | while read f; do
  DIR=$(dirname "$f")
  echo "Python project: $f"
  grep -E "^(name|version)" "$f" | head -2
done

# Go 服务
find . -maxdepth 3 -name "go.mod" 2>/dev/null | while read f; do
  MODULE=$(head -1 "$f" | awk '{print $2}')
  echo "Go module: $MODULE ($f)"
done

# Procfile(Heroku/Dokku)
find . -maxdepth 3 -name "Procfile" 2>/dev/null | while read f; do
  echo "=== Procfile: $f ==="
  cat "$f"
done

# Systemd Unit 文件
find . -maxdepth 4 -name "*.service" -not -path '*/.git/*' 2>/dev/null | while read f; do
  echo "Systemd unit: $f"
  grep -E "^(Description|ExecStart|After|Requires)=" "$f" 2>/dev/null
done

CI/CD 流水线(揭示已部署服务)

# GitHub Actions 部署工作流
find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | 
  xargs grep -l "deploy" 2>/dev/null | while read f; do
  echo "Deploy workflow: $f"
  grep -E "^\\s*(name|runs-on|env):" "$f" | head -5
done

# GitLab CI 部署阶段
grep -A5 "deploy" .gitlab-ci.yml 2>/dev/null | head -20

2. catalog — 生成服务目录

完成服务发现后,将其汇总为结构化服务目录。对每个服务提取以下信息:

  • 名称(Name):服务标识符
  • 类型(Type):API、Worker、Cron Job、Database、Cache、Queue、Frontend、Gateway 等
  • 技术栈(Tech stack):编程语言、框架、运行时
  • 端口(Port):对外暴露的端口
  • 依赖项(Dependencies):该服务连接的其他服务(源自环境变量、配置文件或代码导入)
  • 负责人(Owner):来自 CODEOWNERS、package.json 的 author 字段、或 git blame 结果
  • 仓库地址(Repository):Git 远程 URL
  • 健康检查端点(Health endpoint):/health、/healthz、/ready、/status 等
  • 文档(Documentation):README、Wiki 链接等
# 从环境变量和配置中检测服务依赖
rg -n "(DATABASE_URL|REDIS_URL|RABBITMQ_URL|KAFKA_BROKERS|MONGO_URI|API_URL|SERVICE_URL)" 
  -g '!node_modules' -g '!vendor' -g '!dist' --type-not binary 2>/dev/null

# 检测服务间通信行为
rg -n "(fetch|axios|http.get|requests.get|grpc|amqp|redis)" 
  -g '!node_modules' -g '!vendor' -g '!dist' -g '!.test.' -g '!.spec.' --type-not binary 2>/dev/null | 
  grep -oP 'https?://[a-zA-Z0-9._/-]+' | sort -u

# 检查 CODEOWNERS 文件
cat CODEOWNERS .github/CODEOWNERS docs/CODEOWNERS 2>/dev/null

# 检查健康检查端点
rg -n "(/health|/healthz|/ready|/status|/ping)" 
  -g '!node_modules' -g '!vendor' --type-not binary 2>/dev/null | head -20

输出服务目录文档示例:

# Service Catalog
Generated: [date] | Services: N | Owners: N teams

## Services

### api-gateway
- **Type:** API Gateway
- **Stack:** Node.js 20, Express
- **Port:** 3000
- **Owner:** @platform-team
- **Dependencies:** auth-service, user-service, redis
- **Health:** GET /health
- **Repo:** github.com/org/api-gateway
- **Docs:** docs/api-gateway.md

### user-service
...

3. deps — 依赖关系图

绘制服务到服务的依赖关系:

api-gateway → auth-service → postgres
api-gateway → user-service → postgres, redis
api-gateway → notification-service → redis, smtp
worker → queue (rabbitmq) → notification-service
frontend → api-gateway

自动识别以下风险模式:

  • 循环依赖(Circular dependencies):A → B → C → A
  • 单点故障(Single points of failure):被超过 3 个其他服务依赖、且无冗余机制的服务
  • 缺失健康检查(Missing health checks):未定义 /health 类端点的服务
  • 孤儿服务(Orphaned services):在配置中声明但未被任何其他服务引用的服务

4. health — 检查服务健康状态

针对已知健康检查端点或本地 Docker 容器的服务执行探活:

# 检查本地 Docker 容器
docker ps --format "{{.Names}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null

# 检查 systemd 服务
systemctl list-units --type=service --state=running 2>/dev/null | grep -v systemd

# 探测健康检查端点
for endpoint in $(rg -o "https?://localhost:[0-9]+/(health|healthz|ready|status)" -g '*.{yml,yaml,json,env}' 2>/dev/null | sort -u); do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 3 "$endpoint" 2>/dev/null)
  echo "$endpoint → $STATUS"
done

5. owners — 所有权报告

将服务映射至所属团队或个人:

# 来自 CODEOWNERS
cat CODEOWNERS .github/CODEOWNERS 2>/dev/null | grep -v '^#' | grep -v '^$'

# 来自 package.json 的 author/maintainers 字段
find . -maxdepth 3 -name "package.json" -not -path '*/node_modules/*' 2>/dev/null | while read f; do
  python3 -c "
import json
d = json.load(open('$f'))
name = d.get('name', 'unknown')
author = d.get('author', 'unassigned')
if isinstance(author, dict): author = author.get('name', 'unassigned')
print(f'{name}: {author}')
" 2>/dev/null
done

# 来自 git blame(按目录统计最近 90 天最活跃贡献者)
find . -maxdepth 2 -type d -not -path '*/.git*' -not -path '*/node_modules*' | while read d; do
  TOP=$(git log --since="90 days ago" --format="%an" -- "$d" 2>/dev/null | sort | uniq -c | sort -rn | head -1)
  if [ -n "$TOP" ]; then
    echo "$d: $TOP"
  fi
done 2>/dev/null

将未明确归属的服务标记为风险项。

6. drift — 检测目录漂移(Catalog Drift)

将当前生成的服务目录与先前保存的版本(.service-catalog.json)进行比对,识别变更:

  • 新增服务(未存在于旧目录中)
  • 下线服务(存在于旧目录中,但当前未扫描到)
  • 配置变更(端口、依赖项、技术栈等)
  • 负责人变更

建议在 CI 中运行该命令,及时捕获未文档化的基础设施变更。

输出格式

  • text(默认):面向人工阅读的结构化报告,按服务分节展示
  • json:机器可读格式:{services: [{name, type, stack, port, deps, owner, health, repo}], graph: {edges: []}}
  • markdown:适用于 Wiki 的文档格式,含表格与 Mermaid 依赖关系图
  • mermaid:纯 Mermaid 格式的服务依赖关系图

注意事项

  • 支持单体仓库(monorepo)与多仓库(multi-repo)架构(可从仓库根目录或组织根目录启动扫描)
  • 无需服务实际运行 —— 仅依赖配置文件与源码静态分析
  • 若需检测运行中服务的健康状态,则扫描环境必须能访问目标服务
  • 所有权识别采用启发式策略(优先级:CODEOWNERS > package.json > git blame),结果需人工复核与修正
  • 请将服务目录保存为 .service-catalog.json,以启用 drift 检测能力
  • 可作为轻量级替代方案,或作为 Backstage、Port、Cortex 等内部开发者门户工具的数据源

相关专题

更多
Docker Desktop怎么设置端口映射
Docker Desktop怎么设置端口映射

本专题聚焦Docker Desktop容器端口映射与访问配置,整理从创建容器、设置端口绑定到验证本地服务访问的操作流程。针对端口被占用、映射配置错误、容器服务无法访问等情况,也提供相应的检查方向,方便用户完成端口配置。

2026.11.03

0

18

Docker Desktop镜像构建教程
Docker Desktop镜像构建教程

想使用Docker Desktop将本地项目构建成Docker镜像?本专题围绕镜像构建的实际操作展开,介绍Dockerfile编写、构建命令使用、镜像标签设置和构建日志查看等内容,同时整理镜像无法生成、依赖安装失败及构建缓存异常等问题的排查思路。

2026.11.03

0

11

Docker Desktop容器创建指南
Docker Desktop容器创建指南

本专题聚焦Docker Desktop容器创建与运行配置,介绍通过本地镜像或远程镜像创建容器的方法,以及容器启动、终端访问、日志查看和基础管理等操作。针对端口冲突、参数配置不当、容器无法启动等情况,也整理了相应的排查方向。

2026.11.03

0

11

Tailwind CSS 如何制作导航栏和卡片
Tailwind CSS 如何制作导航栏和卡片

用 Tailwind CSS 制作导航栏和卡片,可先搭建语义化结构,再组合 Flex、Grid、间距、圆角与阴影类。这里整理横向导航、移动端菜单、卡片网格及悬停效果的相关文章,帮助你把常见页面组件做得清晰且适配不同屏幕。

2026.11.03

0

17

Tailwind CSS 响应式布局怎么写
Tailwind CSS 响应式布局怎么写

Tailwind CSS 响应式布局通常从移动端样式写起,再用 sm、md、lg 等前缀调整不同屏幕宽度下的网格、间距和导航。本专题整理断点配置、Grid 与 Flex 自适应布局及常见溢出问题,帮助你逐步完成多设备适配。

2026.11.03

0

19

Tailwind CSS 常用类名怎么记
Tailwind CSS 常用类名怎么记

Tailwind CSS 类名很多,先按布局、间距、文字、颜色和状态分组记忆,再通过官方文档检索具体写法。本专题结合类名排序、动态拼接失效、自定义实用类等问题,帮助你建立常用类名的速查方法。

2026.11.03

0

12

码上飞入口地址合集
码上飞入口地址合集

本专题汇总了码上飞(CodeFlying)的官方入口地址合集,涵盖官网主站及网页版在线使用入口,支持注册登录后直接在线体验零代码AI应用生成。同时整理了APP端下载渠道与小程序入口,助你快速访问平台,通过自然语言描述需求即可生成应用、小程序或网站。

2026.11.03

0

10

Uvicorn 报错与问题解决教程
Uvicorn 报错与问题解决教程

本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

2026.11.02

0

14

Uvicorn使用教程
Uvicorn使用教程

本专题汇总了Uvicorn使用教程与启动运行指南,涵盖其作为Python ASGI服务器的定位与特点,以及命令行启动(uvicorn main:app --reload)、参数配置(host/port/workers)、程序内嵌运行与Gunicorn结合部署等核心用法。同时整理了热重载调试、日志配置与生产环境部署优化等技巧,助你快速掌握Uvicorn的运行与配置。

2026.11.02

0

17

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习