# 性能分析 - 并发数超过20导致WSS连接失败 v3.12.8

**版本**: v3.12.8  
**日期**: 2025-10-08  
**类型**: 性能分析 / 使用建议

## 问题描述

用户反馈：

> "我发现并发的数量超过20个，就很容易导致WSS链接失败，这是什么原因导致的"

**现象**：
- 并发数设置为20以下：稳定运行 ✅
- 并发数设置为20-30：偶尔连接失败 ⚠️
- 并发数设置为30+：频繁连接失败 ❌

## 根本原因分析

### 1. 浏览器WebSocket连接数限制 ⭐ 主要原因

**浏览器限制**：
- **Chrome/Edge**: 每个域名最多约 **255-256** 个WebSocket连接（理论值）
- **实际安全值**: 每个域名建议 **10-20** 个并发连接
- **Firefox**: 约 **200** 个连接
- **Safari**: 约 **100** 个连接

**为什么实际值远小于理论值？**
```
理论最大值: 256个
实际推荐值: 10-20个

原因：
1. 浏览器资源限制（内存、CPU）
2. 网络带宽限制
3. 操作系统的Socket限制
4. 浏览器的性能保护机制
```

### 2. 游戏服务器连接限制

**服务器端可能的限制**：

```
1. 同一IP连接数限制
   - 防止DDoS攻击
   - 限制单个用户的连接数
   - 通常限制：10-50个/IP

2. 连接速率限制
   - 限制连接建立速度
   - 防止批量自动化
   - 例如：1秒内最多建立5个连接

3. 资源保护
   - 服务器总连接数限制
   - 单个用户资源配额
   - 防止服务器过载
```

### 3. 连接建立速度过快

**当前的连接间隔**：
```javascript
const delayMs = connectionIndex * 500  // 每个连接间隔500ms
```

**并发20个时的时间分布**：
```
连接1:  0秒    ← 立即开始
连接2:  0.5秒
连接3:  1.0秒
连接4:  1.5秒
...
连接10: 4.5秒
...
连接20: 9.5秒  ← 最后一个连接在9.5秒后开始
```

**问题**：
- 虽然有间隔，但10秒内建立20个连接
- 可能触发服务器的反批量检测
- 服务器可能认为这是自动化攻击

### 4. 内存和资源占用

**单个WebSocket连接的资源消耗**：
```
内存占用: 约 5-10MB / 连接
网络带宽: 约 100KB-1MB / 连接（活跃时）
CPU占用: 约 1-2% / 连接（活跃时）

20个并发连接：
内存: 100-200MB
带宽: 2-20MB
CPU: 20-40%
```

**浏览器性能影响**：
```
并发10个: 流畅 ✅
并发20个: 可接受 ⚠️
并发50个: 卡顿明显 ❌
并发100个: 浏览器可能崩溃 💥
```

### 5. 网络质量影响

**网络因素**：
```
1. 家庭宽带上行带宽限制
   - 下载速度: 100Mbps
   - 上传速度: 10-20Mbps ← 瓶颈
   - 20个连接可能超过上行带宽

2. 路由器NAT表限制
   - 家用路由器通常支持 1000-5000 个并发连接
   - 但实际稳定值更低
   - 过多连接可能导致路由器不稳定

3. ISP限制
   - 运营商可能限制同时连接数
   - 防止P2P等高并发应用
```

## 技术限制详解

### 浏览器WebSocket实现

```javascript
// Chrome的WebSocket实现（简化）
class WebSocket {
  constructor(url) {
    // 1. 检查连接数
    if (activeConnections >= MAX_CONNECTIONS_PER_DOMAIN) {
      throw new Error('Too many connections')
    }
    
    // 2. 建立TCP连接
    // 3. WebSocket握手
    // 4. 维护心跳
  }
}

// 限制机制
const MAX_CONNECTIONS_PER_DOMAIN = 256  // 理论值
const RECOMMENDED_LIMIT = 10-20         // 实际安全值
```

