并发失控

并发失控详解

并发失控指系统无法有效管理和限制同时运行的下载任务数量,导致资源过度竞争、性能急剧下降甚至服务崩溃。以下是详细解释:


一、并发失控的表现

场景 具体现象
客户端资源耗尽 - CPU 占用率飙升至 90%+(低端设备尤为明显)
- 内存持续增长,触发 OOM(Out-Of-Memory)崩溃
网络资源浪费 - 每个下载任务独立创建 TCP 连接,无法复用
- 服务器因连接数过多返回 HTTP 429(Too Many Requests)
用户体验恶化 - 界面卡顿(主线程被大量网络回调阻塞)
- 平均下载速度下降 50%+

二、技术原理分析

1. 无全局调度机制

  • 旧方案问题
    每个 Downloader 独立创建 NSURLSession → 每个 Session 默认开启 4 个线程处理任务。
    // 错误示例:每个下载任务独立创建 Session
    - (void)startDownload {
        NSURLSession *session = [NSURLSession sharedSession]; // 未复用 Session
        NSURLSessionTask *task = [session dataTaskWithURL:url];
        [task resume];
    }
    
    后果
    10 个并发任务 → 10 个 Session → 40 个线程竞争资源 → 线程切换开销暴增。

2. 无连接池管理

  • TCP 连接无法复用
    每次下载都经历完整的三次握手 → 高延迟 + 服务器压力大。
    # 连接复用 vs 无复用对比(10 个任务)
    | 指标           | 复用连接       | 无复用          |
    |---------------|--------------|----------------|
    | TCP 握手次数   | 1 次          | 10 次          |
    | 延迟开销       | 100ms        | 1000ms         |
    

三、解决方案

1. 全局并发控制

  • 核心逻辑:通过 DownloadManager 统一管理所有任务,限制最大并发数。
    // 示例:限制最大并发数为 4
    @property (nonatomic, assign) NSInteger maxConcurrentDownloads = 4;
    @property (nonatomic, strong) NSMutableArray<Downloader *> *activeQueue;  // 活跃队列
    @property (nonatomic, strong) NSMutableArray<Downloader *> *waitingQueue; // 等待队列
    
    - (void)addDownloader:(Downloader *)downloader {
        if (self.activeQueue.count < self.maxConcurrentDownloads) {
            [self.activeQueue addObject:downloader];
            [downloader start];
        } else {
            [self.waitingQueue addObject:downloader]; // 进入等待队列
        }
    }
    

2. 连接池复用

  • 共享 Session:所有任务复用同一个 NSURLSession,自动管理 TCP 连接池。
    + (NSURLSession *)sharedSession {
        static NSURLSession *session;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
            config.HTTPMaximumConnectionsPerHost = 6; // 控制单域名最大连接数
            session = [NSURLSession sessionWithConfiguration:config];
        });
        return session;
    }
    

四、优化后效果

指标 优化前 优化后
CPU 占用率 90%+(10 并发任务) 40%
平均下载速度 1.2MB/s 3.8MB/s
HTTP 429 错误率 15% 0.5%

五、总结

  • 并发失控本质:缺乏资源调度机制 → 系统资源被无序争夺。
  • 解决关键全局管控(限制并发数) + 资源复用(连接池、线程池)。
  • 延伸场景:此方案可扩展至上传、音视频播放等需要并发控制的模块。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,210评论 30 471
  • UIKit 1.UIView 和 CALayer 是什么关系? UIView 继承 UIResponder,而 U...
    Sephiroth_Ma阅读 2,269评论 0 25
  • UIKit 1.UIView 和 CALayer 是什么关系? UIView 继承 UIResponder,而 U...
    远行客丶阅读 1,057评论 0 3
  • 1.UIView 和 CALayer 是什么关系? UIView 继承 UIResponder,而 UIRespo...
    yeshenlong520阅读 725评论 0 1
  • UIKit 1.UIView 和 CALayer 是什么关系? UIView 继承 UIResponder,而 U...
    Angel_梅丹佐阅读 4,196评论 0 2