ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • iOS에서 서버 과부하 감지 및 API 호출 최적화
    iOS 2025. 3. 15. 09:51

    안녕하세요. 그린입니다 🍏

    이번 포스팅에서는 iOS에서 서버 과부하를 감지하고 이에 API 호출을 최적화 하는 몇가지 방법에 대해 한번 다뤄볼까 합니다 🙋🏻


    Intro

    iOS뿐 아니라 모든 프론트엔드 개발에서는 서버와 원활한 통신이 필수적이죠.

    하지만 과도한 API 호출은 서버에 부담을 주기에 성능 저하, 트래픽 초과, 비용 증가 등의 문제를 야기할 수가 있어요.

    따라서 서버의 상태를 모니터링하고, 과부하 여부를 판단해 적절히 API 호출을 조절하는 전략이 필수적입니다.

     


    Criteria for determining server overload

    서버 과부하라는걸 판단하는 기준에 대해 한번 얘기해볼까 합니다.

    우리는 서버가 느려졌네? 라는걸 감으로 판단하기보다 데이터를 통해 측정해야 하죠.

     

    어떤 방법들이 있는지 볼까요?

     


    Distinction HTTP Status Code

    1️⃣ 429 (Too Many Requests)

    서버가 클라이언트 요청을 너무 많이 받을때 발생하며 보통은 Retry-After 헤더를 포함해 재시도 대기 시간을 제공하죠.

    2️⃣ 503 (Service Unavailable)

    서버가 과부하 상태이거나 유지보수중일때 발생하며 해당 상태에선 일정 시간 후에 재요청하는것이 필요해요.

    3️⃣ 504 (Gateway Timeout)

    서버가 백엔드 응답을 받지 못해서 타임아웃이 발생한 경우이며 즉, 과부하로 요청을 처리하지 못함을 의미해요.

     

    func shouldRetryRequest(response: HTTPURLResponse) -> Bool {
        switch response.statusCode {
        case 429, 503, 504:
            return true
        default:
            return false
        }
    }

     

    요런식으로 간단하게 판단할수도 있죠.

     


    Mesurement Response Time

    서버 응답 시간이 평소보다 길어진다면 과부하가 일어나고 있을 가능성이 있죠.

    예를 들어서, API 응답 시간이 평균적으로 1000ms에서 갑자기 3000ms까지 걸린다면 거진 서버 과부하 상태일 수 있어요.

     

    let startTime = Date()
    URLSession.shared.dataTask(with: request) { data, response, error in
        let elapsedTime = Date().timeIntervalSince(startTime)
        print("Response time: \(elapsedTime) seconds")
    }.resume()

     

    예를 든 코드처럼 핵심은 응답 시간에 대한 데이터를 수집해 과부하 임계값을 초과한다면 API 콜을 줄이는 전략을 가져갈 수 있습니다.

     


    Server sends overload status to response header

    서버가 자체적으로 Retry-After나 X-RateLimit-Remaining 등의 헤더를 반환하는 케이스에서 이를 활용해 요청을 조절할 수 있죠.

     

    if let retryAfter = response.allHeaderFields["Retry-After"] as? String,
       let retrySeconds = Double(retryAfter) {
        DispatchQueue.global().asyncAfter(deadline: .now() + retrySeconds) {
            self.retryAPIRequest()
        }
    }

     

    예시로 이런 코드를 사용해 서버가 과부하 상태일 때 자동으로 대기 시간을 조절할 수도 있습니다.

     

    그럼 이런 판단을 했다면, 우리는 iOS에서 어떻게 API 콜을 조절할 수 있을까요?

     

    몇가지에 대해 알아봅시다 😃

     


    Strategies for controlling API calls on iOS

    서버 과부하를 판단한 후에 과부하를 줄이기 위해서 API 호출을 적절히 조절하는 방법을 알아보려해요.

     


    Retry Exponential Backoff

    지수 백오프 재시도 전략을 볼 수 있는데요.

    과부하 상태일때 동일 요청을 반복한다면 서버 부담을 증폭시키는 행위가 되죠.

    그렇기에 점진적으로 대기 시간을 늘려가면서 재시도하는걸 해볼 수 있습니다.

     

    func retryWithBackoff(attempt: Int) {
        let maxAttempts = 5
        guard attempt < maxAttempts else { return }
    
        let delay = pow(2.0, Double(attempt)) // 점진적 증가하며 대기
        DispatchQueue.global().asyncAfter(deadline: .now() + delay) {
            self.makeAPIRequest(attempt: attempt + 1)
        }
    }

     

    즉, 처음에는 재시도를 즉시하지만, 실패 시 점점 시간을 지수로 늘려가며 재시도를 해볼 수 있죠.

     


    Limit API calls frequency

    불필요한 API 호출을 줄이기 위해서 특정 시간 동안에 콜 횟수를 제한하는 방법도 사용해볼 수 있습니다.

     

    class APIRateLimiter {
        private var lastRequestTime: Date?
        private let minInterval: TimeInterval = 1.0
    
        func canMakeRequest() -> Bool {
            if let lastTime = lastRequestTime, Date().timeIntervalSince(lastTime) < minInterval {
                return false
            }
            lastRequestTime = Date()
            return true
        }
    }

     

    예시 코드처럼 연속적인 API 요청이 일정 간격을 유지하도록 조절해볼 수도 있죠.

     


    Save API calls with caching

    반복적인 동일 데이터 요청 시 유용합니다.

    API 호출을 최소화하기 위해서 캐싱을 활용할 수 있죠.

     

    let configuration = URLSessionConfiguration.default
    configuration.urlCache = URLCache(memoryCapacity: 50 * 1024 * 1024, diskCapacity: 100 * 1024 * 1024, diskPath: nil)
    let session = URLSession(configuration: configuration)

     

    예시로, 요런식으로 iOS의 기본적인 URLCache를 활용해서 API 호출을 줄이는 기본적인 방법도 있습니다.

     

    이런 방법들이 아니더라도, 주기적으로 데이터를 가져오는 polling 방식이나 WebSocket을 사용해 불필요한 API 호출을 줄이는 방법도 하나의 전략이 될 수 있죠.

    무분별한 API 콜 자체를 끊을 수 있으니까요.

     


    Conclusion

    결국 우리는 서버 과부하를 줄이면서 효율적으로 API 콜하는것이 어떻게 보면 iOS 앱 성능 최적화와 서버 비용 절감 측면에서 모두 중요하죠.

    위와 같은 다양한 전략 및 그 외 전략들을 프로젝트에 맞게 적절히 활용해본다면 서버도 지키면서 사용자 경험도 더 높여갈 수 있을거라 생각해요!

    'iOS' 카테고리의 다른 글

    Server-Driven UI  (0) 2025.03.07
    Factory Pattern  (0) 2025.03.03
    카카오톡 공유하기 (메시지 템플릿)  (36) 2024.12.05
    Bring your app to Siri (feat. WWDC 2024)  (7) 2024.10.07
    Genmoji (feat. WWDC 2024)  (4) 2024.10.04
Designed by Tistory.