【发布时间】:2015-12-06 05:40:37
【问题描述】:
我的 iOS 应用从 nginx HTTP 服务器加载图像。在我发送 400 多个此类请求后,网络“卡住”并且所有后续 HTTP 请求都会导致“请求超时”错误。只有重新启动应用程序才能重新加载图像。
详情:
- 我正在使用
NSURLSession.sharedSession().dataTaskWithURL向 jpeg 文件发送四百个 HTTP GET 请求。 - 请求按顺序发送,一个接一个。请求之间的间隔为 10 毫秒。
- 使用
NSURLSessionDataTask对象的cancel()方法取消每个先前未完成的请求。
有趣的是:
- 我只能在 HTTPS 请求和服务器上启用 SPDY 时遇到此问题。
- 非安全 HTTP 请求工作正常。
- 非 SPDY HTTPS 请求工作正常。我通过在 nginx 配置中关闭服务器端的 SPDY 来测试它。
- 问题出现在 iOS 8 和 9、物理设备和模拟器上。支持 Wi-Fi 和 LTE。
- 当我查看 nginx 访问日志时,我仍然可以看到“卡住”的请求进入。重要的细微差别:请求日志记录出现在 iOS 应用程序在超时期限结束后放弃它的确切时刻.
- 我希望用Charles Proxy 分析HTTP 请求,但是当请求通过Charles 时问题会自行解决。也就是说 - 一切都适用于查尔斯,就像量子力学中的效果一样,当观察的事实影响结果时。
- 当 iOS 应用程序连接到两个具有完全不同 nginx 配置的不同服务器时,我能够重现该问题。这可能意味着该问题与特定的 nginx 设置无关。
- 我使用“活动监视器”工具分析了应用程序。它在批量 HTTP 请求期间使用的线程数从 5 跃升至 10。相比之下,当我仅发送一个 HTTP 请求时,线程数跃升至 8。CPU 负载很少超过 30%。
问题的原因可能是什么?谁能推荐其他分析和调试的方法或工具?
使用调度工具进行分析
演示应用
这个演示应用 100% 地重现了我的问题。
https://github.com/exchangegroup/ImageLoadDemo
版本和设置
我的 nginx 配置:http://pastebin.com/pYYjdxfP
OS X:10.10.4 (14E46),iOS:8 和 9,Xcode:7.0 (7A218), nginx:1.9.4
不是理想的解决方法
只有当我为每个单独的请求创建一个新的 NSURLSession 并使用 finishTasksAndInvalidate 或 invalidateAndCancel 清除上一个会话时,我才设法使请求保持工作。
// Request 1
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration)
session.dataTaskWithURL ...
// Request 2
// clear the previous request
session.finishTasksAndInvalidate()
let session2 = NSURLSession(configuration: configuration)
session2.dataTaskWithURL ...
【问题讨论】:
-
nginx 对这些请求做了什么?显示配置
-
@AlexeyTen,这里是 nginx 配置:pastebin.com/pYYjdxfP
-
发生这种情况时,客户端上运行了多少线程?
-
@quellish 只有一个线程。 iOS 应用按顺序发送请求,一个接一个,间隔为 10 毫秒。
-
如果您可以重现它,请这样做并在调试器中停止应用程序 - 查看有多少线程正在运行。很可能所有这些请求都在堆积起来,等待资源被释放,然后才能继续 - 网络延迟、线程等系统资源等。这也可以解释为什么在使用 Charles 时它不会重现。
标签: ios swift nginx nsurlsession