从零构建开源API监控平台:架构设计与工程实践
1. 项目概述为什么我们需要一个自己的API监控平台如果你负责过线上业务的后端服务或者维护过哪怕一个对外的API接口那你一定经历过这样的深夜手机突然收到告警某个核心接口的响应时间飙升或者干脆直接返回500错误。你手忙脚乱地登录服务器查看日志试图定位问题而业务方的电话已经一个接一个地打进来。事后复盘你可能会想如果有一个工具能提前告诉我接口的可用性在下降或者能自动记录下每次故障的详细上下文那该多好。市面上的商业监控工具如Datadog、New Relic功能强大但价格不菲且数据隐私和定制化程度往往受制于人。而一些轻量级的开源方案又可能功能单一无法满足从可用性、性能到业务指标的全方位监控需求。这就是“开源API接口监控平台”这个项目诞生的背景。它不是一个简单的“心跳检测”工具而是一个旨在由团队自主掌控能够深度集成到自身研发流程中的综合性监控解决方案。核心价值在于它让你不仅能知道接口“死没死”更能洞察它“为什么慢”、“哪里出了问题”以及“对业务产生了什么影响”。这个平台适合中小型研发团队、独立开发者以及对数据敏感、希望将监控能力内化的企业。通过构建这样一个平台你不仅能提升系统的稳定性更能沉淀出一套属于自己团队的、可观测性领域的最佳实践。接下来我将从一个实践者的角度拆解如何从零开始设计和实现这样一个平台分享其中的核心设计思路、技术选型考量以及那些只有踩过坑才知道的实操细节。2. 平台核心架构与设计思路拆解一个健壮的监控平台其架构设计决定了它的扩展性、可靠性和易用性。我们不能只做一个简单的定时任务脚本而需要将其视为一个微服务系统来设计。2.1 分层架构与核心组件我倾向于采用清晰的分层架构将平台划分为数据采集层、处理存储层和展示告警层。数据采集层Prober这是平台的“触手”负责主动向目标API发起探测请求。它必须足够轻量、高效且可分布式部署。关键设计点在于探测任务的调度策略。我们不应该用一个中心化的Cron来串行执行所有任务那会成为单点瓶颈和故障源。相反应采用分布式任务队列如Celery、RabbitMQ的模式。一个中心调度器只负责任务的下发和状态的收集而多个“工人”Worker节点从队列中领取任务并执行。这样横向扩展探测能力就变得非常简单——只需增加Worker节点即可。处理存储层Processor Storage采集到的原始数据如HTTP状态码、响应时间、响应体片段需要经过清洗、加工和存储。这里涉及两个核心选择时间序列数据库和关系型数据库。对于监控指标如响应时间、状态码计数其特点是数据点按时间顺序产生查询模式以时间范围聚合为主因此Prometheus或InfluxDB这类时序数据库是天然之选。它们对时间序列数据的压缩存储和高效查询做了大量优化。而对于探测任务配置、告警规则、用户信息等元数据则需要PostgreSQL或MySQL这类关系型数据库来保证事务性和复杂查询。展示告警层Dashboard Alert这是与用户交互的界面。我们需要一个灵活的仪表盘来可视化监控数据Grafana是业界标配可以直接集成以及一个强大的告警引擎。告警引擎不能只是简单的阈值判断如响应时间5s就告警而应支持更复杂的逻辑比如“最近5分钟内失败率超过10%”或“同比上周同一时间平均延迟增长超过50%”。这需要告警引擎能够对时序数据进行实时聚合计算。2.2 技术选型的深度考量为什么是这些技术每一个选择背后都有权衡。任务队列选用Celery Redis/RabbitMQCelery是Python生态中事实标准的分布式任务队列生态成熟与Django/Flask等Web框架集成无缝。Redis作为消息代理Broker部署简单性能极高适合任务量巨大的场景RabbitMQ则功能更全面保证消息可靠不丢失适合对可靠性要求极高的场景。对于监控平台任务丢失偶尔发生是可以接受的下次调度会补上因此我通常首选Redis追求极致的部署简便和性能。时序数据库选用Prometheus虽然InfluxDB功能强大但Prometheus的拉模型Pull对于主动探测的场景需要一些改造需通过Pushgateway推送不过其强大的PromQL查询语言、与Grafana的原生集成以及活跃的社区使其成为监控领域的事实标准。更重要的是它的数据模型指标标签非常适合用来描述API监控“api_response_duration_seconds{job“user-service”, endpoint“/api/v1/login”, method“POST”}”这样一个指标就能清晰定义被监控的对象。核心业务服务语言选用Python (FastAPI)监控平台的管理界面任务配置、告警规则管理、用户管理需要快速开发。FastAPI凭借其现代的异步特性、自动生成API文档、极高的性能非常适合构建这类需要处理大量IO操作如数据库查询、调用Prometheus API的后台服务。相比Django它更轻量更适合构建API驱动的单页应用后端。注意技术选型没有银弹。如果你的团队对Go更熟悉用Go来编写高性能的Prober和后台服务是绝佳选择。这里的选择是基于“快速构建、生态丰富、易于维护”的折中考虑。3. 核心功能模块的详细实现有了架构蓝图我们来深入每个核心模块看看具体如何实现。3.1 分布式探测引擎的实现细节探测引擎是平台最核心的部分它的稳定性和准确性直接决定了监控的有效性。任务定义与序列化一个探测任务需要包含哪些信息至少要有唯一的任务ID、目标URL、请求方法GET/POST等、请求头、请求体对于POST、预期状态码、超时时间、探测频率如每30秒一次。我们需要将这些信息序列化后放入消息队列。通常使用JSON格式因为它通用且易读。Worker的实现Worker是一个独立的进程它持续监听任务队列。当收到一个任务时它需要记录开始时间。使用如httpx或aiohttp异步库发起HTTP请求。务必设置合理的超时和重试机制。一个常见的陷阱是使用默认超时导致Worker在遇到网络缓慢的目标时被长时间阻塞。记录结束时间计算响应时间。检查响应状态码是否与预期相符有时还需要检查响应体是否包含某个关键字用于验证业务逻辑正确性。将本次探测结果成功/失败、响应时间、响应体大小、可能的关键错误信息组装成一个数据点。将这个数据点发送给后续的处理管道如写入Prometheus Pushgateway或直接写入数据库。高可用与负载均衡通过Celery可以轻松启动多个Worker。调度器会根据Worker的繁忙程度分发任务。我们需要确保Worker本身是无状态的任何Worker都能执行任何任务。这样当某个Worker崩溃时它正在执行的任务会被其他Worker重新领取取决于消息队列的ACK机制。# 一个简化的Worker任务示例使用Celery import httpx from celery import Celery from prometheus_client import push_to_gateway, CollectorRegistry, Gauge, Counter app Celery(prober, brokerredis://localhost:6379/0) app.task(bindTrue, max_retries3) def probe_api(self, task_config): url task_config[url] method task_config.get(method, GET) timeout task_config.get(timeout, 10) expected_status task_config.get(expected_status, 200) registry CollectorRegistry() duration_gauge Gauge(api_response_duration_seconds, API response duration, [job, endpoint, method], registryregistry) status_counter Counter(api_requests_total, Total API requests, [job, endpoint, method, status], registryregistry) start_time time.time() try: with httpx.Client(timeouttimeout) as client: resp client.request(method, url) response_time time.time() - start_time # 记录指标 duration_gauge.labels(jobmy-service, endpointurl, methodmethod).set(response_time) status_counter.labels(jobmy-service, endpointurl, methodmethod, statusresp.status_code).inc() # 判断成功与否可根据业务逻辑更复杂 success resp.status_code expected_status if not success: # 可以记录错误信息到日志或特定指标 pass # 推送指标到Prometheus Pushgateway push_to_gateway(pushgateway:9091, jobapi-prober, registryregistry) return {success: success, response_time: response_time, status_code: resp.status_code} except Exception as exc: # 记录失败并触发重试 self.retry(excexc, countdown60)3.2 指标数据模型与Prometheus集成如何将一次探测抽象成Prometheus的指标这是设计的关键。我们至少需要定义以下几个核心指标api_requests_total计数器Counter记录总请求数用标签区分状态码status“200”status“500”。通过PromQLrate(api_requests_total{status!~“2..”}[5m])可以计算5分钟内的非2xx错误率。api_response_duration_seconds仪表盘Gauge或直方图Histogram。Gauge记录最后一次的响应时间简单直接。但我强烈推荐使用Histogram。因为Histogram会自动计算分位数如P50, P90, P99。api_response_duration_seconds_bucket这个指标能让你清晰地看到“95%的请求在多少秒内完成”这对于衡量SLA服务等级协议至关重要。api_up仪表盘Gauge1表示可用0表示不可用。可以直接通过判断最近一次探测是否成功来设置。数据推送策略Prometheus默认是拉取Pull模型但我们的Worker是主动探测更适合推送Push。这里就需要用到Prometheus Pushgateway。Worker将每次探测生成的指标推送到Pushgateway然后由Prometheus Server定期从Pushgateway拉取。需要注意的是Pushgateway通常用于批处理作业或服务生命周期短的任务对于持续运行的监控我们需要小心处理指标在Pushgateway上的持久化问题避免旧数据残留。一种做法是在推送时总是覆盖同一job的指标。3.3 灵活可配的告警规则引擎告警是监控的最终目的。我们需要一个能解析复杂规则并执行告警动作的引擎。规则定义告警规则可以用YAML或JSON定义存储在关系数据库中。一条规则应包含name: 告警规则名称。expr: PromQL表达式这是核心。例如rate(api_requests_total{job“order-service”, status“500”}[5m]) / rate(api_requests_total{job“order-service”}[5m]) 0.05表示订单服务5分钟内500错误率超过5%。for: 持续时长例如“2m”。表示表达式连续满足2分钟才触发告警用于避免毛刺。severity: 严重级别critical, warning。annotations: 告警内容模板可以使用查询结果的标签变量如{{ $labels.endpoint }} 接口错误率过高当前值{{ $value }}。receivers: 接收人组如“运维组”、“开发组”。告警引擎工作流规则加载与周期评估一个独立的告警评估服务Alert Evaluator定期如每15秒从数据库加载所有启用状态的规则。执行PromQL评估服务连接Prometheus的查询API执行规则中的expr。状态管理与去重如果表达式结果满足条件且持续时间达到for的要求则生成一条告警Alert。告警需要有自己的状态firingresolved。这里的关键是告警去重同一个规则、同一组标签labels标识的告警在未恢复前不应重复发送。我们需要在内存或Redis中维护一个活跃告警的集合。触发通知当告警状态从“正常”变为“触发”firing或从“触发”变为“恢复”resolved时调用通知服务Notifier。通知服务根据receivers配置通过邮件、企业微信、钉钉、Slack等渠道发送消息。实操心得告警疲劳是运维的头号敌人。一定要设置合理的阈值和持续时间for。对于响应时间使用分位数如P992s比平均值更有意义因为平均值容易被少数极端请求拉高而分位数能反映大多数用户的体验。同时建议为关键服务设置“黄金信号”告警延迟Latency、流量Traffic、错误Errors、饱和度Saturation。4. 平台功能拓展与高级特性基础监控搭建完毕后可以考虑引入一些高级特性让平台从“能用”变得“好用”。4.1 多协议支持与自定义检查脚本除了HTTP/HTTPS我们可能还需要监控TCP端口是否开放、数据库连接是否正常、SSL证书是否即将过期。这要求探测引擎具备插件化能力。我们可以设计一个“检查器”Checker接口每种协议对应一个实现。Worker执行任务时根据任务类型动态加载对应的检查器。更灵活的是支持自定义脚本。允许用户上传一段Python或Shell脚本Worker在一个安全的沙箱环境如Docker容器中执行该脚本并根据脚本的退出码和输出判断成功与否。这几乎可以监控任何东西但必须严格考虑安全性防止恶意脚本。4.2 性能数据聚合与趋势分析监控不能只看当前。我们需要历史趋势分析。Prometheus本身提供了强大的查询能力但数据默认只保留15天左右可配置。对于更长期的趋势分析如月度报表、同比环比需要将数据导出到长期存储中如TimescaleDB基于PostgreSQL的时序数据库扩展或ClickHouse。可以设计一个ETL作业定期如每天将Prometheus中的关键指标聚合后如计算日平均响应时间、日总请求量写入长期存储。然后在平台的仪表盘中就可以展示“近30天平均响应时间趋势图”、“本周与上周错误率对比”等高级视图。4.3 权限控制与多租户隔离当平台需要给多个团队使用时权限控制就至关重要。需要实现基于角色的访问控制RBAC租户/项目级隔离每个团队或项目有自己的空间只能查看和管理自己名下的监控任务和告警规则。角色定义常见的角色有管理员管理所有资源、用户、开发者创建、修改自己项目的任务和告警、查看者仅能查看仪表盘和告警。数据隔离在数据层面所有指标和任务都需要打上“租户ID”或“项目ID”的标签。在查询时必须强制带上该标签进行过滤。Prometheus的标签原生支持这种过滤。5. 部署、运维与踩坑实录设计和开发只是第一步让平台稳定可靠地跑起来才是真正的挑战。5.1 容器化部署与编排强烈建议使用Docker容器化所有组件并用Docker Compose或Kubernetes进行编排。一个典型的docker-compose.yml可能包含以下服务postgres: 元数据存储。redis: Celery消息代理和缓存。prometheus: 时序数据库。pushgateway: 指标推送网关。grafana: 数据可视化。web(FastAPI): 主管理后台。celery_worker: 探测Worker可以启动多个实例。celery_beat: Celery的定时调度器用于下发周期性的探测任务。alertmanager(可选): Prometheus生态的独立告警管理组件负责告警去重、分组和路由功能比自研的简单引擎更强大。可以考虑后期集成。使用Kubernetes部署可以更方便地管理Worker的水平扩缩容HPA例如根据任务队列的长度自动增加或减少Worker Pod的数量。5.2 监控平台自身的监控“医者不能自医”是监控平台最大的讽刺。我们必须监控平台自身基础设施监控监控所有容器的CPU、内存、磁盘使用情况。这可以用Prometheus的node_exporter来完成。组件健康监控为每个核心服务Web、Worker、PostgreSQL、Redis添加健康检查接口并设置一个最基础的外部探测任务来检查这个接口。确保平台本身宕机时你能通过另一个更简单的通道如云厂商的监控收到告警。业务指标监控监控平台的关键业务指标如worker_tasks_executed_totalWorker执行任务总数、queue_length任务队列长度、alert_evaluation_duration_seconds告警规则评估耗时。这些指标能帮你发现平台的性能瓶颈。5.3 常见问题与排查技巧在实际运营中你会遇到各种各样的问题。以下是一些典型场景和排查思路问题一Worker负载不均有的很忙有的空闲。排查检查消息队列Redis的连接和配置。Celery默认的预取prefetch设置可能导致一个Worker一次性领取过多任务。可以调整worker_prefetch_multiplier为1让Worker一次只取一个任务实现更公平的调度。技巧可以为不同类型的任务高频任务、低频任务、长超时任务创建不同的队列并让专门的Worker消费指定队列实现资源隔离。问题二Prometheus查询变慢Grafana图表加载超时。排查首先检查Prometheus的本地存储压力。使用top或htop查看Prometheus进程的CPU和内存。检查磁盘IO。可能是数据量太大或者查询的时序范围太广、指标标签组合太多导致计算量爆炸。技巧1) 调整Prometheus的数据保留策略删除不必要的历史数据。2) 优化PromQL避免使用*这样的全匹配尽量指定具体的标签。3) 对于Grafana为频繁查看的仪表盘设置缓存。问题三告警漏报或误报。排查检查告警规则的for字段是否合理。过短容易误报过长可能漏报。检查PromQL表达式是否正确特别是rate()函数的时间窗口[5m]是否与数据抓取间隔匹配。技巧引入告警模拟测试功能。允许用户针对一条历史时间范围的数据运行告警规则查看是否会触发以及触发的内容。这是验证告警规则最有效的方法。问题四自定义脚本执行超时或产生安全问题。排查严格限制脚本的执行时间和资源CPU、内存。必须使用Docker等容器技术进行强隔离确保脚本无法访问宿主机敏感资源。技巧提供一个安全的脚本运行时基础镜像只包含最必要的工具如curl, python3。所有脚本执行前进行简单的语法检查或静态分析如果支持。构建一个开源API监控平台是一个典型的“吃自己的狗粮”的过程。你在监控他人的服务同时也在深度使用和考验自己的平台。这个过程会迫使你思考监控的本质、告警的意义以及可靠性的价值。从最简单的HTTP探测开始逐步迭代加入更复杂的特性最终你会收获的不仅仅是一个工具更是一套对系统可观测性深刻的理解和实践经验。

