Rust异步性能监控与调优:用tokio-console透视Tokio运行时
排了将近两周的异步性能问题最后发现罪魁祸首是一个没有被监控到的同步阻塞调用。这事发生在一次基于 Rust 和 Tokio 的在线服务改造里接口延迟从 3ms 抖到 800msCPU 占用却一直不高所有日志都显示业务代码执行正常。后来把 tokio-console 挂上去才看到某个 worker 线程上的 poll 耗时到了几十毫秒再往下追才找到那个藏在第三方 SDK 里的阻塞式 DNS 查询。那之后我养成了一个习惯凡是基于 Tokio 的异步服务上线前先把监控和调优机制搭好不然性能问题就是黑盒。本文直接围绕 Rust 异步性能这个主题讲透 Tokio 运行时内部发生了什么、应该盯哪些指标、用什么工具把黑盒变成透视以及真实项目里怎么用监控数据指导调优。适合正在用 Rust 写服务端、爬虫、网关或消息系统的同学尤其是那些已经感受到异步偶尔会卡但不知道怎么查的人。1. 为什么异步性能是个黑盒1.1 Future 状态机与调度模型Rust 的 async/await 不是魔法它本质上是编译器把一段异步函数生成一个状态机 Future。每次调用 pollFuture 就向前执行一段遇到真正需要等待的事情就挂起返回 Pending。运行时负责在将来某个时刻再次 poll 这个 Future。Tokio 就是这套运行时的集大成者。它的多线程运行时大致是这么运作的程序启动后创建若干 worker 线程每个 worker 有自己的本地任务队列同时还有一个全局调度队列。新任务会先进入某个 worker 的本地队列worker 处理完当前任务后从本地队列取下一个。如果本地队列空了它就会去偷其他 worker 或者全局队列里的任务这就是所谓的工作窃取work stealing调度。与此同时Tokio 内部还有一个 I/O 驱动reactor和定时器驱动负责监听 socket 事件、计时器超时一旦事件就绪就唤醒对应的 waker让任务重新进入可调度状态。这套模型很强大但它对开发者是不透明的。你在一个异步函数里写下socket.read(...).await眼前看到的只是一行代码加一个 await背后却发生了注册事件、挂起任务、返回 Pending、事件到达、唤醒任务、再次 poll 这一连串动作。如果某个环节出问题你靠肉眼看源代码很难定位到具体卡点。1.2 黑盒的三个根源第一Tokio 采用的是协作式调度任务主动让出执行权。同步线程靠操作系统的抢占式调度来保证公平性而 Tokio 里一个任务如果不 await、不主动 yield它可以一直占着 worker 线程不放。其他任务只能干等。但你从业务代码里很难看出来哪段逻辑会长时间霸占 worker因为普通函数调用不会自动让出执行权。第二编译器生成的 Future 状态机对调试工具并不友好。同步代码的调用栈是清晰的一条链出现问题可以一层层往上回溯。异步 Future 的调用栈是分散的、被打断的backtrace 往往只能看到这个 Future 被 poll 了却很难直接告诉你它执行到了源码里的哪一行。第三大量任务在多个 worker 线程之间迁移。同一个 Future 可能第一次 poll 在 worker 1第二次 poll 在 worker 2任务之间的等待、唤醒、窃取关系极其复杂。没有监控数据辅助性能问题看起来就像随机发生这也是很多团队抱怨异步服务拍不准问题的根本原因。2. 监控工具箱从开关到仪表盘2.1 tokio-console 接入流程Tokio 官方维护了一个监控工具 tokio-console它能实时展示运行时里所有任务的状态、poll 次数、poll 耗时、waker 数量等信息。我最初踩过一个坑只加了依赖没有开tokio_unstable编译配置启动后 console 一点数据都没有。官方为了快速迭代要求显式开启这个配置而且它目前只能在Rust nightly或设置cfg的情况下使用使用 stable Rust 但设置 RUSTFLAGS 也可以。最简配置是[dependencies] tokio { version 1, features [full, rt-multi-thread, macros, sync, time, tracing] } console-subscriber 0.4 tracing 0.1 tracing-subscriber { version 0.3, features [env-filter, fmt] }main.rs 里要初始化 trace 和 consoleuse tracing_subscriber::EnvFilter; #[tokio::main] async fn main() { tracing_subscriber::fmt() .with_env_filter(EnvFilter::from_default_env()) .init(); console_subscriber::init(); // 你的业务启动代码 run_server().await; }编译时设置RUSTFLAGS--cfg tokio_unstable或者在项目根目录的.cargo/config.toml里统一配置[build] rustflags [--cfg, tokio_unstable]然后安装并启动终端仪表盘cargo install tokio-console tokio-console如果你在启动时看到任务列表就说明已经能看到运行时内部的情况了。tokio-console 会展示每个任务当前是 running、pending、scheduled 还是 idle包括创建时间、最近一次 poll 时间、poll 次数和总耗时、waker 的数量与来源。这些字段对定位哪个任务在拖后腿非常有价值。注意开了tokio_unstable之后Tokio、console-subscriber 这些 crate 的内部 API 都可能变化升级版本时要格外小心。生产环境不建议直接把 console 暴露到公网它是调试工具不是生产监控组件。2.2 用 tracing 给异步代码打点tokio-console 只是第一层透视它能看到任务级别的问题但有时你需要知道某个具体业务请求到底卡在哪个异步函数上。这种场景要用tracing。不要小看这层打点它是连接运行时指标和业务逻辑的桥梁。给关键异步函数加上#[instrument]之后每个 span 的进入和退出都会产生事件再结合tracing-subscriber的输出可以看到函数耗时use tracing::instrument; #[instrument(skip(app), fields(req_id %req_id))] async fn handle_request(app: AppState, req: Request) - ResultResponse, Error { let data fetch_user(app, uid).await?; build_response(data).await }日志输出里会自动带上函数名、耗时、字段信息。如果配合 tokio::task::Id 的追踪字段甚至能把某次业务请求和 console 里的任务对应上。2.3 生产环境指标导出tokio-console 适合开发和压测阶段真正进了生产我更倾向于把指标导出到 Prometheus、Grafana 这类监控平台。Tokio 运行时自身暴露了不少指标关键在于开启metricsfeature 并持有 Runtime 对象。我一般不用#[tokio::main]这种快捷方式而是手动构建 Runtimeuse tokio::runtime::Builder; let rt Builder::new_multi_thread() .worker_threads(4) .enable_all() .metrics() .build() .expect(build runtime failed); rt.block_on(async_main());之后可以从rt.metrics()里读到 worker 数、存活任务数、阻塞线程池队列深度等数据具体方法名看当前 Tokio 版本的文档不同版本会调整。我会开一个后台任务每隔几秒采样一次再转成 Prometheus 格式暴露出去。这样 Grafana 面板上就能长期看到任务数、worker 利用率、队列深度这些核心趋势。还要强调一点生产环境的指标要分层。业务层用 tracing 记录慢请求和错误运行时层用 runtime metrics 记录全局状态微观层用 console 在出问题时临时抓现场。三层各司其职才能既不淹没在日志里又不至于在故障时两眼一抹黑。3. 关键指标解读从数字里看到调度真相3.1 Console 面板上的关键字段tokio-console 打开后第一眼看到的是一堆字段很多人容易挑错重点。我的经验是优先盯这四类Tasks 总数当前存活的任务数量持续上涨通常意味着任务泄漏或并发失控。Polls某个任务被 poll 的次数。这是一个任务是否频繁被唤醒的重要信号。Poll time该任务所有 poll 消耗的总时长除以 Polls 可得平均耗时。如果平均 poll 耗时异常高说明 Future 内部有占用时间过长的同步逻辑。Wakers任务被唤醒的次数和来源。大量 waker 触发但任务又快速挂起往往意味着唤醒风暴。只看单个任务还不够我还会观察 worker 线程分布。如果多线程运行时有 3 个 worker 忙到冒烟另一个 worker 完全空闲那就要思考是不是窃取机制失效、任务都固定在一个本地队列里了。3.2 Poll 耗时最容易骗人的指标一个常见的误判是poll time很小就认为系统健康。不对。poll time 很小可能只说明任务经常处于等待状态真正要关注的是任务的大 poll长尾。比如某个任务平均 poll 时间只有 10 微秒但每隔几百次 poll 就会出现一次 50 毫秒的超长 poll这就是拖垮延迟抖动的元凶。为什么会出现长 poll因为 poll 里一旦执行了同步、阻塞代码整个 worker 线程都会被占住其他排队的任务全部停摆。这在 console 上表现的非常直观worker busy time 飙高、其他任务处于 scheduled 状态迟迟得不到执行。读这个指标时不要只看平均值至少看 p50、p95 或最大值分布。我习惯在 tokio-console 里按 poll time 排序把排在最前面的任务点开如果发现它们的 poll 耗时波动极大基本可以断定代码里有阻塞调用或者 CPU 密集计算没有拆成多个 poll 段。3.3 任务数、唤醒数、队列深度存活任务数高不一定代表问题。一个高并发的网关服务Task 数几千是很正常的。但如果任务数在无限上涨且同时有大量任务状态为 waiting那就是典型的只创建不回收。常见原因包括异步锁泄漏、channel 的 receiver 被丢弃、或者每次请求都 spawn 了额外的监督任务但这些任务永远等待某个信号。waker 数量是另一个容易被忽略的信号。tokio-console 会显示每个任务的本地唤醒和远程唤醒次数。如果某个任务的 waker 数量每秒暴涨通常意味着某个信号量或 channel 在反复通知所有等待者即使大部分等待者什么也没拿到。这种惊群式唤醒会把 worker 的调度时间耗光表现是 CPU 飙升、任务数不高但吞吐很差。队列深度方面如果 blocking 队列深度居高不下说明spawn_blocking的任务积压严重。这时就算 worker 线程再多也无济于事因为阻塞任务是另外一套线程池在跑你需要优化阻塞任务本身而不是盲目加 worker。4. 调优实战三个真实场景下的参数与代码改动4.1 场景一并发过高导致任务膨胀某个 API 网关在压测时任务数在 30 秒内从几千涨到几十万延迟随之恶化。console 里看到大量任务在等同一个下游连接池的信号量。无数个 Future 同时发起对数据库连接池的请求但连接池最多只有 20 个连接剩下的几十万任务全都挂起等待白白消耗内存和调度时间。这种问题不是靠增加连接数简单解决的而是要限流。我在应用层加了一个全局异步信号量限制同时进入数据库访问逻辑的任务数use std::sync::Arc; use tokio::sync::Semaphore; let semaphore Arc::new(Semaphore::new(512)); async fn query_with_limit(sem: ArcSemaphore, param: Param) - ResultData, Error { // acquire_owned 保证 permit 在任务结束后释放 let permit sem.acquire_owned().await?; let _permit permit; // 真正访问数据库 db_query(param).await }加上之后任务数稳定在几千不再无限膨胀。这里的核心思路是当系统无法提升下游处理能力时控制并发比盲目重试更有效。信号量上限的具体值需要通过压测逐步调整看任务数和延迟曲线找到拐点。4.2 场景二阻塞操作偷走了 worker 线程另一个线上项目出现了诡异现象 worker 数量 8 个压测时只有 2 个 worker 忙碌另外 6 个几乎空转接口延迟却很高。tokio-console 显示那 2 个 worker 上各有一个 poll 耗时 100ms 以上的任务而且它们反复出现。顺着 poll time 最高的任务继续定位发现业务代码调用了一个老旧的 SDK这个 SDK 内部做了一次同步 DNS 查找。在 Tokio 里直接执行同步 DNS 查询会把 worker 线程挂住 100ms这期间该 worker 无法调度其他任务。修复方式很简单把同步阻塞操作挪到spawn_blocking让 Tokio 用独立的阻塞线程池去执行let result tokio::task::spawn_blocking(move || { sync_sdk_query(id) }) .await??;注意spawn_blocking也不是银弹。如果高频调用阻塞线程池也会被占满需要控制并发或者干脆把同步 SDK 替换成异步版本。Tokio 的max_blocking_threads默认值是 512实际生产里如果业务高度依赖这种阻塞操作建议在构建 Runtime 时显式设置这个参数Builder::new_multi_thread() .max_blocking_threads(128) .build()4.3 场景三任务饥饿与不公平调度还有一次服务 CPU 只用了 40%但吞吐率上不去延迟毛刺很大。console 里看到某个任务的 poll 耗时虽然只有几毫秒但它被 poll 得非常频繁几乎霸占了某个 worker。再看其他任务大量时间停留在 scheduled 状态迟迟得不到执行。这是典型的单任务饿死别人。协作式调度下一个不停有事件触发的任务如果不主动让出执行权它就能一直占用 worker。解决办法是在长循环或大 chunk 处理中主动让出调度for chunk in large_data.chunks(1024) { process_chunk(chunk).await?; // 主动让出当前 worker给其他任务一个执行机会 tokio::task::yield_now().await; }yield_now()会立即返回 Pending然后在下一轮调度中被重新 poll。这就是把一个大任务切成多个小 poll 段消除不公平调度。对纯 CPU 密集计算来说更好的选择是干脆把它放到独立线程池里而不是和异步任务挤在一起。4.4 线程数、调度策略与全局配置调优实战里worker 线程数和队列参数往往被过度讨论。我个人的经验是worker 线程数不要盲调默认值等于 CPU 核数在很多场景下是合理的。真正要判断的是你的任务是 I/O 密集还是 CPU 密集。I/O 密集服务比如大量 await 网络请求、文件读写可以适量增加 worker 线程数让更多任务有机会并发执行。但要注意增加 worker 线程并不等于一定提升吞吐因为内核调度、内存访问争抢都会引入额外开销。CPU 密集服务则刚好相反worker 数接近核数就够了再往上加会导致上下文切换增多。更合理的做法是用spawn_blocking或独立线程池把 CPU 任务和 async 调度分离。构建 Runtime 时我通常还会开启enable_all()确保 I/O 驱动和定时器都可用。如果服务对延迟敏感可以关注tokio::runtime::RuntimeMetrics中关于任务调度的直方图数据这些数据能帮你验证调优前后的变化而不是凭感觉改配置。5. 常见问题与排查技巧实录5.1 任务数飙升但 CPU 不高这是典型的任务在等待信号。打开 console 看任务状态大概率是一大片 pending/waiting。说明系统里存在资源争抢锁、连接池、信号量或 channel 容量不足。先看被等待的资源是否存在泄漏比如连接池没有被归还、Semaphore 的 permit 没有释放。实践中我发现acquire().await之后如果用?提前返回permit 可能被丢弃导致信号量被长期占住。这种问题用acquire_owned()并把 Permit 绑定到任务生命周期上能明显改善。5.2 延迟抖动与 waker 大量唤醒如果你发现服务平均延迟低但 p99 很高且 console 上有任务的 waker 数量异常大要考虑唤醒风暴。比如用tokio::sync::watch广播状态大量任务订阅同一个消息每次状态变化所有订阅者都被唤醒但实际上只有少数任务需要响应。把 watch 换成broadcast并按业务分桶或者给每个任务独立的信号能显著减少无效唤醒。5.3 CPU 打满但吞吐上不去CPU 打满显然是有任务在忙但吞吐上不去说明忙的内容不是有效工作。优先看 poll time 高的任务确认有没有不必要的忙轮询。比如用tokio::time::interval做每 1ms 的循环循环里还涉及复杂计算可能就把 CPU 吃干榨净。另外检查异步锁 Mersenne 之类的地方不检查tokio::sync::Mutex的持锁时间。Tokio Mutex 不是公平锁一旦某个任务在某 worker 上不停抢锁其他 worker 上的任务可能一直等不到。这种情况下要么缩短临界区要么改用更细粒度的锁要么把对锁的需求转移到 channel 上。5.4 排查流程速查表现象可能原因排查手段解决方向任务数持续上涨任务泄漏、并发失控、信号量未释放console 看 tasks 增长趋势与任务状态限流、确保 Permit 被正确释放worker 分布不均衡长任务霸占单 worker、窃取失效console 按 worker 排序拆小 poll 段、yield_now、调整 worker 数延迟 p99 高某任务长 poll、waker 风暴按 poll time 排序看 waker 数量分离阻塞操作、控制广播信号频繁 spawn_blocking 后卡顿阻塞线程池耗尽看 blocking 队列深度控制阻塞任务并发、换异步 SDKCPU 高但无产出忙轮询、持锁等待看任务 poll 分布与锁等待时间用 channel/信号替换轮询、缩短临界区排查异步性能问题的顺序我自己固定成三步先看宏观指标worker 利用率、任务总数、队列深度再抓中间层日志trace span 耗时最后用 console 抓微观现场poll time、waker。定位到具体任务后不要急着改并发参数先搞清楚它到底是在等待资源还是在做无效计算否则调优往往变成撞运气。记录一次真实调优过程最后分享一个自己在项目里攒下的习惯每次启动新的 Tokio 服务我第一件事不是写业务代码而是把tracing-subscriber、console_subscriber和运行时 metrics 的初始化代码先写好。哪怕是临时 Demo也保持这个流程。因为这些监控代码在问题发生时再补往往已经来不及了你手头没有基线数据很难判断调优是否有效。正式环境里我会在 CI 里加一个压测任务压测期间开着 tokio-console 记录任务和 poll 数据把慢任务截图留档。这样每次版本迭代都能对照同一套压测模型看指标变化。依赖升级、运行时版本变更后也跑一遍同样的脚本避免性能回归在线上才爆发。这轮调优下来我最大的体会是Rust 异步性能问题之所以像黑盒通常不是运行时真的不可观测而是我们很少主动给这个盒子里装上仪表。Tokio 已经把监控接口摆在那里了剩下的就是花点时间把它接进自己的工程体系。下次再有人说异步出问题没法查我第一反应不是怀疑语言而是问他监控数据在哪

