From f7e44114c0eb50d1373e3ca3762ee5974db4ee0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A1=A5=E4=B8=8B=E7=BA=A2=E8=8D=AF?= Date: Tue, 27 Jan 2026 22:55:20 +0800 Subject: [PATCH] update --- README.md | 277 ++++++++++++++++++++++++++------------------------ src/server.rs | 2 +- src/types.rs | 3 + 3 files changed, 149 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index ba9ca8e..fe4ecc7 100644 --- a/README.md +++ b/README.md @@ -4,177 +4,190 @@ [![Documentation](https://docs.rs/dht-crawler/badge.svg)](https://docs.rs/dht-crawler) [![License](https://img.shields.io/crates/l/dht-crawler.svg)](https://github.com/yourusername/dht-crawler/blob/master/LICENSE) -一个高性能的 Rust DHT(分布式哈希表)爬虫库,用于爬取 BitTorrent DHT 网络中的种子信息。 +一个基于 Rust 和 Tokio 实现的高性能分布式哈希表 (DHT) 爬虫库。它能够加入 BitTorrent DHT 网络,监听并自动获取种子的元数据(Metadata/InfoHash)。 -## 特性 +## ✨ 核心特性 -- 🚀 **高性能**:基于 Tokio 异步运行时,支持高并发处理 -- 🌐 **双栈支持**:同时支持 IPv4 和 IPv6(DualStack 模式) -- 📦 **自动元数据获取**:自动从对等节点获取完整的种子元数据 -- ⚡ **可配置并发**:支持自定义元数据获取并发数和队列大小 -- 🎯 **灵活回调**:提供多种回调接口,方便自定义处理逻辑 -- 📊 **监控支持**:内置统计和监控接口 +- **🚀 极致性能**:基于 `Tokio` 异步运行时构建,支持数万级的高并发连接处理。 +- **📦 自动元数据抓取**:内置元数据获取引擎,自动完成从 InfoHash 到种子详情的抓取。 +- **🌐 双栈网络支持**:完美支持 IPv4 和 IPv6(DualStack 模式),扩大节点覆盖范围。 +- **⚡ 高度可配置**:支持自定义并发数、队列大小、超时时间等核心参数。 +- **📊 监控友好**:提供 Prometheus 指标导出接口,轻松监控爬虫状态(可选)。 -## 安装 +## 🏗️ 架构与流程 -在 `Cargo.toml` 中添加依赖: +本库采用了 **Reactor 模式** 与 **Worker Pool** 相结合的高并发架构,确保了在处理海量 UDP 数据包时的吞吐量。 + +### 系统架构图 + +```mermaid +graph TD + %% 网络层 + Network((DHT Network)) <-->|UDP Packets| Socket[UDP Socket] + + %% 接收与分发 + subgraph Receiver [Packet Receiver] + Socket -->|recv_from| Reader[UDP Reader / Dispatcher] + Reader -->|Round Robin| Ch1[Channel 1] + Reader -->|Round Robin| Ch2[Channel 2] + Reader -->|...| ChN[Channel N] + end + + %% 并行处理 + subgraph Processing [Packet Processing Workers] + Ch1 --> W1[Worker 1] + Ch2 --> W2[Worker 2] + ChN --> WN[Worker N] + + W1 & W2 & WN -->|Parse & Logic| Logic{Protocol Logic} + end + + %% 业务逻辑分支 + Logic -->|Discover Node| NodeMgr[Node Queue] + Logic -->|Discover InfoHash| HashQ[Hash Queue] + + %% 元数据抓取子系统 + subgraph Metadata [Metadata Subsystem] + HashQ --> Scheduler[Scheduler] + Scheduler -->|Spawn| MetaW1[Meta Worker 1] + Scheduler -->|...| MetaWN[Meta Worker N] + + MetaW1 & MetaWN <-->|TCP / ut_metadata| Peer((Remote Peer)) + end + + MetaW1 & MetaWN -->|Success| Callback[User Callback] +``` + +### 核心流程解析 + +1. **UDP 读取与分发 (Reader & Dispatcher)**: + * 独立的 UDP Reader 任务持续从 Socket 读取数据包。 + * 使用 Round-Robin 策略将数据包分发给 N 个(默认为 CPU 核心数)处理 Channel,实现无锁的负载均衡。 + +2. **并行协议处理 (Packet Workers)**: + * N 个 Packet Worker 并行消费 Channel 中的数据。 + * 负责 Bencode 解码、KRPC 协议解析、消息路由(Query/Response)。 + * 高效处理 `get_peers` 和 `announce_peer` 消息,提取 InfoHash。 + +3. **元数据调度 (Metadata Subsystem)**: + * 提取出的 InfoHash 进入独立的 Hash Queue。 + * Scheduler 根据配置的并发度(如 1000+)动态启动 Metadata Worker。 + * Worker 通过 TCP 连接 Peer,使用 BEP-0009 协议下载种子元数据。 + +## 📦 安装 + +在你的 `Cargo.toml` 中添加依赖: ```toml [dependencies] -dht-crawler = "0.0.6" +dht-crawler = "0.1" ``` -或者查看 [crates.io](https://crates.io/crates/dht-crawler) 获取最新版本号。 - -### 启用可选 Features - -如果需要使用 Prometheus 指标支持,可以启用 `metrics` feature: +如果需要 **Prometheus 监控支持**: ```toml [dependencies] -dht-crawler = { version = "0.0.6", features = ["metrics"] } +dht-crawler = { version = "0.1", features = ["metrics"] } ``` -## Features +## 🚀 快速开始 -本库支持以下可选特性: +下面是一个最简的启动示例。它会启动一个 DHT 节点,并在抓取到新种子时打印日志。 +```rust +use dht_crawler::prelude::*; +use std::sync::Arc; -> **⚠️ 重要说明:特性支持限制** -> -> - **`--lib` 编译库时**:**仅支持 `metrics` 可选特性** -> - **`mimalloc` feature**:仅用于编译 examples(位于 `dev-dependencies`),库本身不依赖 mimalloc -> - 如果需要同时使用 `mimalloc` 和 `metrics`,请使用 `--examples` 编译示例程序 +#[tokio::main] +async fn main() -> Result<()> { + // 1. 配置爬虫参数 + let options = DHTOptions { + port: 12313, + auto_metadata: true, // 开启自动元数据获取 + ..Default::default() + }; + // 2. 初始化 Server + let server = DHTServer::new(options).await?; + println!("DHT Server 启动于端口 12313..."); -### `mimalloc` - 高性能内存分配器 + // 3. 注册回调函数:当成功获取到种子元数据时触发 + server.on_torrent(move |torrent| { + println!("🎉 抓取成功: {} (文件数: {})", torrent.name, torrent.files.len()); + }); -使用 `mimalloc` 作为全局内存分配器,可以显著降低内存占用(通常降低 10-30%),特别适合长时间运行的高并发场景。 - -### `metrics` - Prometheus 指标支持 - -启用 `metrics` feature 后,库会通过 `metrics` crate 暴露统计指标,可以与 Prometheus 等监控系统集成。 - -**注意**: -- `mimalloc` 和 `metrics-exporter-prometheus` 仅在编译 example 时可用(位于 `dev-dependencies`) -- 使用 example 时需要显式启用对应的 features -- 库本身可以使用 `metrics` feature(通过 `[dependencies]` 中的可选依赖) - -## 快速开始 - -### 基本使用 - -请参考 `examples/main.rs` 查看完整的使用示例。 - -### 编译示例 - -#### 基本编译(不启用任何 features) - -```bash -# Debug 模式 -cargo build --example dht_crawler_example - -# Release 模式 -cargo build --release --example dht_crawler_example + // 4. 启动服务 + server.start().await?; + Ok(()) +} ``` -#### 启用 mimalloc(推荐) +*完整的可运行代码请参考 [examples/main.rs](examples/main.rs)* -```bash -# Debug 模式 -cargo build --example dht_crawler_example --features mimalloc +## ⚙️ 配置详解 -# Release 模式(推荐用于生产环境) -cargo build --release --example dht_crawler_example --features mimalloc +`DHTOptions` 提供了丰富的配置项来调整爬虫行为: + +```rust +let options = DHTOptions { + // 监听端口 + port: 12313, + + // 网络模式:Ipv4Only, Ipv6Only, 或 DualStack (默认) + netmode: NetMode::Ipv4Only, + + // 是否自动尝试从 peers 获取元数据 + auto_metadata: true, + + // 元数据获取超时时间 (秒) + metadata_timeout: 5, + + // 元数据下载队列大小,建议根据内存大小调整 + max_metadata_queue_size: 100000, + + // 同时进行元数据下载的并发任务数 + max_metadata_worker_count: 1000, + + ..Default::default() +}; ``` -#### 启用 metrics(Prometheus 指标导出) +## 🛠️ 性能优化与编译选项 +为了在生产环境中获得最佳性能,本库提供了几个可选的 Feature 和编译建议。 + +### 1. 启用 `mimalloc` (内存优化) + +在长运行的高并发场景下,使用 `mimalloc` 替代默认内存分配器可以降低 10-30% 的内存占用。 + +**运行示例代码:** ```bash -# 启用 metrics feature -cargo build --example dht_crawler_example --features metrics - -# Release 模式 -cargo build --release --example dht_crawler_example --features metrics +cargo run --release --example dht_crawler_example --features mimalloc ``` -#### 同时启用 mimalloc 和 metrics +**在项目中使用:** +只需在你的 `Cargo.toml` 和 `main.rs` 中配置全局分配器即可(无需依赖本库的 feature,直接引入 mimalloc crate)。 +### 2. 启用 `metrics` (监控) + +启用后,可以通过 HTTP 接口拉取 Prometheus 格式的监控数据。 + +**启动带监控的示例:** ```bash -# Debug 模式 -cargo build --example dht_crawler_example --features mimalloc,metrics - -# Release 模式(推荐) -cargo build --release --example dht_crawler_example --features mimalloc,metrics +cargo run --release --example dht_crawler_example --features metrics ``` +*监控地址:http://localhost:9000/metrics* -#### 交叉编译(Linux) +### 3. 交叉编译 (Linux) + +推荐使用以下命令编译 Linux 生产环境版本: ```bash -# 编译 Linux 版本(推荐使用 mimalloc 以获得更好的内存性能) cargo build --release --target x86_64-unknown-linux-gnu --examples --features mimalloc,metrics - -# 编译后的可执行文件位于: -# target/x86_64-unknown-linux-gnu/release/examples/dht_crawler_example ``` -> **⚠️ 重要说明:交叉编译特性支持** -> -> - 使用 `cargo build --lib` 编译库时,**仅支持 `metrics` 可选特性** -> - `mimalloc` feature 仅在编译 examples 时可用(位于 `dev-dependencies`) -> - 如果需要同时使用 `mimalloc` 和 `metrics`,请使用 `cargo build --examples` 编译示例 +> **注意**:`mimalloc` feature 主要是为了方便示例程序 (`examples/`) 的编译。在将其作为库引用时,建议你在自己的 `bin` 项目中独立配置内存分配器。 -### 运行示例 - -#### 基本运行(不使用任何 features) - -```bash -cargo run --example dht_crawler_example -``` - -#### 启用 mimalloc 运行 - -```bash -cargo run --example dht_crawler_example --features mimalloc -``` - -#### 启用 metrics 运行 - -启用 metrics 后,Prometheus metrics 导出器会在 `http://localhost:9000/metrics` 启动。 - -```bash -cargo run --example dht_crawler_example --features metrics -``` - -然后在浏览器或使用 curl 访问: -```bash -curl http://localhost:9000/metrics -``` - -#### 同时启用 mimalloc 和 metrics(推荐) - -```bash -cargo run --example dht_crawler_example --features mimalloc,metrics -``` - -### 在项目中使用 Features - -#### 使用库本身(不带任何 features) - -```toml -[dependencies] -dht-crawler = "0.0.6" -``` - -#### 使用库并启用 metrics feature - -```toml -[dependencies] -dht-crawler = { version = "0.0.6", features = ["metrics"] } -``` - -这样可以在你的代码中使用库暴露的 metrics 指标。 - -## 许可证 +## 📜 许可证 MIT License diff --git a/src/server.rs b/src/server.rs index 3f85ca2..91685e6 100644 --- a/src/server.rs +++ b/src/server.rs @@ -138,7 +138,7 @@ impl DHTServer { let node_queue = ShardedNodeQueue::new(options.node_queue_capacity); - let (hash_tx, hash_rx) = mpsc::channel::(10000); + let (hash_tx, hash_rx) = mpsc::channel::(options.hash_queue_capacity); let fetcher = Arc::new(RbitFetcher::new(options.metadata_timeout)); diff --git a/src/types.rs b/src/types.rs index 6e15b55..caeb1ea 100644 --- a/src/types.rs +++ b/src/types.rs @@ -66,6 +66,8 @@ pub struct DHTOptions { pub netmode: NetMode, pub node_queue_capacity: usize, + + pub hash_queue_capacity: usize, } impl Default for DHTOptions { @@ -78,6 +80,7 @@ impl Default for DHTOptions { max_metadata_worker_count: 1000, netmode: NetMode::Ipv4Only, node_queue_capacity: 100000, + hash_queue_capacity: 10000, } } }