### 操作系统限制

**Windows**：
```
默认最大Socket数: 65535（理论）
实际推荐值: 5000-10000
单个进程限制: 2000-5000
```

**macOS/Linux**：
```
默认限制: 1024（ulimit -n）
可调整为: 65535
但实际使用建议: 5000以下
```

## 当前实现分析

### 连接建立流程

```javascript
// src/stores/batchTaskStore.js
const executeBatchWithConcurrency = async (tokenIds, tasks) => {
  const queue = [...tokenIds]
  const executing = []
  let connectionIndex = 0
  
  while (queue.length > 0 || executing.length > 0) {
    // 填充执行队列（最多maxConcurrency个）
    while (executing.length < maxConcurrency.value && queue.length > 0) {
      const tokenId = queue.shift()
      
      // 错开连接时间
      const delayMs = connectionIndex * 500  // 500ms间隔
      connectionIndex++
      
      const promise = (async () => {
        if (delayMs > 0) {
          await new Promise(resolve => setTimeout(resolve, delayMs))
        }
        
        // 建立连接并执行任务
        return executeTokenTasks(tokenId, tasks)
      })()
      
      executing.push(promise)
    }
    
    // 等待至少一个完成
    if (executing.length > 0) {
      await Promise.race(executing)
    }
  }
}
```

### 问题分析

1. **累加的延迟时间**：
   ```
   第1个: 0ms
   第2个: 500ms
   第3个: 1000ms
   ...
   第20个: 9500ms
   
   问题：前面的连接可能已经完成，
        但新连接仍在累加延迟
   ```

2. **并发控制不精确**：
   ```
   虽然限制了executing.length < maxConcurrency
   但实际活跃的WebSocket连接数可能更多
   因为连接建立和任务执行是异步的
   ```

3. **没有连接失败重试限制**：
   ```
   连接失败会重试，但可能加剧连接压力
   ```

## 解决方案和建议

### 方案1：降低推荐并发数 ⭐ 推荐

**建议的安全值**：

| 网络环境 | 推荐并发数 | 说明 |
|---------|----------|------|
| **家庭宽带** | **10-15** | 最稳定，适合大多数用户 |
| 高速宽带 | 15-20 | 网络条件好可以尝试 |
| 企业网络 | 20-30 | 专线网络，上行带宽足够 |
| 服务器环境 | 30-50 | 数据中心，网络质量极好 |

**实施**：
```javascript
// src/stores/batchTaskStore.js
const maxConcurrency = ref(
  parseInt(localStorage.getItem('maxConcurrency') || '10')  // 默认改为10
)

// 添加警告提示
const setMaxConcurrency = (count) => {
  if (count > 20) {
    console.warn(`⚠️ 警告：并发数 ${count} 超过推荐值(20)`)
    console.warn(`⚠️ 可能导致WebSocket连接失败、浏览器卡顿等问题`)
    console.warn(`⚠️ 建议设置为10-20之间`)
  }
  
  maxConcurrency.value = count
  localStorage.setItem('maxConcurrency', count.toString())
}
```

### 方案2：优化连接间隔策略

**当前策略问题**：
```javascript
const delayMs = connectionIndex * 500  // 累加延迟
// 第20个要等9.5秒，但前面的可能已经完成了
```

**优化策略**：
```javascript
// 固定间隔，不累加
const CONNECTION_INTERVAL = 1000  // 每个连接间隔1秒

let lastConnectionTime = 0

while (executing.length < maxConcurrency.value && queue.length > 0) {
  const tokenId = queue.shift()
  
  // 计算需要等待的时间
  const now = Date.now()
  const timeSinceLastConnection = now - lastConnectionTime
  const waitTime = Math.max(0, CONNECTION_INTERVAL - timeSinceLastConnection)
  
  if (waitTime > 0) {
    await new Promise(resolve => setTimeout(resolve, waitTime))
  }
  
  lastConnectionTime = Date.now()
  
  // 建立连接...
}
```