相关新闻

treehouse租约机制完全指南:用get --lease为自动化创建持久化隔离环境

treehouse租约机制完全指南:用get --lease为自动化创建持久化隔离环境

【免费下载链接】treehouse Manage worktrees without managing worktrees. 项目地址: https://gitcode.com/gh_mirrors/treehou/treehouse 点击查看 免费下载 treehouse 是一个管理 git worktree 池的命令行工具,核心理念是"Manage worktrees wit…

2026/10/11 22:46:30 阅读更多 →
Java基础核心梳理:从JVM运行机制、集合框架到并发编程

Java基础核心梳理:从JVM运行机制、集合框架到并发编程

这几年我参与过不少技术面试,也带过刚入行的新人,发现一个特别普遍的现象:很多同学能背出 ArrayList 和 LinkedList 的区别,但问他为什么 HashMap 线程不安全、String 为什么要设计成不可变、AQS 到底解决了什么问题,能…

2026/10/11 22:46:30 阅读更多 →
DeepSeek 与 Claude 接入哪个平台划算:2026 实测对比与成本口径参考

DeepSeek 与 Claude 接入哪个平台划算:2026 实测对比与成本口径参考

为什么要用聚合服务?直接对接多家厂商有三个痛点:境外模型支付与网络访问不便、多平台 Key 管理成本高、接口协议不统一。聚合平台用统一协议、简化接入、降低多模型管理成本来回应这些痛点。本文以 DeepSeek 与 Claude 两类最常用的模型为线索&#xff…

2026/10/11 22:46:30 阅读更多 →

最新新闻

头歌MySQL实训全关卡答案解析与避坑指南

头歌MySQL实训全关卡答案解析与避坑指南

简介:这是一份头歌MySQL数据库实训的答案整理文档,面向正在完成头歌平台实训作业的学生,也适合需要系统回顾MySQL核心操作的初学者。文档以PDF格式提供,共1个文件,压缩包大小433KB,配有目录结构&#xff0c…

2026/10/12 0:30:14 阅读更多 →
OpenClaw 下一代 AI 助手框架:让 AI 拥有记忆和工具,TaoToken 统一 Key 接入实战

OpenClaw 下一代 AI 助手框架:让 AI 拥有记忆和工具,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/12 0:30:14 阅读更多 →
身份证识别OCR实战:从图像预处理到字段解析的完整流程

身份证识别OCR实战:从图像预处理到字段解析的完整流程

简介:这是一份面向图像识别与OCR入门者的身份证识别项目实践资源,聚焦从身份证图片中自动提取身份证号及其他字段的完整实现。项目基于百度开源的PaddleOCR,针对中文识别效果做了优化,并编译了Windows可执行版本,可通过…

2026/10/12 0:30:14 阅读更多 →
Hyperf 中使用 Elasticsearch:协程化客户端封装与连接池实战指南

