proxy manager
npm install proxy-pool-manager一个功能强大的代理管理器 SDK,提供代理管理、HTTP 请求封装、自动代理轮换和健康检查等功能。
- 🪶 轻量级模式:无需 MongoDB,仅使用请求和队列功能
- 🔄 智能代理管理:支持从 MongoDB 加载代理,自动验证和轮换(可选)
- 🌐 HTTP 请求封装:内置 HTTP 客户端,支持自动代理切换或直接指定代理
- 📊 代理健康检查:自动检测代理可用性,支持自定义检测规则(可选)
- 🎯 多种代理策略:支持顺序、随机、故障转移三种策略
- 📦 批量操作:支持批量插入和管理代理
- 🔍 日志系统:基于 Winston 的完整日志记录
- ⚡ 异步队列:高效的异步任务处理机制
- 🛡️ 类型安全:完整的 TypeScript 类型定义
``bash`
npm install proxy-pool-manager
如果你只需要使用 HTTP 请求和队列功能,不需要代理管理,可以使用轻量级模式:
`typescript
import { createProxyRequest } from 'proxy-pool-manager';
// 创建轻量级 SDK 实例(不连接 MongoDB)
const sdk = await createProxyRequest({
maxRetries: 3,
timeout: 30,
logLevel: 'info'
});
// 发送 GET 请求
const response = await sdk.get('https://api.example.com/data', {
params: { page: 1 }
});
// 在请求中直接指定代理(可选)
const responseWithProxy = await sdk.post('http://your-api.com/request', {
url: 'https://api.example.com/data',
method: 'GET',
proxy: 'http://proxy.example.com:8080', // 直接指定代理
timeout: 10
});
console.log(response.data);
`
如果你需要代理管理但不想连接 MongoDB,可以传入代理数组:
`typescript
import { createProxyRequest } from 'proxy-pool-manager';
// 创建轻量级 SDK 实例 + 代理数组(不连接 MongoDB)
const sdk = await createProxyRequest({
proxies: [
'proxy1.example.com:8080:user1:pass1',
'proxy2.example.com:8080:user2:pass2',
'proxy3.example.com:8080:user3:pass3'
],
proxyStrategy: 'sequential', // 顺序策略
maxRetries: 3,
timeout: 30,
logLevel: 'info'
});
// 发送请求,会自动使用代理管理器选择的代理
// 如果代理失败,会自动轮换到下一个代理并重试
const response = await sdk.post('http://your-api.com/request', {
url: 'https://api.example.com/data',
method: 'GET',
timeout: 10
});
console.log('当前使用的代理:', sdk.getCurrentProxy());
console.log('可用代理列表:', sdk.getAvailableProxies());
`
如果需要代理管理功能(自动轮换、健康检查等),需要提供 MongoDB 连接:
`typescript
import { createProxyRequest } from 'proxy-pool-manager';
// 创建完整 SDK 实例(包含代理管理)
const sdk = await createProxyRequest({
mongoUri: 'mongodb://localhost:27017/proxy_db',
proxyStrategy: 'sequential',
logLevel: 'info',
timeout: 30,
proxyCheckOptions: {
mainUrl: 'http://example.com/check',
timeout: 10,
}
});
// 发送 GET 请求(自动使用代理管理器选择的代理)
const response = await sdk.get('https://api.example.com/data', {
params: { page: 1 }
});
// 或者为特定请求指定代理(优先级高于自动选择)
const responseWithSpecificProxy = await sdk.post('http://your-api.com/request', {
url: 'https://api.example.com/data',
method: 'GET',
proxy: 'http://specific-proxy.com:8080', // 请求级代理优先
timeout: 10
});
console.log(response.data);
`
如果需要代理管理功能,并且想预先设置代理列表:
`typescript
import { createProxyRequest } from 'proxy-pool-manager';
// 创建完整 SDK 实例 + 代理数组(连接 MongoDB)
const sdk = await createProxyRequest({
mongoUri: 'mongodb://localhost:27017/proxy_db',
proxies: [
'proxy1.example.com:8080:user1:pass1',
'proxy2.example.com:8080:user2:pass2',
'proxy3.example.com:8080:user3:pass3'
],
proxyStrategy: 'failover', // 故障转移策略
maxRetries: 3,
timeout: 30,
proxyCheckOptions: {
mainUrl: 'http://example.com/check',
timeout: 10,
}
});
// 代理会被保存到 MongoDB,并支持自动轮换
// 如果请求失败,会自动轮换到下一个代理并重试
const response = await sdk.get('https://api.example.com/data');
`
`typescript
// 添加单个代理
await sdk.addProxy('proxy.example.com:8080:username:password');
// 批量添加代理
const count = await sdk.bulkInsertProxies([
'proxy1.example.com:8080:user1:pass1',
'proxy2.example.com:8080:user2:pass2',
'proxy3.example.com:8080:user3:pass3',
]);
console.log(成功添加 ${count} 个代理);`
`typescript
// GET 请求
const getResponse = await sdk.get('https://api.example.com/users', {
params: { page: 1, limit: 10 }
});
// POST 请求
const postResponse = await sdk.post('https://api.example.com/users', {
data: { name: 'John', email: 'john@example.com' },
headers: { 'Content-Type': 'application/json' }
});
// PUT 请求
const putResponse = await sdk.put('https://api.example.com/users/1', {
data: { name: 'Jane' }
});
// DELETE 请求
const deleteResponse = await sdk.delete('https://api.example.com/users/1');
// PATCH 请求
const patchResponse = await sdk.patch('https://api.example.com/users/1', {
data: { status: 'active' }
});
// 自定义请求
const customResponse = await sdk.request({
url: 'https://api.example.com/custom',
method: 'POST',
options: {
data: { custom: 'data' },
timeout: 60,
proxy: 'specific-proxy.com:8080' // 使用特定代理
}
});
`
主 SDK 类,提供统一的 API 接口。
#### 构造函数选项
`typescript`
interface SDKOptions {
mongoUri?: string; // MongoDB 连接 URI(可选,启用代理管理时需要)
maxRetries?: number; // 最大重试次数,默认 3
timeout?: number; // 请求超时时间(秒),默认 30
proxyStrategy?: ProxyStrategy; // 代理策略,默认 'sequential'
logLevel?: LogLevel; // 日志级别,默认 'info'
instanceId?: string; // 实例 ID,用于多实例场景
proxies?: string[]; // 代理数组,支持异常时自动轮换
proxy?: string; // 单个代理
retryDelay?: number; // 重试间隔(毫秒),默认使用指数退避策略
retryDelayBase?: number; // 指数退避的基础延迟(毫秒),默认 1000
retryDelayMultiplier?: number; // 指数退避的倍数,默认 2
proxyCheckEnabled?: boolean; // 是否启用代理检查,默认 true
proxyLimit?: number; // 代理加载限制,0 表示不加载,默认 0
proxyCheckOptions?: { // 代理检查配置(启用代理管理时需要)
mainUrl: string; // 代理检查主 URL(启用代理管理时必需)
testUrls?: string[]; // 额外的测试 URL
timeout?: number; // 检查超时时间(秒)
successStatusCodes?: number[]; // 成功状态码列表
checkInterval?: number; // 检查间隔(毫秒)
maxConsecutiveFails?: number; // 最大连续失败次数
maxResponseTime?: number; // 最大响应时间(毫秒)
};
}
配置说明:
- 轻量级模式:不提供 mongoUri 和 proxyCheckOptions,SDK 将以轻量级模式运行,不连接 MongoDB,不初始化代理管理功能proxies
- 轻量级模式 + 代理数组:提供 或 proxy 但不提供 mongoUri,SDK 将以轻量级模式运行,代理仅存储在内存中,支持异常时自动轮换mongoUri
- 完整模式:提供 或 proxyCheckOptions,SDK 将启用代理管理功能mongoUri
- 完整模式 + 代理数组:同时提供 和 proxies,代理会被保存到 MongoDB,并支持异常时自动轮换proxyCheckEnabled: false
- 禁用代理检查:设置 可禁用代理检查proxyLimit: 0
- 不加载代理:设置 可不从数据库加载代理
#### 方法
##### 请求方法
- getpost
- put
- delete
- patch
- request
-
##### 代理管理方法(仅在启用代理管理功能时可用)
- addProxy(proxyUrl: string): Promise - 添加代理deleteProxy(proxyUrl: string): Promise
- - 删除代理getAvailableProxies(): string[]
- - 获取可用代理列表getCurrentProxy(): string | null
- - 获取当前使用的代理rotateProxy(): Promise
- - 轮换到下一个代理setProxyStrategy(strategy: ProxyStrategy): void
- - 设置代理策略checkProxy(proxy?: string): Promise
- - 检查代理可用性triggerProxyCheck(): Promise
- - 触发代理检查getProxyDetails(proxyUrl: string): ProxyItem | undefined
- - 获取代理详情hasProxyManagement(): boolean
- - 检查是否启用了代理管理功能
##### 批量操作
- bulkInsertProxies(proxyUrls: string[]): Promise - 批量插入代理
##### 统计信息
- getProxyStats(): Promise - 获取代理统计信息getQueueStats(): QueueStats
- - 获取队列统计信息
##### 工具方法
- waitForReady(): Promise - 等待初始化完成setLogLevel(level: LogLevel): void
- - 设置日志级别getLogLevel(): LogLevel
- - 获取当前日志级别getInstanceId(): string
- - 获取实例 IDdestroy(): Promise
- - 清理资源
支持三种代理选择策略,每种策略都有不同的使用场景和特点:
#### 1. sequential(顺序策略)
特点:
- 按照代理列表的顺序依次使用代理
- 每次请求后自动切换到下一个代理
- 简单、可预测,适合需要均匀分配请求的场景
使用场景:
- 需要均匀分配请求到各个代理
- 代理质量相近,不需要特别优化
- 需要可预测的代理使用顺序
示例:
`typescript
const sdk = await createProxyRequest({
proxies: [
'proxy1.example.com:8080:user1:pass1',
'proxy2.example.com:8080:user2:pass2',
'proxy3.example.com:8080:user3:pass3'
],
proxyStrategy: 'sequential'
});
// 第一次请求使用 proxy1
const response1 = await sdk.get('https://api.example.com/data');
// 第二次请求使用 proxy2
const response2 = await sdk.get('https://api.example.com/data');
// 第三次请求使用 proxy3
const response3 = await sdk.get('https://api.example.com/data');
// 第四次请求又回到 proxy1(循环)
`
轮换机制:
- 请求失败时,自动切换到下一个代理并重试
- 如果所有代理都失败,停止重试
#### 2. random(随机策略)
特点:
- 从可用代理中随机选择一个使用
- 避免重复使用同一个代理,直到所有代理都被使用过
- 适合需要避免代理被过度使用的场景
使用场景:
- 需要避免某些代理被过度使用
- 代理质量相近,随机分配即可
- 需要分散请求负载
示例:
`typescript
const sdk = await createProxyRequest({
proxies: [
'proxy1.example.com:8080:user1:pass1',
'proxy2.example.com:8080:user2:pass2',
'proxy3.example.com:8080:user3:pass3'
],
proxyStrategy: 'random'
});
// 每次请求随机选择一个代理
const response1 = await sdk.get('https://api.example.com/data');
const response2 = await sdk.get('https://api.example.com/data');
const response3 = await sdk.get('https://api.example.com/data');
`
轮换机制:
- 随机选择代理,避免重复使用
- 当所有代理都被使用过后,重置使用记录
- 请求失败时,从剩余未使用的代理中随机选择并重试
#### 3. failover(故障转移策略)⭐ 推荐
特点:
- 智能选择最佳可用代理
- 根据代理的历史表现(失败率、响应时间)自动选择最优代理
- 优先使用失败率低、响应时间短的代理
- 适合需要高可用性和性能的场景
- 不需要 MongoDB:统计信息存储在内存中,实时更新
选择优先级:
1. 连续失败次数:优先选择连续失败次数最少的代理
2. 失败率:在连续失败次数相同的情况下,选择失败率最低的代理
3. 响应时间:在失败率相同的情况下,选择平均响应时间最短的代理
使用场景:
- 需要高可用性和性能的场景
- 代理质量差异较大,需要自动选择最优代理
- 需要自动排除故障代理
- 对请求成功率要求较高的场景
- 轻量级模式:不需要 MongoDB,仅使用内存统计
示例:
`typescript
// 轻量级模式 + failover(不需要 MongoDB)
const sdk1 = await createProxyRequest({
proxies: [
'proxy1.example.com:8080:user1:pass1', // 高质量代理
'proxy2.example.com:8080:user2:pass2', // 中等质量代理
'proxy3.example.com:8080:user3:pass3' // 低质量代理
],
proxyStrategy: 'failover' // 不需要 MongoDB,统计信息存储在内存中
});
// 自动选择最优代理(失败率低、响应时间短)
const response = await sdk1.get('https://api.example.com/data');
`
`typescript
// 完整模式 + failover(使用 MongoDB 持久化统计信息)
const sdk2 = await createProxyRequest({
mongoUri: 'mongodb://localhost:27017/proxy_db',
proxies: [
'proxy1.example.com:8080:user1:pass1',
'proxy2.example.com:8080:user2:pass2',
'proxy3.example.com:8080:user3:pass3'
],
proxyStrategy: 'failover',
proxyCheckOptions: {
mainUrl: 'http://example.com/check'
}
});
// 统计信息会被持久化到 MongoDB,重启后仍然保留历史数据
const response = await sdk2.get('https://api.example.com/data');
`
统计信息说明:
- 内存模式(不提供 mongoUri):
- 统计信息存储在内存中,实时更新
- 重启后统计信息会重置
- 适合临时使用或单次运行场景
- 持久化模式(提供 mongoUri):
- 统计信息会保存到 MongoDB
- 重启后仍然保留历史数据
- 适合长期运行或需要历史数据的场景
轮换机制:
- 请求失败时,自动标记当前代理的失败次数
- 下次请求时,自动选择表现最好的代理
- 连续失败超过阈值的代理会被标记为无效,不再使用
- 代理恢复后(成功请求),会自动重新启用
故障转移流程:
`text`
1. 选择最优代理(连续失败次数最少 → 失败率最低 → 响应时间最短)
2. 发送请求
3. 如果失败:
- 增加代理的失败计数
- 如果连续失败次数超过阈值,标记为无效
- 下次请求时自动选择下一个最优代理
4. 如果成功:
- 重置连续失败次数
- 更新平均响应时间
- 如果之前被标记为无效,自动恢复为有效状态
性能优化:
- 自动排除故障代理,避免重复尝试
- 优先使用高质量代理,提高成功率
- 动态调整代理优先级,适应代理质量变化
重要说明:
- ✅ 不需要 MongoDB:failover 策略可以在轻量级模式下使用,统计信息存储在内存中
- ✅ 实时更新:每次请求后,统计信息会立即更新(成功/失败次数、响应时间等)
- ✅ 自动学习:随着请求的进行,系统会自动学习每个代理的质量,并优先使用高质量代理
- 💡 MongoDB 的作用:如果提供 MongoDB,统计信息会被持久化,重启后仍然保留历史数据,有助于更快地识别高质量代理
支持两种重试间隔策略:
#### 1. 指数退避策略(默认)
每次重试前等待时间递增,适合大多数场景:
`typescript
const sdk = await createProxyRequest({
maxRetries: 3,
retryDelayBase: 1000, // 基础延迟 1000ms(默认)
retryDelayMultiplier: 2 // 倍数 2(默认)
});
// 重试间隔:第1次 1000ms,第2次 2000ms,第3次 4000ms
`
计算公式: waitTime = retryDelayBase × retryDelayMultiplier^(attempt-1)
示例:
- 第1次重试:1000ms × 2^0 = 1000ms
- 第2次重试:1000ms × 2^1 = 2000ms
- 第3次重试:1000ms × 2^2 = 4000ms
#### 2. 固定间隔策略
每次重试前等待固定时间,适合需要稳定重试间隔的场景:
`typescript
const sdk = await createProxyRequest({
maxRetries: 3,
retryDelay: 2000 // 每次重试都等待 2000ms
});
// 重试间隔:每次都是 2000ms
`
使用场景:
- 指数退避:适合网络不稳定、需要避免服务器压力的场景
- 固定间隔:适合需要稳定重试节奏、便于调试的场景
自定义配置示例:
`typescript
// 快速重试(500ms 基础,1.5倍递增)
const sdk1 = await createProxyRequest({
retryDelayBase: 500,
retryDelayMultiplier: 1.5
// 重试间隔:500ms → 750ms → 1125ms
});
// 慢速重试(2000ms 基础,2倍递增)
const sdk2 = await createProxyRequest({
retryDelayBase: 2000,
retryDelayMultiplier: 2
// 重试间隔:2000ms → 4000ms → 8000ms
});
// 固定间隔 3 秒
const sdk3 = await createProxyRequest({
retryDelay: 3000
// 重试间隔:每次都是 3000ms
});
`
- none - 不记录日志error
- - 仅记录错误warn
- - 记录警告和错误info
- - 记录信息、警告和错误(默认)debug
- - 记录调试信息verbose
- - 记录所有详细信息
#### 场景 1:仅需要 HTTP 请求功能(推荐轻量级模式)
`typescript
// 不需要代理管理,只需要发送 HTTP 请求
const sdk = await createProxyRequest({
maxRetries: 3,
timeout: 30,
logLevel: 'info'
});
// 直接使用,无需 MongoDB
const response = await sdk.get('https://api.example.com/data');
`
#### 场景 2:需要临时使用代理
`typescript
// 轻量级模式 + 直接指定代理
const sdk = await createProxyRequest({
maxRetries: 3,
timeout: 30
});
// 在请求中直接指定代理
const response = await sdk.post('http://your-api.com/request', {
url: 'https://api.example.com/data',
method: 'GET',
proxy: 'http://proxy.example.com:8080:user:pass' // 直接指定代理
});
`
#### 场景 2.5:使用代理数组 + 异常时自动轮换(推荐)
`typescript
// 轻量级模式 + 代理数组(不连接 MongoDB)
const sdk = await createProxyRequest({
proxies: [
'proxy1.example.com:8080:user1:pass1',
'proxy2.example.com:8080:user2:pass2',
'proxy3.example.com:8080:user3:pass3'
],
proxyStrategy: 'failover', // 故障转移策略
maxRetries: 3,
timeout: 30
});
// 发送请求,如果代理失败会自动轮换到下一个代理
const response = await sdk.post('http://your-api.com/request', {
url: 'https://api.example.com/data',
method: 'GET',
timeout: 10
});
`
#### 场景 3:需要代理管理功能
`typescript
// 完整模式,启用代理管理
const sdk = await createProxyRequest({
mongoUri: 'mongodb://localhost:27017/proxy_db',
proxyCheckOptions: {
mainUrl: 'http://example.com/check',
timeout: 10,
}
});
// 添加代理到管理器
await sdk.addProxy('proxy1.example.com:8080:user1:pass1');
// 自动使用代理管理器选择的代理
const response = await sdk.get('https://api.example.com/data');
`
#### 场景 4:禁用代理检查,但仍使用代理管理
`typescript
// 使用代理管理,但禁用代理检查
const sdk = await createProxyRequest({
mongoUri: 'mongodb://localhost:27017/proxy_db',
proxyCheckEnabled: false, // 禁用代理检查
proxyLimit: 0, // 不加载代理
proxyCheckOptions: {
mainUrl: 'http://example.com/check', // 仍然需要提供(用于后续启用)
}
});
// 手动添加代理,不进行自动检查
await sdk.addProxy('proxy.example.com:8080:user:pass');
`
`typescript
import { initializeServices } from 'proxy-pool-manager';
// 创建多个独立的 SDK 实例
const sdk1 = await initializeServices({
mongoUri: 'mongodb://localhost:27017/proxy_db',
instanceId: 'instance-1',
proxyCheckOptions: {
mainUrl: 'http://example.com/check'
}
});
const sdk2 = await initializeServices({
mongoUri: 'mongodb://localhost:27017/proxy_db',
instanceId: 'instance-2',
proxyCheckOptions: {
mainUrl: 'http://example.com/check'
}
});
`
`typescript`
const sdk = await createProxyRequest({
mongoUri: 'mongodb://localhost:27017/proxy_db',
proxyCheckOptions: {
mainUrl: 'https://httpbin.org/ip',
testUrls: [
'https://api.ipify.org?format=json',
'https://ipinfo.io/json'
],
timeout: 15,
successStatusCodes: [200, 201],
checkInterval: 60000, // 每分钟检查一次
maxConsecutiveFails: 3, // 连续失败3次后标记为无效
maxResponseTime: 5000 // 最大响应时间5秒
}
});
#### 1. 直接指定代理(轻量级模式和完整模式都支持)
`typescript`
// 为特定请求指定代理(优先级最高)
const response = await sdk.post('http://your-api.com/request', {
url: 'https://api.example.com/data',
method: 'GET',
proxy: 'http://proxy.example.com:8080:user:pass', // 直接指定代理
timeout: 10
});
#### 2. 使用代理数组(支持异常时自动轮换)
`typescript
// 创建 SDK 时传入代理数组
const sdk = await createProxyRequest({
proxies: [
'proxy1.example.com:8080:user1:pass1',
'proxy2.example.com:8080:user2:pass2',
'proxy3.example.com:8080:user3:pass3'
],
proxyStrategy: 'sequential', // 顺序策略
maxRetries: 3
});
// 发送请求,会自动使用代理管理器选择的代理
// 如果代理失败,会自动轮换到下一个代理并重试
const response = await sdk.post('http://your-api.com/request', {
url: 'https://api.example.com/data',
method: 'GET',
timeout: 10
});
// 查看当前使用的代理
console.log('当前代理:', sdk.getCurrentProxy());
console.log('可用代理:', sdk.getAvailableProxies());
`
#### 3. 自动使用代理管理器选择的代理(完整模式)
`typescript
// 先添加代理到管理器
await sdk.addProxy('proxy1.example.com:8080:user1:pass1');
await sdk.addProxy('proxy2.example.com:8080:user2:pass2');
// 不指定代理,自动使用代理管理器选择的代理
const response = await sdk.post('http://your-api.com/request', {
url: 'https://api.example.com/data',
method: 'GET',
// 不指定 proxy,会自动使用 ProxyManager 选择的代理
timeout: 10
});
`
#### 4. 代理优先级
代理使用遵循以下优先级:
1. 请求级代理(options.proxy)- 最高优先级,总是优先使用
2. 代理管理器自动选择 - 如果启用了代理管理且没有指定请求级代理
3. 无代理 - 如果都没有,则直接请求(不使用代理)
#### 5. 异常时自动轮换
当请求失败时(超时、连接错误等),系统会自动轮换到下一个代理并重试:
`typescript
const sdk = await createProxyRequest({
proxies: [
'proxy1.example.com:8080:user1:pass1',
'proxy2.example.com:8080:user2:pass2',
'proxy3.example.com:8080:user3:pass3'
],
proxyStrategy: 'failover', // 推荐使用故障转移策略
maxRetries: 3 // 最多重试3次,每次失败会自动轮换代理
});
// 如果 proxy1 失败,会自动尝试 proxy2,再失败会尝试 proxy3
const response = await sdk.get('https://api.example.com/data');
`
轮换机制说明:
- 只有在使用代理管理器选择的代理时才会轮换(如果请求中直接指定了代理,不会轮换)
- 支持两种重试间隔策略:
- 指数退避策略(默认):每次重试前等待时间递增,公式为 retryDelayBase × retryDelayMultiplier^(attempt-1)retryDelay
- 默认值:基础延迟 1000ms,倍数 2
- 示例:第1次重试等待 1000ms,第2次等待 2000ms,第3次等待 4000ms
- 固定间隔策略:设置 后,每次重试前等待固定时间retryDelay: 2000
- 示例:设置 ,每次重试都等待 2000ms
- 支持三种代理策略,每种策略的轮换方式不同:
- sequential:按顺序切换到下一个代理
- random:从剩余未使用的代理中随机选择
- failover:自动选择表现最好的代理(推荐)
不同策略的轮换行为:
| 策略 | 首次选择 | 失败后轮换 | 特点 |
|------|---------|-----------|------|
| sequential | 第一个代理 | 按顺序切换到下一个 | 简单、可预测 |
| random | 随机选择 | 从剩余代理中随机选择 | 分散负载 |
| failover | 最优代理 | 选择下一个最优代理 | 智能、高效 ⭐ |
故障检测:
系统会自动检测以下类型的错误并触发代理轮换:
- 连接超时(TimeoutError)
- 连接被拒绝(ECONNREFUSED)
- 网络错误(网络相关关键词)
- HTTP 错误(根据配置)
代理状态管理:
- 连续失败超过阈值的代理会被标记为无效
- 无效代理不会参与选择,直到恢复
- 代理恢复后(成功请求),会自动重新启用
#### 6. 检查代理管理功能状态
`typescript`
// 检查是否启用了代理管理功能
if (sdk.hasProxyManagement()) {
console.log('代理管理功能已启用');
// 可以使用代理管理相关方法
await sdk.addProxy('proxy.example.com:8080');
} else {
console.log('轻量级模式,仅支持直接指定代理');
// 只能通过 options.proxy 指定代理
}
`typescript
const stats = await sdk.getProxyStats();
console.log({
total: stats.total, // 总代理数
valid: stats.valid, // 有效代理数
invalid: stats.invalid, // 无效代理数
available: stats.available // 可用代理数
});
// 获取队列统计
const queueStats = sdk.getQueueStats();
console.log({
length: queueStats.length, // 队列长度
running: queueStats.running, // 运行中任务数
concurrency: queueStats.concurrency, // 并发数
idle: queueStats.idle // 是否空闲
});
`
`typescript
import { bulkInsertProxyUrls } from 'proxy-pool-manager';
const count = await bulkInsertProxyUrls({
mongoUri: 'mongodb://localhost:27017/proxy_db',
proxyUrls: [
'proxy1.com:8080:user1:pass1',
'proxy2.com:8080:user2:pass2',
// ... 更多代理
],
batchSize: 500, // 每批处理500个
concurrency: 4, // 并发4个批次
logLevel: 'info'
});
console.log(成功插入 ${count} 个代理);`
AsyncQueueSingleton 是一个强大的异步任务队列管理器,支持并发控制、优先级任务、多实例等特性。
`typescript
import { AsyncQueueSingleton } from 'proxy-pool-manager';
// 创建队列实例
const queue = AsyncQueueSingleton.getInstance('my-queue', {
concurrency: 3, // 并发数:同时执行3个任务
autoStart: true, // 自动开始执行
logLevel: 'info',
onDrain: () => {
console.log('所有任务完成!');
},
onError: (error) => {
console.error('任务执行错误:', error);
},
onSuccess: (result) => {
console.log('任务成功:', result);
}
});
// 添加单个任务
const result = await queue.add({ id: 1, name: '任务1' });
console.log('任务结果:', result);
// 批量添加任务
const tasks = [
{ id: 1, name: '任务1' },
{ id: 2, name: '任务2' },
{ id: 3, name: '任务3' }
];
const results = await queue.addBatch(tasks);
console.log('批量任务结果:', results);
`
`typescript
// 创建队列并设置自定义处理器
const queue = AsyncQueueSingleton.getInstance('custom-queue', {
concurrency: 2,
logLevel: 'debug'
});
// 设置任务处理器
queue.setTaskHandler(async (task: any) => {
console.log(处理任务: ${task.name});
// 模拟异步操作
await new Promise(resolve => setTimeout(resolve, task.duration));
// 返回处理结果
return {
taskId: task.id,
status: 'completed',
timestamp: new Date().toISOString()
};
});
// 添加任务
const result = await queue.add({ id: 1, name: '处理文件', duration: 1000 });
console.log(result);
`
`typescript
const queue = AsyncQueueSingleton.getInstance('control-queue', {
concurrency: 2,
autoStart: false // 手动控制启动
});
// 添加任务(队列已暂停,不会立即执行)
const promise = queue.add({ id: 1, name: '任务1' });
// 暂停队列
queue.pause();
console.log('队列已暂停');
// 恢复队列
queue.resume();
console.log('队列已恢复');
// 等待任务完成
const result = await promise;
`
`typescript
const queue = AsyncQueueSingleton.getInstance('priority-queue', {
concurrency: 2
});
// 普通任务(priority = 0,默认)
await queue.add({ id: 1, name: '普通任务1' }, 0);
// 高优先级任务(priority > 0,会插入到队列前面)
await queue.add({ id: 2, name: '高优先级任务' }, 1);
// 最高优先级任务
await queue.add({ id: 3, name: '紧急任务' }, 2);
`
`typescript
const queue = AsyncQueueSingleton.getInstance('monitor-queue');
// 获取队列统计信息
const stats = queue.stats;
console.log({
length: stats.length, // 队列中等待的任务数
running: stats.running, // 正在执行的任务数
concurrency: stats.concurrency, // 并发数
idle: stats.idle // 是否空闲
});
// 获取队列长度
console.log('队列长度:', queue.length);
// 获取运行中任务数
console.log('运行中任务:', queue.running);
// 检查队列是否空闲
if (queue.idle) {
console.log('队列空闲,所有任务已完成');
}
`
`typescript处理图片: ${task.filename}
// 创建不同类型的队列实例
const imageQueue = AsyncQueueSingleton.getInstance('image-processing', {
concurrency: 2,
taskHandler: async (task) => {
console.log();图片处理完成: ${task.filename}
await new Promise(resolve => setTimeout(resolve, 2000));
return ;
}
});
const dataQueue = AsyncQueueSingleton.getInstance('data-processing', {
concurrency: 5,
taskHandler: async (task) => {
console.log(处理数据: ${task.id});数据处理完成: ${task.id}
await new Promise(resolve => setTimeout(resolve, 500));
return ;
}
});
// 同时使用多个队列
const [imageResults, dataResults] = await Promise.all([
imageQueue.addBatch(imageTasks),
dataQueue.addBatch(dataTasks)
]);
// 获取所有实例名称
const instanceNames = AsyncQueueSingleton.getInstanceNames();
console.log('所有队列实例:', instanceNames);
// 获取所有实例的统计信息
const allStats = AsyncQueueSingleton.getAllInstancesStats();
console.log('所有队列统计:', allStats);
`
`typescript
const queue = AsyncQueueSingleton.getInstance('dynamic-queue', {
concurrency: 3
});
// 动态更新并发数
queue.updateConcurrency(5);
console.log('并发数已更新为:', queue.stats.concurrency);
`
`typescript
// 使用泛型指定返回类型
interface ApiResponse {
endpoint: string;
status: string;
data: any;
}
const apiQueue = AsyncQueueSingleton.getInstance
concurrency: 3
});
apiQueue.setTaskHandler(async (task: any): Promise
// 模拟API请求
await new Promise(resolve => setTimeout(resolve, 1000));
return {
endpoint: task.url,
status: 'success',
data: { result: 'ok' }
};
});
const response = await apiQueue.add({ url: '/api/users' });
// response 的类型是 ApiResponse
console.log(response.endpoint, response.status);
`
#### 1. API 请求限流
`typescript
const apiQueue = AsyncQueueSingleton.getInstance('api-rate-limit', {
concurrency: 5 // 限制同时最多5个API请求
});
apiQueue.setTaskHandler(async (apiCall: any) => {
const response = await fetch(apiCall.url);
return await response.json();
});
// 添加多个API请求,自动限流
const results = await apiQueue.addBatch([
{ url: 'https://api.example.com/users' },
{ url: 'https://api.example.com/orders' },
{ url: 'https://api.example.com/products' }
]);
`
#### 2. 文件批量处理
`typescript
const fileQueue = AsyncQueueSingleton.getInstance('file-processing', {
concurrency: 2,
onDrain: () => console.log('所有文件处理完成')
});
fileQueue.setTaskHandler(async (file: any) => {
// 处理文件
await processFile(file);
return 文件 ${file.name} 处理完成;
});
const files = [
{ name: 'document1.pdf', size: 1024 },
{ name: 'image1.jpg', size: 2048 }
];
const results = await fileQueue.addBatch(files);
`
#### 3. 数据库操作队列
`typescript
const dbQueue = AsyncQueueSingleton.getInstance('database-queue', {
concurrency: 1 // 串行执行,避免数据库锁冲突
});
dbQueue.setTaskHandler(async (operation: any) => {
// 执行数据库操作
await db.execute(operation);
return 操作完成: ${operation.type};
});
await dbQueue.add({ type: 'INSERT', table: 'users', data: {...} });
`
`typescript
// 销毁指定队列实例
AsyncQueueSingleton.destroyInstance('my-queue');
// 销毁所有队列实例
AsyncQueueSingleton.destroyAllInstances();
`
#### 静态方法
- getInstance - 获取或创建队列实例getInstanceNames(): string[]
- - 获取所有实例名称getAllInstancesStats(): Record
- - 获取所有实例统计信息hasInstance(name: string): boolean
- - 检查实例是否存在getExistingInstance
- - 获取已存在的实例destroyInstance(name: string): void
- - 销毁指定实例destroyAllInstances(): void
- - 销毁所有实例
#### 实例方法
- add(task: Task, priority?: number): Promise - 添加任务addBatch(tasks: Task[], priority?: number): Promise
- - 批量添加任务setTaskHandler(handler: (task: Task) => Promise
- - 设置任务处理器updateConcurrency(newConcurrency: number): void
- - 更新并发数pause(): this
- - 暂停队列resume(): this
- - 恢复队列destroy(): void
- - 销毁队列setLogLevel(level: LogLevel): void
- - 设置日志级别getLogLevel(): LogLevel
- - 获取日志级别getName(): string
- - 获取实例名称
#### 属性
- length: number - 队列长度running: number
- - 运行中任务数idle: boolean
- - 是否空闲stats: QueueStats
- - 队列统计信息
#### 配置选项
`typescript`
interface AsyncQueueOptions
concurrency?: number; // 并发数,默认 100
autoStart?: boolean; // 自动开始,默认 true
logLevel?: LogLevel; // 日志级别
onDrain?: () => void; // 队列排空回调
onError?: (error: Error) => void; // 错误回调
onSuccess?: (result: T) => void; // 成功回调
taskHandler?: (task: Task) => Promise
}
代理数据存储在 MongoDB 中,集合结构如下:
`typescript`
interface ProxyDocument {
url: string; // 代理 URL(格式:host:port:username:password)
totalRequests: number; // 总请求数
failCount: number; // 失败次数
avgResponseTime: number; // 平均响应时间(毫秒)
lastCheckTime: number; // 最后检查时间(时间戳)
consecutiveFails: number; // 连续失败次数
status: 'valid' | 'invalid'; // 状态
createdAt: Date; // 创建时间
updatedAt: Date; // 更新时间
}
完整的 TypeScript 类型定义已包含在包中:
`typescript`
import type {
RequestOptions,
HttpResponse,
ProxyStrategy,
ProxyItem,
ProxyCheckOptions,
LogLevel
} from 'proxy-pool-manager';
1. 轻量级模式 vs 完整模式:
- 轻量级模式:不提供 mongoUri 和 proxyCheckOptions,不连接 MongoDB,仅使用请求和队列功能mongoUri
- 完整模式:提供 或 proxyCheckOptions,启用代理管理功能,需要 MongoDB 连接
2. MongoDB 连接:仅在启用代理管理功能时需要,确保 MongoDB 服务正在运行且连接 URI 正确
3. 代理格式:代理 URL 格式为 host:port:username:password 或 http://host:port:username:password
4. 代理使用:
- 轻量级模式下,只能通过 options.proxy 直接指定代理
- 完整模式下,可以自动使用代理管理器选择的代理,也可以直接指定代理(优先级更高)
5. 初始化等待:SDK 初始化是异步的,使用 waitForReady() 确保初始化完成
6. 资源清理:使用完毕后调用 destroy() 方法清理资源
7. 并发限制:代理检查的并发数可通过 maxConcurrentChecks 配置
8. 禁用功能:
- 设置 proxyCheckEnabled: false 可禁用代理检查proxyLimit: 0` 可不从数据库加载代理
- 设置