From 892a179664f03218be90f6dba2fd48ae3e4bc237 Mon Sep 17 00:00:00 2001 From: soyeon <102381857+soyeon1806@users.noreply.github.com> Date: Wed, 15 Jul 2026 22:52:23 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20RestTemplate=EC=97=90=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EB=B0=8F=20=EC=9D=91=EB=8B=B5=20=ED=83=80=EC=9E=84?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/RestTemplateConfig.java | 14 ++++++++-- .../global/config/RestTemplateConfigTest.java | 28 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 roome/src/test/java/com/roome/global/config/RestTemplateConfigTest.java diff --git a/roome/src/main/java/com/roome/global/config/RestTemplateConfig.java b/roome/src/main/java/com/roome/global/config/RestTemplateConfig.java index 4a0e0558..8df1ffd9 100644 --- a/roome/src/main/java/com/roome/global/config/RestTemplateConfig.java +++ b/roome/src/main/java/com/roome/global/config/RestTemplateConfig.java @@ -1,14 +1,24 @@ package com.roome.global.config; +import java.time.Duration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { + // 외부 API 호출에 타임아웃 강제 + // 타임아웃이 없으면 상대 서버 지연 시 톰캣 스레드가 무한 대기해서 스레드 풀이 고갈되고, 결제 장애가 서비스 전체 장애로 전이될 수 있음 + static final Duration CONNECT_TIMEOUT = Duration.ofSeconds(3); + static final Duration READ_TIMEOUT = Duration.ofSeconds(10); + @Bean public RestTemplate restTemplate() { - return new RestTemplate(); + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setConnectTimeout(CONNECT_TIMEOUT); + factory.setReadTimeout(READ_TIMEOUT); + return new RestTemplate(factory); } -} \ No newline at end of file +} diff --git a/roome/src/test/java/com/roome/global/config/RestTemplateConfigTest.java b/roome/src/test/java/com/roome/global/config/RestTemplateConfigTest.java new file mode 100644 index 00000000..4cfd4292 --- /dev/null +++ b/roome/src/test/java/com/roome/global/config/RestTemplateConfigTest.java @@ -0,0 +1,28 @@ +package com.roome.global.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.client.RestTemplate; + +class RestTemplateConfigTest { + + @Test + @DisplayName("RestTemplate은 무한 대기를 막기 위해 연결 및 응답 타임아웃이 설정되어 있어야 한다.") + void restTemplate_HasTimeouts() { + // when + RestTemplate restTemplate = new RestTemplateConfig().restTemplate(); + ClientHttpRequestFactory factory = restTemplate.getRequestFactory(); + + // then: 기본(new RestTemplate())이 아닌, 타임아웃이 지정된 팩토리여야 한다 + assertThat(factory).isInstanceOf(SimpleClientHttpRequestFactory.class); + assertThat(ReflectionTestUtils.getField(factory, "connectTimeout")) + .isEqualTo((int) RestTemplateConfig.CONNECT_TIMEOUT.toMillis()); + assertThat(ReflectionTestUtils.getField(factory, "readTimeout")) + .isEqualTo((int) RestTemplateConfig.READ_TIMEOUT.toMillis()); + } +}