相关新闻

ELK栈生产环境调优:从性能瓶颈到稳定输出的工程实践

ELK栈生产环境调优:从性能瓶颈到稳定输出的工程实践

最近在社区里看到不少关于 ELK 和 EZ 的讨论,尤其是当 ELK 在特定版本或配置下表现不尽如人意时,总有人会调侃它像一位“涅槃AD”——看似华丽,但在高压环境下(比如高并发、复杂查询)却容易“暴毙”,输出不…

2026/10/15 0:07:20 阅读更多 →
HarmonyOS 鸿蒙App开发不难:一个前端工程师的 ArkTS 上手实践

HarmonyOS 鸿蒙App开发不难:一个前端工程师的 ArkTS 上手实践

HarmonyOS 鸿蒙App开发不难:一个前端工程师的 ArkTS 上手实践前端去搞鸿蒙,是不是想不开?一、先搞清楚:ArkTS 到底是什么二、前端工程师"白捡"的四个优势1. TypeScript 直接迁移2. 声明式 UI 响应式状态,就…

2026/10/9 6:58:02 阅读更多 →
武汉自动意志科技有限公司:智钳Claw AI智能盒子如何完成实时落地交付

武汉自动意志科技有限公司:智钳Claw AI智能盒子如何完成实时落地交付

