-
클라우드 환경에서의 유휴 커넥션 관리(Idle Connection Management for Cloud)Cloud 2024. 6. 9. 18:29반응형
https://www.flaticon.com/free-icons/omnichannel Omnichannel icons created by Prosymbols Premium - Flaticon
0. 케이스
최근에 진행한 프로젝트 환경이 Microsoft Azure 였는데, 정확하게는 AKS(Azure Kubernetes Service) + Azure Event Hubs + Azure Cosmos DB, + Azure Database for PostgreSQL + ... 이었다. 문제는 이러한 서비스들에서 공통적으로 ConnectException(Kafka Producer), NoHttpResponseException, SocketException(Rest call) 같은 연결 오류가 발생했다.
클라우드는 아니었지만, 이전 고객사에서 비슷한 경험을 했었기에 원인은 금방 짐작할 수 있었다. (사례는 접은글 참고)
문제는 Azure의 리소스 관리 정책을 알아야 한다는 것이었다.
1. 정책
https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-tcp-reset
Load Balancer TCP Reset and idle timeout in Azure - Azure Load Balancer
With this article, learn about Azure Load Balancer with bidirectional TCP RST packets on idle timeout.
learn.microsoft.com
매뉴얼을 찾아보다가 관련된 글을 찾았는데, 결론은 Azure Load Balancer에서는 사용하지 않고 4분(기본값)이 지난 TCP 연결을 닫는다는 것이다. (Azure Load Balancer has a 4 minutes to 100-minutes timeout range for Load Balancer rules, Outbound Rules, and Inbound NAT rules. The default is 4 minutes. If a period of inactivity is longer than the timeout value, there's no guarantee that the TCP or HTTP session is maintained between the client and your cloud service.)
따라서 아키텍처상 레이어 간에 Azure Load Balancer를 사용하는 경우 클라이언트에서 연결 설정 시 해당 부분을 고려해야 장애 없이 서비스가 가능하다.
2. 조치
연결 오류가 발생했던 클라이언트의 연결 설정에 Idle Connection timeout 설정을 Azure Load Balancer의 설정(4분) 보다 짧게 설정하여, 닫힌 소켓으로 요청하는 일이 없도록 설정했다(유휴 커넥션에 대해 문제가 발생한 것이기 떄문에 최대 연결 유지 시간 자체를 변경할 필요는 없다). 여러 서비스를 사용했기에 각각 클라이언트 설정을 모두 변경해야 했는데, 내용은 아래와 같다.
2-1. Kafka(Event Hubs)
/* * Kafka Producer * Java Client인 경우 Map에 config들을 담아서 Bean을 생성할 텐데, 아래 설정값들을 적용해야 한다. */ metadata.max.age.ms = 180000 connections.max.idle.ms = 180000
+ Kafka Client는 Azure Event Hubs를 사용하는 경우 권장 설정들을 정리한 문서가 따로 있으니 참고.
Apache Kafka 클라이언트에 권장되는 구성 - Azure Event Hubs
이 문서에서는 Apache Kafka용 Azure Event Hubs와 상호 작용하는 클라이언트에 권장되는 Apache Kafka 구성을 제공합니다.
learn.microsoft.com
2-2. MongoDB(CosmosDB)
/* * MongoDB Client * maxIdleTimeMS의 기본값은 0인데, 0인 경우에는 유휴 시간에 제한이 없다(...) */ maxIdleTimeMS = 180000
2-3. HttpClient
HttpClient httpClient = HttpClientBuilder.create() .evictIdleConnections(180L, TimeUnit.SECONDS) .evictExpiredConnections() .build();
3. AWS는?
Azure에서 발생한 이슈에 대해서 글을 쓰다 보니 AWS도 비슷하지 않을까 하는 생각이 들었다.
역시나 AWS의 Gateway Load Balancer(GWLB)에서도 비슷한 구성이 존재했다. TCP 연결은 350초, TCP가 아닌 연결에 대해서는 120초를 유지한다. static이라 변경도 안된다고 한다..
Idle timeout
Gateway Load Balancers support idle timeout for both TCP, and non-TCP flows.
- For TCP flows, the idle timeout is 350 seconds.
- For non-TCP flows, the idle timeout is 120 seconds.
Note: The idle timeout values for Gateway Load Balancers are static and cannot be changed.
Gateway Load Balancers - Elastic Load Balancing
Thanks for letting us know this page needs work. We're sorry we let you down. If you've got a moment, please tell us how we can make the documentation better.
docs.aws.amazon.com
반응형