Http请求失败,响应状态码为502

时间:2020-07-10 09:58:20

标签: ios swift

在一个循环中,我遇到了1000个GET请求。由于请求太多,并且网关无法处理它,因此失败并显示错误代码502。解决此问题的最佳方法是什么。我的代码如下。

 //In the array there are about 10000 ids 
 for id in Array {

  Network.shared.getData(accountId: id ?? "", successBlock: {(result) in

    //Save results to coredata

    }) {(errorCode:Int, error:String) in
        print(errorCode, error)
        
    }


 }

后来我的Singleton Network不能以上述方式调用下面的方法。

 class Network: NSObject {

 //These blocks catches success & failures
    typealias SuccessBlock = (Any) -> Void
    typealias FailureBlock = (_ errorCode: Int, _ error: String) -> Void
 

private static var networkCalls: Network?
private override init() {}

public static var shared: Network {

    if networkCalls == nil {
        networkCalls = Network()
    }
    return networkCalls!

 }

private lazy var configurationManager: URLSession = {
   let configuration = URLSessionConfiguration.default
    configuration.allowsExpensiveNetworkAccess = true
    configuration.allowsConstrainedNetworkAccess = true
    configuration.allowsCellularAccess = true
    configuration.timeoutIntervalForRequest = 60
    configuration.timeoutIntervalForResource = 60
    configuration.httpMaximumConnectionsPerHost = 2
    
    
    let manager = URLSession(configuration: configuration)
    return manager
   
}()

在上面的类中,我使用通用方法来调用HTTP请求(此处我没有显示带有所有参数的完整方法,但是您可以了解它的外观)

   private func performWebServiceRequest(with url: URL, contentType: CONTENT_TYPE? = nil, requestOptions: [String: String]?,successBlock: @escaping SuccessBlock, failureBlock: @escaping FailureBlock) {

    let request = NSMutableURLRequest(url: url)
    request.httpMethod = requestType // As in "POST", "GET", "PUT" or "DELETE"
    request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData

  let task = configurationManager.dataTask(with: request as URLRequest) { (data, response, error) in
        guard let data: Data = data, let response: URLResponse = response, error == nil else 
    {return}

           do {
              let result = try JSONDecoder().decode(type, from: data)
                    successBlock(result)

            } catch {
                    failureBlock(0,errorMessage)
            }

  }

  task.resume()

 }

1 个答案:

答案 0 :(得分:0)

您可以使用DispatchSemaphore来限制并行运行任务的数量,如下所示:

var countedSemaphore = DispatchSemaphore(value:500)  // Allow 500 parallel network calls
var queue = DispatchQueue(label: "runner", qos: .background, attributes: .concurrent)

//In the array there are about 10000 ids
for id in Array {
    queue.async {  //(1)
        countedSemaphore.wait()  // (2)

        Network.shared.getData(accountId: id ?? "", successBlock: {(result) in
            countedSemaphore.signal() // (3a)

            //Save results to coredata

       }) {(errorCode:Int, error:String) in
           countedSemaphore.signal()  // (3b)
           print(errorCode, error)
       }
    }
}

该示例使用自定义的并发队列(1)创建将启动网络获取的任务。 在任务中,我们首先使用wait(2)作为信号量。只要该计数器大于零,此调用将简单地减少信号量的计数器。如果计数器为零,则wait调用会阻塞。

wait返回后,我们称为getData

在成功(3a)和错误(3b)处理程序中,我们在信号量上调用signal,以表明我们已完成网络调用。 signal将增加计数器或唤醒任何等待的呼叫。

此构造可确保最多并行运行500个getData调用