武汉自动意志科技有限公司推出的智钳Claw AI智能盒子面向实际业务问题,重点不在堆砌概念,而在说明产品适合什么场景、怎样使用以及如何验证效果。面向CSDN写作时,需要先讲清读者痛点,再逐步展开产品方案。武汉自动意志科技有限公司…

2026/9/27 14:44:12 阅读更多 →

最新新闻

064、广播数据长度超出承载上限时的分包处理

064、广播数据长度超出承载上限时的分包处理

现场:一条永远发不出去的广播 几年前做一个分布式采集系统,主控通过广播通道向所有节点下发同步命令和参数。协议栈的单帧净荷上限是 31 字节,这是链路层硬约束,改不了。前期功能很简单,同步命令就几个字节&#xff0c…

2026/10/15 0:08:01 阅读更多 →
063、广播间隔与扫描窗口错配导致的设备不可见

063、广播间隔与扫描窗口错配导致的设备不可见

一个做资产追踪标签的团队遇到过这样一件事。标签固件烧录完毕,功耗测试过了,广播内容用嗅探工具抓包也正常,RSSI 在预期范围内。但配套的接收端在实验室里就是扫不到这批标签。换一台接收端,能扫到。再换回来,又扫不到…

2026/10/15 0:08:01 阅读更多 →
062、连接建立瞬间超时断开的原因分类