### 方案3：添加连接池管理

```javascript
// 连接池配置
const CONNECTION_POOL_CONFIG = {
  maxConnections: 20,           // 最大连接数
  maxActiveConnections: 10,     // 最大活跃连接数
  connectionTimeout: 30000,     // 连接超时30秒
  idleTimeout: 60000,          // 空闲超时60秒
  connectionInterval: 1000      // 连接间隔1秒
}

// 连接池管理
class WebSocketPool {
  constructor(config) {
    this.config = config
    this.activeConnections = new Map()
    this.pendingQueue = []
  }
  
  async acquire(tokenId) {
    // 等待直到可以建立新连接
    while (this.activeConnections.size >= this.config.maxActiveConnections) {
      await new Promise(resolve => setTimeout(resolve, 100))
    }
    
    // 建立连接
    const connection = await this.createConnection(tokenId)
    this.activeConnections.set(tokenId, connection)
    
    return connection
  }
  
  release(tokenId) {
    this.activeConnections.delete(tokenId)
  }
}
```

### 方案4：分批执行

```javascript
// 将Token分批执行，每批不超过10个
const BATCH_SIZE = 10
const BATCH_INTERVAL = 5000  // 批次间隔5秒

for (let i = 0; i < tokenIds.length; i += BATCH_SIZE) {
  const batch = tokenIds.slice(i, i + BATCH_SIZE)
  
  console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`)
  console.log(`🔄 执行第 ${Math.floor(i / BATCH_SIZE) + 1} 批`)
  console.log(`📊 本批数量: ${batch.length}`)
  console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`)
  
  // 执行这一批
  await executeBatch(batch, tasks)
  
  // 批次间隔
  if (i + BATCH_SIZE < tokenIds.length) {
    console.log(`⏸️ 等待${BATCH_INTERVAL/1000}秒后执行下一批...`)
    await new Promise(resolve => setTimeout(resolve, BATCH_INTERVAL))
  }
}
```

## 用户使用建议

### 1. 根据Token数量选择并发数

```
Token总数     推荐并发数    预计时间
--------------------------------------
1-10个        5-7          2-3分钟
10-50个       7-10         5-8分钟
50-100个      10-15        8-12分钟
100-500个     10-15        20-60分钟
500-1000个    10-15        60-120分钟
```

### 2. 网络环境优化

**家庭网络**：
```
1. 使用有线连接（比WiFi更稳定）
2. 关闭其他占用带宽的应用
3. 避免高峰时段（晚上8-10点）
4. 重启路由器清理NAT表
5. 并发数设置为10-12
```

**移动热点**：
```
1. 4G/5G热点通常上行带宽较低
2. 建议并发数: 5-8
3. 避免流量不足时执行
4. 注意流量消耗
```

**企业/学校网络**：
```
1. 可能有防火墙限制
2. 可能禁止WebSocket
3. 建议先小规模测试
4. 并发数: 10-15
```

### 3. 分时段执行

```javascript
// 方案A：深夜执行（服务器压力小）
定时时间: 凌晨2:00-5:00
并发数: 可以设置高一些 (15-20)
稳定性: ⭐⭐⭐⭐⭐

// 方案B：白天执行
定时时间: 上午10:00-下午4:00
并发数: 中等 (10-12)
稳定性: ⭐⭐⭐⭐

// 方案C：高峰时段（不推荐）
定时时间: 晚上8:00-10:00
并发数: 低 (5-8)
稳定性: ⭐⭐
```

### 4. 监控和调整

**观察指标**：
```
1. WebSocket连接成功率
   - >95%: 并发数合适 ✅
   - 90-95%: 可以接受 ⚠️
   - <90%: 降低并发数 ❌

2. 任务执行失败率
   - <5%: 正常 ✅
   - 5-10%: 注意观察 ⚠️
   - >10%: 需要优化 ❌

3. 浏览器响应速度
   - 流畅: 合适 ✅
   - 偶尔卡顿: 可接受 ⚠️
   - 频繁卡顿: 降低并发 ❌
```

