Objective c 在多线程应用程序上测量AFN网络的响应时间

Objective c 在多线程应用程序上测量AFN网络的响应时间,objective-c,multithreading,afnetworking,load-testing,Objective C,Multithreading,Afnetworking,Load Testing,更新 经过一些研究,我对代码做了一些改进。我首先用以下方法替换我测量时间的每个位置:[NSNumber numberWithDouble:[[NSDate date]TimeIntervalsIncess1970]具有原子时间测量,例如:CFAbsoluteTimeGetCurrent() 我注意到这没什么区别。与我们的服务器人员核对时,我注意到服务器显示了令人印象深刻的结果——这让我觉得这里的瓶颈不是服务器,而是我的笔记本电脑/其他方面 原创帖子 我正在尝试对我的服务器进行负载测试,因此我构

更新

经过一些研究,我对代码做了一些改进。我首先用以下方法替换我测量时间的每个位置:
[NSNumber numberWithDouble:[[NSDate date]TimeIntervalsIncess1970]具有原子时间测量,例如:
CFAbsoluteTimeGetCurrent()

我注意到这没什么区别。与我们的服务器人员核对时,我注意到服务器显示了令人印象深刻的结果——这让我觉得这里的瓶颈不是服务器,而是我的笔记本电脑/其他方面


原创帖子

我正在尝试对我的服务器进行负载测试,因此我构建了一个模拟应用程序中用户流的场景。此流包含对服务器的大约11-17个调用,其中一些调用必须是同步的(因为用户除非通过其他屏幕,否则无法到达某个屏幕)

然后,我同时使用
X
线程运行了这个场景,试图对服务器施加压力,看看最薄弱的环节在哪里。为了分析这些信息,每次回复(无论是成功还是失败)时,我都会将一些相关信息记录到一个文件中,并注意到每次调用的时间安排都有一些非常奇怪的事情发生

要测量通话时间,我在每次通话开始前使用以下方法测量了通话的开始时间:

 test.startTime = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]];
//fire the request
[operation start];
在成功/失败模块中发生的第一件事是:

成功

void (^successWrapper)  (AFHTTPRequestOperation *, id) = ^(AFHTTPRequestOperation *operation, id responseObject){
    //#################TEST ANALYTICS###############
    NSDate *endTime = [NSDate date];
    test.endTime = [NSNumber numberWithDouble:[endTime timeIntervalSince1970]];
    test.lat = [NSNumber numberWithDouble:(test.endTime.doubleValue - test.startTime.doubleValue)];
    //##############################################

   //Some other success stuff...

   };
失败:

void (^failureWrapper) (AFHTTPRequestOperation *, NSError *) = ^(AFHTTPRequestOperation *operation, NSError *error) {

   //#################TEST ANALYTICS###############
   NSDate *endTime = [NSDate date];
   test.endTime = [NSNumber numberWithDouble:[endTime timeIntervalSince1970]];
   test.lat = [NSNumber numberWithDouble:(test.endTime.doubleValue - test.startTime.doubleValue)];
   //##############################################

   //Some other failure stuff...

   };
然而,我在日志文件中遇到了非常高的延迟,并且随着
X
越来越大,延迟变得越来越严重

我假设这个问题是由于线程之间的上下文切换造成的,但我不确定。因此,我的问题是:在一个具有多线程的系统中,如何正确测量
AFNetworking
中每个调用的响应时间

一些注意事项:

  • 如上所述,一些调用可以同时发生,而另一些调用必须按顺序发生
  • X
    最终应该非常高(>10000)

谢谢

可以同时运行的
NSURLConnection
网络请求数量有限。您可以启动任意数量的操作,但是
NSURLConnection
只能同时运行有限数量的操作(我相信是4-6次,取决于操作系统版本)。后续的
NSURLConnection
请求将等待前面的请求完成。在极端情况下(例如提交数百个请求),这甚至会导致后一个请求超时(除非指定足够大的超时参数)。这个约束不是网络延迟,而是操作系统对客户端施加的有限数量的并发请求的产物

在客户端应用程序中,当使用基于
NSOperationQueue
的框架(如AFNetworking)时,您不需要自己启动操作,只需将操作添加到
NSOperationQueue
即可解决此限制。然后,您可以将操作队列的
maxConcurrentOperationCount
限制为某个合理的数量,该数量对应于可在任何给定时间运行的并发
NSURLConnection
请求的数量(例如,我可能建议5),以消除单个操作中出现的延迟。如果要将这些请求添加到自己的队列中,则需要为该队列指定
maxConcurrentOperationCount
。如果您使用的是
afhttprequestorerationmanager
,则应该在管理器的
operationQueue
属性上执行此操作

如果您想在上述上下文中对AFNetworking的性能进行基准测试,问题是您是否希望测量总运行时间(在这种情况下,您可以在将开始时间添加到队列中时捕获开始时间,然后在完成块中计算运行时间,类似于您在问题中概述的方式)或者您是否希望捕获实际运行操作所花费的时间

如果您对后者感兴趣,您确实希望在操作队列导致调用
start
方法时启动计时器,您可以为
AFNetworkingOperationDidStartNotification
AFNetworkingOperationDidFinishNotification
通知添加观察员,或者只需拨叉AFNetworking并修改
AFURLConnectionOperation
即可计算所用时间


最后,有点不清楚你的问题是真的对应用程序进行压力测试,还是对服务器进行压力测试。如果只是简单地对应用程序进行压力测试,上述方法应该可以奏效。如果您想对服务器进行压力测试以模拟多个同时使用的用户,这将更加困难,并且可能需要完全绕过
NSURLConnection
/AFNetworking(使用
CFNetwork
)或者真的设置一组物理设备/计算机,让它们同时进行客户端AFNetworking压力测试。

在10000个线程时,您将看到巨大的开销,我建议将您的测试应用程序限制在少数几个线程内。@SamMiller,好吧-我有100个线程(甚至更少),不要说10000…@goldengil,你应该使用<20个线程,而不是大约100个。