062、连接建立瞬间超时断开的原因分类

一个半夜被叫起来处理的问题 去年冬天做的一个数据采集项目,现场大概两百多个节点,通过无线链路往中心网关上报数据。上线跑了三天都正常,第四天凌晨两点,值班同事打电话说监控大屏上设备在线数从两百多掉到了三十几个&#xff0c…

2026/10/15 0:08:01 阅读更多 →
061、广播包发出后没有回应时的链路排查思路

061、广播包发出后没有回应时的链路排查思路

上个月帮一个做工业数据采集的团队看问题,他们用一套自研的无线轮询协议,主站每隔两秒向从站发一轮广播包,从站收到后回传采集数据。现场跑了三个月一直正常,突然有一天主站日志里开始出现大量“广播发出后无回应”的告警&#xf…

2026/10/15 0:08:01 阅读更多 →
别再让“虚拟时装毕设”卡在论文上:数字时尚设计人的 AI 工具搭子清单 ✨

别再让“虚拟时装毕设”卡在论文上:数字时尚设计人的 AI 工具搭子清单 ✨

如果你读的是数字时尚设计,大概率会遇到这样一种“分裂”的毕业状态: 一边在用 CLO 3D / Style3D 调版片、缝份、面料垂坠和动态走秀效果;一边还要翻虚拟时尚、数字服装、AIGC、非遗纹样、用户审美评价等一大堆中英文文献;最后还…

2026/10/15 0:08:01 阅读更多 →
二次规划QP实战:从调包到手撕,解决不可行与病态问题

二次规划QP实战:从调包到手撕,解决不可行与病态问题

1. 从“调包”到“手撕”:为什么QP值得你花时间很多做算法落地的朋友,第一次接触二次规划(Quadratic Programming,简称QP)都是在MATLAB的quadprog或者Python的cvxopt.solvers.qp里填几个矩阵就完事了。模型跑通那一刻觉…

2026/10/15 0:07:00 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →