Android만 API 요청이 불안정했던 이유

같은 로직의 RN 프로젝트를 빌드했을때 iOS는 항상 API 요청이 성공하는데, Android는 성공했다가 실패했다가를 반복했다.
김보람's avatar
Oct 31, 2025
Android만 API 요청이 불안정했던 이유

Android만 API 요청이 불안정했던 이유

같은 로직의 프로젝트를 iOS와 Android에 동시에 올렸는데 이상한 현상이 생겼다.
iOS는 항상 API 요청이 성공하는데, Android는 성공했다가 실패했다가를 반복했다.
처음엔 네트워크 문제나 토큰 이슈, 혹은 axios 쪽 버그일 수도 있겠다고 생각했었고 여러 수정을 계속해도 결과는 같았다


원인 찾기

조사해보니, 서비스는 여러 대의 EC2 인스턴스 뒤에 로드밸런서(Load Balancer) 를 두고 있었다.
요청이 들어오면 로드밸런서가 서버 여러 대 중 하나로 트래픽을 분배하는 구조다.

문제는 이 중 한 인스턴스가 죽어 있었다는 것.
그런데 로드밸런서가 그걸 인식하지 못하고,
여전히 그쪽으로도 일부 요청을 보내고 있었다.

결과적으로,

  • 살아있는 서버 → 요청 성공

  • 죽은 서버 → 요청 실패

즉, Android는 죽은 서버로 트래픽이 가면 실패했고,
살아있는 서버로 가면 성공했던 거다.


그런데 iOS는 왜 괜찮았을까?

여기서 진짜 흥미로웠던 부분이 있었다.
같은 로직, 같은 API인데 왜 iOS는 항상 성공했을까?

차이는 바로 네트워크 연결 방식이었다.

[ iOS ]

  • 내부적으로 NSURLSession을 사용한다.

  • 여러 IP가 있을 때, 연결이 실패하면 즉시 다른 IP로 재시도한다.

  • 즉, 죽은 서버를 만나도 알아서 “살아 있는 서버”로 옮겨 붙는다.

[ Android ]

  • 내부적으로 OkHttp를 쓴다.

  • DNS에서 받은 IP 중 하나를 고정으로 선택하고, 실패해도 다른 IP로 재시도하지 않는다.

  • 게다가 SSL 세션을 캐싱하기 때문에,
    한 번 죽은 서버에 붙으면 그 연결 정보를 계속 재활용하면서 반복적으로 실패한다.

결국,

iOS는 자동 회피 덕분에 항상 성공했고,
Android는 죽은 서버 IP를 계속 물고 있어서 성공/실패를 반복했다.


해결

문제의 원인은 결국 로드밸런서 뒤의 죽은 인스턴스였다.
백단에 요청해 그 인스턴스를 타깃 그룹에서 제거했다.

추가로 Android 쪽엔
Connection: close 헤더를 추가해서 SSL 세션 캐시를 강제로 끊도록 수정했다.
그 이후로는 Android에서도 API 요청이 모두 안정적으로 성공했다.

이건 Android가 죽은 세션을 재사용하지 않도록 강제하는 방법이었다.

하지만 인스턴스 문제가 해결된 뒤 난 Connection: close 구문을 삭제했다 그이유는 이 헤더를 쓰면 한 번의 요청이 끝날 때마다 기존 연결을 끊고 새로 연결하기 때문에 지속적인 요청에는 비효율적이기 때문이다.


정리

사건: Android만 API 요청 실패
원인: 로드밸런서 뒤 EC2 인스턴스 중 하나가 죽어 있었음
차이점: Android는 고정된 IP로만 연결, iOS는 실패 시 다른 IP로 자동 재시도
조치: 죽은 서버 제거 + Android 임시 Connection: close 적용
결과: 안정화 이후 효율성 고려해 Connection: close 제거

Share article

RN 삽질 일지