-
Spring Integration 내부에 AbstractClientConnectionFactory라는 추상 클래스가 존재한다.
이 클래스는 Spring Integration에서 클라이언트 측 소켓 연결을 추상화하는 기반 클래스로,
이를 확장하여 구체적인 TCP/UDP 클라이언트 팩토리를 구현할 수 있도록 도와주는 역할을 한다.
이 추상 클래스에 singleUse라는 설정이 있다.
이 설정은 클라이언트 소켓 연결을 요청당 한 번만 사용할지 여부를 결정하는 플래그다.
플래그에 대한 설명 및 장점과 단점은 다음과 같다.
🔹 singleUse = true
- 요청을 보낼 때마다 새로운 연결을 생성하고, 요청이 끝나면 바로 닫는다.
- 장점:
- 각 요청이 독립적인 연결을 사용하므로, 연결 상태 관리가 필요 없음
- 서버와의 연결이 끊어져도 영향이 적음
- 단점:
- 매 요청마다 소켓을 생성하고 닫으므로 오버헤드가 증가 (특히 짧은 요청이 많을 경우 성능 저하)
- 긴 연결이 필요한 경우 비효율적
🔹 singleUse = false (기본값)
- 하나의 연결을 재사용하여 여러 요청을 처리한다.
- 장점:
- 연결 재사용으로 성능이 향상됨 (소켓 생성/해제 비용 절감)
- 지속적인 연결이 필요한 프로토콜(TCP 기반 스트리밍 등)에 적합
- 단점:
- 연결이 끊어지면 복구해야 함 (예: 서버가 재시작되면 클라이언트가 다시 연결해야 함)
- 여러 요청이 하나의 연결을 공유하기 때문에 병렬 처리 시 동기화 문제 발생 가능
🛠 언제 true 또는 false를 선택해야 할까?
- 단순한 요청-응답 패턴이라면 → singleUse = true
- 지속적인 데이터 전송 (스트리밍, 다중 요청) 이 필요하다면 → singleUse = false
그런데, 이 설정이 강제로 true로 변경되거나(CachingClientConnectionFactory),
true 이면 작동하지 않는 설정(FailOverClientConnectionFactory.setCloseOnRefresh ...)들이 몇 개 존재한다...
우선 왜 CachingClinetConnectionFactory는 강제로 singleUse를 true로 설정하고
false로 변경하지 못하게 하는걸까에 대해서 알아보고자 한다.
CachingClientConnectionFactory
📌 역할
- TCP 클라이언트 연결을 캐싱하여 재사용하는 역할
- 내부적으로 여러 개의 연결을 유지하면서 필요할 때 꺼내 쓰고, 사용이 끝난 연결을 다시 풀(pool)로 반환
📌 기본 동작
- Default - singleUse = true (값 변경 불가능)
- 연결을 완전히 닫지 않고 캐싱된 연결을 재사용함으로써 성능을 최적화할 수 있음
- 연결이 풀(pool)에서 반환되면 닫히지 않고 다시 사용될 수 있음
📌 성능 최적화 포인트
1️⃣ 소켓 생성 비용 절감
- TCP 연결을 매번 생성하면 3-way handshake 등의 오버헤드 발생
- 기존 연결을 캐싱하여 불필요한 소켓 생성을 방지하고 성능 향상
- 요청량이 많을수록 효과 극대화
2️⃣ 서버 리소스 관리
- 다수의 클라이언트가 존재하는 경우, 서버의 동시 연결 제한을 초과할 가능성 있음
- CachingClientConnectionFactory는 일정 개수의 연결만 유지하여 서버 리소스를 효율적으로 사용
- 과도한 연결 생성 및 해제를 방지하여 서버 부담 감소
3️⃣ 여러 개의 연결 관리 (멀티 연결 지원)
- TcpNioClientConnectionFactory(singleUse=false)는 하나의 연결만 유지
- CachingClientConnectionFactory는 여러 개의 연결을 유지하여 동시 요청을 더 효율적으로 처리
- 다중 연결을 유지하는 Connection Pool과 유사한 동작
📌 singleUse = true가 기본값인 이유
- 데이터 무결성 보장
- TCP 연결을 캐싱하면 이전 클라이언트의 데이터가 새로운 요청에 영향을 줄 가능성이 있음
- singleUse=true 설정을 통해 각 요청이 새로운 연결을 사용하도록 보장
- 연결 풀에서 적절한 관리 가능
- singleUse=false가 되면, 특정 연결이 풀에서 반환되지 않고 계속 사용될 수 있음
- 불완전한 상태의 연결이 캐싱될 경우, 오류 발생 가능성이 증가
- 안정적인 연결 관리를 위해 기본값을 true로 설정
- 요청 간 간섭 방지
- 동일한 연결을 여러 요청에서 동시에 사용하면 패킷이 엉킬 가능성이 있음
- singleUse=true일 경우, 각 요청이 독립적으로 처리되므로 데이터 충돌 방지
여기까지 봤을 때는 문제가 없어보인다.
AbstractClientConnectionFactory (default - singleUse : false, 변경 가능)
-> TcpNetClientConnectionFactory or TcpNioClientConnectionFactory (default - singleUse : false, 변경 가능)
-> CachingClientConnectionFactory (default - singleUse : true, 변경 불가) ????!
그럼 TcpNetClientConnectionFactory or TcpNioClientConnectionFactory 에서 singleUse가 false인 상태로
CachingClientConnectionFactory에 주입하면 어떻게 될까?
CachingClientConnectionFactory의 생성자에 아래와 같이 강제로 true로 명시하고 있다.

그리고 setSingleUse를 통해 false로 변경하는 것을 제한하고 있으며, 현재의 singleUse값을 바로 true로 리턴하는 것을 확인할 수 있다.

그럼 CachingClientConnectionFactory 이전까지의 singleUse 설정은 무시되고, true로 덮여쓰여진다는 것 까지는 알았다.
근데... 아래와 같이 이후에 singleUse가 false여야만 작동하는 게 있을 때에는 어떻게 해야할까...?
AbstractClientConnectionFactory (default - singleUse : false, 변경 가능)
-> TcpNetClientConnectionFactory or TcpNioClientConnectionFactory (default - singleUse : false, 변경 가능)
-> CachingClientConnectionFactory (default - singleUse : true, 변경 불가)
-> ??? singleUse가 false 여야만 작동하는 경우에는 ???
이 케이스는 다음에 해당 경우가 어떤 경우인지와 어떻게 해결을 했는지에 대해 풀어보려고 한다..!
'Study > TCP-IP' 카테고리의 다른 글
로컬 주소는 Timeout 시간 설정이 되지 않는다?? (0) 2024.12.31 Java Socket vs Spring Integration vs Netty (0) 2024.12.29 TCP/IP 4계층 vs OSI 7계층 (1) 2024.12.26 TCP / IP (0) 2024.12.25