# 快速开始:通用HTTP客户端多平台账户管理 **版本**: 1.0.0 **创建日期**: 2025-09-28 **目标**: 提供HTTP客户端库的快速开始指南和使用示例 ## 15分钟快速开始 ### 步骤1: 安装和配置 ```bash # 安装HTTP客户端库 npm install @yourorg/http-client # 安装依赖(如果单独使用) npm install @yourorg/credential-manager winston https-proxy-agent ``` ### 步骤2: 环境配置 创建 `.env` 文件: ```bash # Pacifica DEX配置 PACIFICA_ACCOUNT_ID=your_pacifica_account PACIFICA_PRIVATE_KEY=your_pacifica_private_key # Aster DEX配置 ASTER_ACCOUNT_ID=0x_your_aster_account ASTER_PRIVATE_KEY=0x_your_aster_private_key # Binance配置 BINANCE_API_KEY=your_binance_api_key BINANCE_SECRET_KEY=your_binance_secret_key # 可选:代理配置 HTTP_PROXY_URL=http://username:password@proxy.server.com:8080 ``` ### 步骤3: 基本使用 ```typescript import { UniversalHttpClient } from '@yourorg/http-client' // 创建客户端实例 const httpClient = new UniversalHttpClient({ timeout: { connect: 5000, read: 30000, write: 15000 }, retry: { maxAttempts: 3, exponentialBackoff: true }, enableLogging: true }) // 添加账户 await httpClient.addAccount('pacifica', 'main-account', { accountId: process.env.PACIFICA_ACCOUNT_ID!, privateKey: process.env.PACIFICA_PRIVATE_KEY! }) // 发起API请求 const response = await httpClient.request({ platform: 'pacifica', accountId: 'main-account', method: 'GET', url: '/api/v1/account/info' }) console.log('账户信息:', response.data) ``` ## 完整使用场景 ### 场景1: 多平台账户余额查询 **目标**: 查询所有平台账户的余额信息 ```typescript import { UniversalHttpClient } from '@yourorg/http-client' async function queryAllBalances() { const client = new UniversalHttpClient() // 配置多个平台账户 await client.addAccount('pacifica', 'pac-main', { accountId: process.env.PACIFICA_ACCOUNT_ID!, privateKey: process.env.PACIFICA_PRIVATE_KEY! }) await client.addAccount('aster', 'ast-main', { accountId: process.env.ASTER_ACCOUNT_ID!, privateKey: process.env.ASTER_PRIVATE_KEY! }) await client.addAccount('binance', 'bnc-main', { apiKey: process.env.BINANCE_API_KEY!, secretKey: process.env.BINANCE_SECRET_KEY! }) // 并发查询所有平台余额 const requests = [ { platform: 'pacifica' as const, accountId: 'pac-main', method: 'GET' as const, url: '/api/v1/account/info' }, { platform: 'aster' as const, accountId: 'ast-main', method: 'GET' as const, url: '/api/v1/account/balance' }, { platform: 'binance' as const, accountId: 'bnc-main', method: 'GET' as const, url: '/api/v3/account' } ] // 批量执行请求 const responses = await client.batchRequest(requests) // 处理结果 responses.forEach((response, index) => { const platform = requests[index].platform console.log(`${platform} 余额:`, response.data) }) await client.close() } // 运行示例 queryAllBalances().catch(console.error) ``` **预期输出**: ``` pacifica 余额: { totalBalance: 1500.50, availableBalance: 1200.30, ... } aster 余额: { balance: 2300.75, lockedBalance: 100.25, ... } binance 余额: { balances: [{ asset: 'USDT', free: '1000.00', ... }] } ``` ### 场景2: 平台特定订单下单 **目标**: 在不同平台下单,处理平台特定的认证和格式要求 ```typescript import { UniversalHttpClient } from '@yourorg/http-client' async function placeOrdersAcrossPlatforms() { const client = new UniversalHttpClient({ retry: { maxAttempts: 3, shouldRetry: (error) => { // 认证错误不重试,网络错误重试 return error.code !== 'AUTH_FAILED' } } }) // 添加账户 await client.addAccount('pacifica', 'trading', { accountId: process.env.PACIFICA_ACCOUNT_ID!, privateKey: process.env.PACIFICA_PRIVATE_KEY! }) await client.addAccount('aster', 'trading', { accountId: process.env.ASTER_ACCOUNT_ID!, privateKey: process.env.ASTER_PRIVATE_KEY! }) try { // Pacifica 限价单 const pacificaOrder = await client.request({ platform: 'pacifica', accountId: 'trading', method: 'POST', url: '/api/v1/order/limit', body: { symbol: 'BTC-USD', side: 'buy', amount: 0.001, price: 65000, timeInForce: 'GTC' }, options: { timeout: { read: 10000 }, idempotencyKey: `pac-order-${Date.now()}` } }) console.log('Pacifica订单成功:', pacificaOrder.data.orderId) // Aster 市价单 const asterOrder = await client.request({ platform: 'aster', accountId: 'trading', method: 'POST', url: '/api/v1/orders', body: { symbol: 'BTCUSDT', side: 'BUY', type: 'MARKET', quantity: 0.001 }, options: { timeout: { read: 15000 }, idempotencyKey: `ast-order-${Date.now()}` } }) console.log('Aster订单成功:', asterOrder.data.orderId) } catch (error) { if (error.code === 'AUTH_FAILED') { console.error('认证失败,请检查凭据配置') } else if (error.code === 'RATE_LIMITED') { console.error('触发速率限制,请稍后重试') } else { console.error('订单失败:', error.message) } } await client.close() } placeOrdersAcrossPlatforms().catch(console.error) ``` ### 场景3: 代理开关和高级配置 **目标**: 灵活控制代理开关,使用高级代理配置进行网络隔离 ```typescript import { UniversalHttpClient } from '@yourorg/http-client' async function proxyAdvancedConfiguration() { const client = new UniversalHttpClient({ // 全局代理配置 globalProxy: { enabled: true, url: process.env.HTTP_PROXY_URL, type: 'http', auth: { username: process.env.PROXY_USERNAME!, password: process.env.PROXY_PASSWORD! }, pool: { servers: [ 'http://proxy1.example.com:8080', 'http://proxy2.example.com:8080', 'http://proxy3.example.com:8080' ], strategy: 'round-robin', healthCheckUrl: 'http://httpbin.org/ip', healthCheckInterval: 60000 }, failover: { enabled: true, maxRetries: 3, delay: 1000, fallbackToDirect: false // 不允许直连回退 } } }) // 添加账户(使用全局代理) await client.addAccount('pacifica', 'global-proxy-account', { accountId: process.env.PACIFICA_ACCOUNT_ID!, privateKey: process.env.PACIFICA_PRIVATE_KEY! }) // 添加账户(禁用代理) await client.addAccount('aster', 'no-proxy-account', { accountId: process.env.ASTER_ACCOUNT_ID!, privateKey: process.env.ASTER_PRIVATE_KEY!, proxyDisabled: true // 账户级别禁用代理 }) try { console.log('=== 代理开关测试 ===') // 1. 使用全局代理(默认行为) console.log('\\n1. 使用全局代理配置:') const response1 = await client.request({ platform: 'pacifica', accountId: 'global-proxy-account', method: 'GET', url: '/api/v1/market/prices', options: { proxy: { strategy: 'global' } // 明确使用全局代理 } }) console.log('- 响应时间:', response1.metadata.duration, 'ms') console.log('- 使用代理:', response1.metadata.usedProxy) // 2. 强制使用特定代理 console.log('\\n2. 强制使用特定代理:') const response2 = await client.request({ platform: 'pacifica', accountId: 'global-proxy-account', method: 'GET', url: '/api/v1/account/info', options: { proxy: { strategy: 'force', forceProxy: { enabled: true, url: 'http://special-proxy.example.com:8080', type: 'http', auth: { username: 'special-user', password: 'special-pass' }, session: { prefix: 'force-session-', suffix: '_custom', rotation: false, sticky: true } } } } }) console.log('- 使用的代理:', response2.metadata.proxyUsed) // 3. 临时禁用代理 console.log('\\n3. 临时禁用代理(直连):') const response3 = await client.request({ platform: 'pacifica', accountId: 'global-proxy-account', method: 'GET', url: '/api/v1/market/tickers', options: { proxy: { strategy: 'disabled', disableProxy: true } } }) console.log('- 使用代理:', response3.metadata.usedProxy) console.log('- 直连响应时间:', response3.metadata.duration, 'ms') // 4. 账户级别禁用代理的测试 console.log('\\n4. 账户级别禁用代理:') const response4 = await client.request({ platform: 'aster', accountId: 'no-proxy-account', method: 'GET', url: '/api/v1/market/tickers' // 即使不指定proxy选项,该账户也不会使用代理 }) console.log('- 使用代理:', response4.metadata.usedProxy) // 5. 代理轮换测试 console.log('\\n5. 代理轮换测试:') for (let i = 0; i < 3; i++) { const response = await client.request({ platform: 'pacifica', accountId: 'global-proxy-account', method: 'GET', url: '/api/v1/market/prices', options: { proxy: { strategy: 'global', rotation: { enabled: true, interval: 1, // 每次请求轮换 strategy: 'round-robin' } } } }) console.log(`- 第${i+1}次请求代理:`, response.metadata.proxyUsed) } // 6. 代理健康检查 console.log('\\n6. 代理健康检查:') const proxyStatus = await client.getProxyStatus() console.log('代理池状态:', { 总代理数: proxyStatus.pool?.totalProxies, 活跃代理数: proxyStatus.pool?.activeProxies, 当前代理: proxyStatus.currentProxy, 健康状态: proxyStatus.health.isHealthy, 连续失败次数: proxyStatus.health.consecutiveFailures }) // 7. 代理故障转移测试 console.log('\\n7. 代理故障转移测试:') const response7 = await client.request({ platform: 'pacifica', accountId: 'global-proxy-account', method: 'GET', url: '/api/v1/market/depth', params: { symbol: 'BTC-USD' }, options: { proxy: { strategy: 'global', healthCheck: { enabled: true, timeout: 2000, failureThreshold: 2 } }, retry: { maxAttempts: 5, // 增加重试次数以测试故障转移 shouldRetry: (error) => { return error.code === 'PROXY_ERROR' || error.code === 'TIMEOUT' } } } }) console.log('- 故障转移成功,响应:', response7.status) } catch (error) { console.error('代理配置错误:', { code: error.code, message: error.message, proxyStatus: error.proxyStatus }) // 代理错误处理 if (error.code === 'PROXY_ERROR') { console.log('\\n尝试切换到备用代理或直连...') const fallbackResponse = await client.request({ platform: 'pacifica', accountId: 'global-proxy-account', method: 'GET', url: '/api/v1/market/prices', options: { proxy: { strategy: 'disabled' } // 回退到直连 } }) console.log('直连回退成功:', fallbackResponse.status) } } await client.close() } proxyAdvancedConfiguration().catch(console.error) ``` ### 场景4: 性能监控和健康检查 **目标**: 监控客户端性能,确保服务质量 ```typescript import { UniversalHttpClient } from '@yourorg/http-client' async function performanceMonitoring() { const client = new UniversalHttpClient({ metrics: { enabled: true, collectInterval: 30000, // 30秒收集一次指标 historyRetention: 3600000 // 保留1小时历史 } }) // 添加多个账户进行测试 await client.addAccount('pacifica', 'test-1', { accountId: process.env.PACIFICA_ACCOUNT_ID!, privateKey: process.env.PACIFICA_PRIVATE_KEY! }) await client.addAccount('aster', 'test-2', { accountId: process.env.ASTER_ACCOUNT_ID!, privateKey: process.env.ASTER_PRIVATE_KEY! }) // 模拟高并发请求 console.log('开始性能测试...') const startTime = Date.now() const requests = Array.from({ length: 100 }, (_, i) => ({ platform: i % 2 === 0 ? 'pacifica' as const : 'aster' as const, accountId: i % 2 === 0 ? 'test-1' : 'test-2', method: 'GET' as const, url: i % 2 === 0 ? '/api/v1/market/prices' : '/api/v1/market/tickers' })) try { // 批量执行并发请求 const responses = await client.batchRequest(requests) const endTime = Date.now() console.log('性能测试完成:', { totalRequests: requests.length, successfulRequests: responses.filter(r => r.ok).length, totalTime: endTime - startTime, averageTime: (endTime - startTime) / requests.length }) // 获取详细健康状态 const health = await client.getHealth() console.log('系统健康状态:', { status: health.status, platforms: Object.entries(health.platforms).map(([name, status]) => ({ platform: name, status: status.status, responseTime: status.responseTime, successRate: status.successRate })), metrics: { totalRequests: health.metrics.totalRequests, successRate: health.metrics.successfulRequests / health.metrics.totalRequests, averageResponseTime: health.metrics.averageResponseTime, p99ResponseTime: health.metrics.p99ResponseTime, activeConnections: health.metrics.activeConnections } }) } catch (error) { console.error('性能测试失败:', error) } await client.close() } performanceMonitoring().catch(console.error) ``` ## 测试验证 ### 单元测试示例 ```typescript import { UniversalHttpClient } from '@yourorg/http-client' import { describe, it, expect, beforeEach, afterEach } from '@jest/globals' describe('UniversalHttpClient', () => { let client: UniversalHttpClient beforeEach(async () => { client = new UniversalHttpClient({ timeout: { connect: 1000, read: 5000, write: 3000 } }) }) afterEach(async () => { await client.close() }) it('应该成功添加Pacifica账户', async () => { await client.addAccount('pacifica', 'test-account', { accountId: 'test-account-id', privateKey: 'test-private-key' }) const health = await client.getHealth() expect(health.platforms.pacifica).toBeDefined() }) it('应该处理认证失败错误', async () => { await client.addAccount('pacifica', 'invalid-account', { accountId: 'invalid', privateKey: 'invalid' }) await expect(client.request({ platform: 'pacifica', accountId: 'invalid-account', method: 'GET', url: '/api/v1/account/info' })).rejects.toThrow('AUTH_FAILED') }) it('应该在速率限制时正确重试', async () => { // 测试重试逻辑 // 实现省略... }) }) ``` ### 集成测试示例 ```bash # 运行完整集成测试 npm run test:integration # 运行特定平台测试 npm run test:pacifica npm run test:aster npm run test:binance # 运行性能基准测试 npm run test:performance ``` ## 代理开关最佳实践 ### 代理策略选择指南 ```typescript // 1. 全局代理策略(推荐用于生产环境) const productionConfig = { proxy: { strategy: 'global' }, // 使用全局配置的代理池 } // 2. 账户专用代理策略(推荐用于多账户隔离) const accountConfig = { proxy: { strategy: 'account' }, // 使用账户专用代理配置 } // 3. 强制代理策略(推荐用于特殊需求) const forceConfig = { proxy: { strategy: 'force', forceProxy: { enabled: true, url: 'http://special.proxy.com:8080', type: 'socks5' } } } // 4. 禁用代理策略(推荐用于调试和测试) const directConfig = { proxy: { strategy: 'disabled' } } ``` ### 代理开关环境变量配置 ```bash # .env文件配置示例 # 全局代理配置 GLOBAL_PROXY_ENABLED=true GLOBAL_PROXY_URL=http://proxy.example.com:8080 GLOBAL_PROXY_USERNAME=your_username GLOBAL_PROXY_PASSWORD=your_password # 代理池配置 PROXY_POOL_SERVERS=http://proxy1.com:8080,http://proxy2.com:8080,http://proxy3.com:8080 PROXY_POOL_STRATEGY=round-robin PROXY_HEALTH_CHECK_URL=http://httpbin.org/ip PROXY_HEALTH_CHECK_INTERVAL=60000 # 账户专用代理配置 PACIFICA_PROXY_ENABLED=true PACIFICA_PROXY_URL=http://pacifica-proxy.com:8080 PACIFICA_PROXY_SESSION_PREFIX=pac_session_ ASTER_PROXY_ENABLED=false # 禁用Aster账户代理 BINANCE_PROXY_ENABLED=true BINANCE_PROXY_URL=http://binance-proxy.com:8080 # 故障转移配置 PROXY_FAILOVER_ENABLED=true PROXY_FAILOVER_MAX_RETRIES=3 PROXY_FAILOVER_DELAY=1000 PROXY_FALLBACK_TO_DIRECT=false # 是否允许直连回退 ``` ### 代理开关使用模式 ```typescript import { UniversalHttpClient } from '@yourorg/http-client' // 模式1: 智能代理开关(推荐) async function smartProxyUsage() { const client = new UniversalHttpClient({ globalProxy: { enabled: process.env.GLOBAL_PROXY_ENABLED === 'true', url: process.env.GLOBAL_PROXY_URL, // 自动故障转移和健康检查 failover: { enabled: true, fallbackToDirect: false }, pool: { strategy: 'fastest' } } }) // 根据操作类型智能选择代理策略 const marketDataResponse = await client.request({ platform: 'pacifica', accountId: 'main', method: 'GET', url: '/api/v1/market/prices', options: { proxy: { strategy: 'global', // 市场数据使用全局代理池 rotation: { enabled: true } } } }) const accountResponse = await client.request({ platform: 'pacifica', accountId: 'main', method: 'GET', url: '/api/v1/account/info', options: { proxy: { strategy: 'account', // 账户数据使用专用代理 healthCheck: { enabled: true } } } }) const tradingResponse = await client.request({ platform: 'pacifica', accountId: 'main', method: 'POST', url: '/api/v1/order/limit', body: { symbol: 'BTC-USD', side: 'buy', amount: 0.001 }, options: { proxy: { strategy: 'force', // 交易操作使用稳定代理 forceProxy: { enabled: true, url: process.env.TRADING_PROXY_URL, connection: { keepAlive: true, timeout: 10000 } } } } }) } // 模式2: 条件代理开关 async function conditionalProxyUsage() { const client = new UniversalHttpClient() // 根据环境条件动态选择代理策略 const isDevelopment = process.env.NODE_ENV === 'development' const isHighLatency = await checkNetworkLatency() > 200 const proxyStrategy = isDevelopment ? 'disabled' // 开发环境直连 : isHighLatency ? 'force' // 高延迟强制代理 : 'global' // 正常情况全局代理 const response = await client.request({ platform: 'pacifica', accountId: 'main', method: 'GET', url: '/api/v1/market/depth', options: { proxy: { strategy: proxyStrategy } } }) } // 模式3: 代理性能监控和自动切换 async function performanceBasedProxyUsage() { const client = new UniversalHttpClient({ globalProxy: { enabled: true, pool: { servers: ['http://fast-proxy.com:8080', 'http://stable-proxy.com:8080'], strategy: 'fastest', // 自动选择最快代理 healthCheckInterval: 30000 } } }) // 性能监控和自动切换 for (let i = 0; i < 10; i++) { const startTime = Date.now() try { const response = await client.request({ platform: 'pacifica', accountId: 'main', method: 'GET', url: '/api/v1/market/prices', options: { proxy: { strategy: 'global', rotation: { enabled: true, strategy: 'fastest' } } } }) const duration = Date.now() - startTime console.log(`请求${i+1}: ${duration}ms, 代理: ${response.metadata.proxyUsed}`) // 如果响应时间过长,切换到直连 if (duration > 1000) { console.log('代理响应过慢,切换到直连模式') break } } catch (error) { if (error.code === 'PROXY_ERROR') { console.log('代理故障,自动切换到备用代理') // 客户端会自动切换到备用代理 } } } } async function checkNetworkLatency(): Promise { // 简单的延迟检测实现 const start = Date.now() try { await fetch('http://httpbin.org/delay/0') return Date.now() - start } catch { return 9999 // 网络不可达 } } ``` ### 代理开关调试技巧 ```typescript // 启用详细的代理日志 const client = new UniversalHttpClient({ logging: { level: 'debug', proxyDetails: true // 记录代理连接详细信息 } }) // 监听代理事件 client.on('proxy:connect', (proxyUrl) => { console.log(`代理连接成功: ${proxyUrl}`) }) client.on('proxy:disconnect', (proxyUrl, reason) => { console.log(`代理断开连接: ${proxyUrl}, 原因: ${reason}`) }) client.on('proxy:error', (proxyUrl, error) => { console.error(`代理错误: ${proxyUrl}`, error) }) client.on('proxy:switch', (fromProxy, toProxy) => { console.log(`代理切换: ${fromProxy} -> ${toProxy}`) }) // 代理状态实时监控 setInterval(async () => { const status = await client.getProxyStatus() console.log('代理状态监控:', { 当前代理: status.currentProxy, 连接状态: status.status, 成功率: `${(status.stats.successfulRequests / status.stats.totalRequests * 100).toFixed(1)}%`, 平均响应时间: `${status.stats.averageResponseTime}ms`, 健康状态: status.health.isHealthy ? '健康' : '异常' }) }, 30000) ``` ## 故障排除 ### 常见问题 1. **认证失败 (AUTH_FAILED)** ``` 错误: 签名验证失败 解决: 检查私钥格式和账户ID是否正确 ``` 2. **连接超时 (TIMEOUT)** ``` 错误: 请求超时 解决: 检查网络连接,调整超时配置 ``` 3. **速率限制 (RATE_LIMITED)** ``` 错误: 超出API调用限制 解决: 增加请求间隔,实现退避重试 ``` 4. **代理连接失败** ``` 错误: 代理服务器无响应 解决: 验证代理配置,检查防火墙设置 ``` ### 调试技巧 ```typescript // 启用详细日志 const client = new UniversalHttpClient({ logging: { level: 'debug', sensitiveData: true } }) // 查看请求详情 client.on('request', (request) => { console.log('发送请求:', request.id, request.url) }) client.on('response', (response) => { console.log('收到响应:', response.requestId, response.status) }) client.on('error', (error) => { console.error('请求错误:', error.code, error.message) }) ``` ## 生产部署建议 ### 配置优化 ```typescript // 生产环境配置 const productionConfig = { timeout: { connect: 5000, read: 30000, write: 15000 }, retry: { maxAttempts: 3, exponentialBackoff: true, delay: 1000 }, connectionPool: { maxConnectionsPerPlatform: 20, idleTimeout: 30000, reuseConnections: true }, logging: { level: 'info', sensitiveData: false, // 生产环境不记录敏感数据 retention: '30d' } } ``` ### 监控设置 ```typescript // 设置监控告警 client.on('healthChange', (health) => { if (health.status === 'unhealthy') { // 发送告警通知 alertingService.sendAlert('HTTP客户端健康状态异常') } }) // 性能监控 setInterval(async () => { const metrics = await client.getPerformanceMetrics() if (metrics.averageResponseTime > 100) { console.warn('响应时间超出目标值') } }, 60000) ``` --- **快速开始总结**: 通过以上示例,您可以在15分钟内完成HTTP客户端的基本配置,在1小时内掌握高级功能使用。