Hyperf 中使用 Elasticsearch:协程化客户端封装与连接池实战指南

后端Web框架微服务RPC框架异步编程 【免费下载链接】hyperf 🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease. 项目地址: https://gitcode.com/hyperf/hyperf 点击查看 免费下载 …

2026/10/12 0:30:14 阅读更多 →
指针仪表检测数据集实战:1000张图与三种标签格式的YOLO训练指南

指针仪表检测数据集实战:1000张图与三种标签格式的YOLO训练指南

简介:这份YOLO指针仪表目标检测数据集面向计算机、电子信息工程、数学等专业的学生与算法初学者,可用于课程设计、期末大作业和毕业设计中的目标检测训练与验证任务。压缩包共2000个文件,约20.25MB,包含1000张指针仪表图片&#x…

2026/10/12 0:30:14 阅读更多 →
基于深度学习的智慧教室:专注度分析与作弊检测实战

基于深度学习的智慧教室:专注度分析与作弊检测实战

简介:这份资源是面向计算机相关专业学生与项目实战学习者的智慧教室系统源码,核心围绕基于深度学习的课堂专注度分析与考试作弊检测两大功能展开,可作为毕业设计、课程设计或期末大作业的完整参考方案。压缩包共626个文件,约87.73…

2026/10/12 0:29:13 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 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/11 10:45:37 阅读更多 →
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/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练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/11 14:36:54 阅读更多 →