**调整策略**：
```
步骤1: 从10开始测试
步骤2: 观察连接成功率和失败率
步骤3: 如果稳定，可以逐步增加到12、15
步骤4: 如果出现问题，立即降低
步骤5: 找到最佳值后固定使用
```

## 错误排查

### 常见错误和解决方法

#### 错误1：连接超时

```
错误信息: WebSocket connection timeout
原因: 服务器响应慢或网络不稳定
解决: 
1. 降低并发数到10
2. 增加连接间隔到1000ms
3. 检查网络连接
```

#### 错误2：连接被拒绝

```
错误信息: WebSocket connection refused
原因: 服务器限制连接数或IP被封
解决:
1. 立即停止批量任务
2. 等待5-10分钟
3. 降低并发数到5-8
4. 增加连接间隔到2000ms
```

#### 错误3：浏览器卡死

```
现象: 浏览器无响应，CPU 100%
原因: 并发数过高，资源耗尽
解决:
1. 强制刷新页面 (Ctrl+F5)
2. 清除浏览器缓存
3. 下次使用时降低并发数到5-10
```

#### 错误4：部分Token连接失败

```
现象: 100个Token中20-30个连接失败
原因: 超过服务器或浏览器限制
解决:
1. 降低并发数
2. 使用"重试失败"功能
3. 分批执行
```

## 最佳实践总结

### 稳定运行配置

```javascript
// 推荐配置
{
  maxConcurrency: 10,           // 并发数
  connectionInterval: 1000,     // 连接间隔1秒
  requestTimeout: 5000,         // 请求超时5秒
  maxRetries: 3,               // 最大重试3次
  retryDelay: 3000             // 重试延迟3秒
}
```

### 性能vs稳定性权衡

```
高性能模式（不推荐）:
- 并发数: 30-50
- 连接间隔: 500ms
- 风险: 高
- 稳定性: ⭐⭐
- 速度: ⭐⭐⭐⭐⭐

平衡模式（推荐）:
- 并发数: 10-15
- 连接间隔: 1000ms
- 风险: 低
- 稳定性: ⭐⭐⭐⭐
- 速度: ⭐⭐⭐⭐

稳定模式:
- 并发数: 5-8
- 连接间隔: 2000ms
- 风险: 极低
- 稳定性: ⭐⭐⭐⭐⭐
- 速度: ⭐⭐⭐
```

## 技术限制对照表

| 限制类型 | 限制值 | 影响 | 建议 |
|---------|--------|------|------|
| 浏览器连接数 | 10-20/域名 | 超过会连接失败 | 并发≤15 |
| 服务器限制 | 10-50/IP | 超过可能被封 | 并发≤20 |
| 上行带宽 | 10-20Mbps | 影响连接速度 | 并发≤15 |
| 浏览器内存 | 100-200MB | 影响性能 | 并发≤20 |
| 路由器NAT | 1000-5000 | 连接不稳定 | 并发≤15 |

## 总结

**问题根源**：
- 🔍 浏览器WebSocket连接数限制（10-20个）
- 🔍 游戏服务器连接数限制
- 🔍 网络带宽限制（特别是上行）
- 🔍 系统资源限制（内存、CPU）

**推荐配置**：
- ✅ **并发数**: 10-15（最佳平衡点）
- ✅ **连接间隔**: 1000ms
- ✅ **网络环境**: 有线连接优先
- ✅ **执行时段**: 避开高峰期

**关键建议**：
- 💡 **不要盲目追求高并发**，稳定性更重要
- 💡 **从10开始测试**，逐步找到最佳值
- 💡 **关注连接成功率**，<95%就降低并发
- 💡 **使用进度保存**，连接失败可以继续
- 💡 **分时段执行**，深夜/凌晨最稳定

---

**状态**: ✅ 已分析  
**版本**: v3.12.8  
**推荐并发数**: 10-15

