FeginClient 어노테이션을 추가하고, yml 파일에 추가한 설정값으로 Timeout을 테스트한 결과입니다.
송신 서버는 아래 java 코드와 같이 단순 호출만 하고, 시간을 체크합니다.
수신 서버는 Thread.sleep(1000 * 120); 과 같이 매우 긴 시간을 대기하게 설정했습니다.
- Controller Class
import com.test.project.feign.client.TestClient;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequiredArgsConstructor
public class TestController {
private final TestClient testClient;
@PostMapping("/test")
public ResponseEntity<?> zxc() throws InterruptedException {
long startTime = System.currentTimeMillis();
try {
testClient.test();
} catch (Exception e) {
e.printStackTrace();
}
long timeTaken = System.currentTimeMillis() - startTime;
System.err.println("################## 걸린 시간 : " + timeTaken);
return ResponseEntity.ok().build();
}
}
- Feign Interface
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "test", url = "http://localhost:28010", path = "/test")
public interface TestClient {
@GetMapping(value = "/do")
void test();
}
테스트 결과 Timeout에 영향을 받는 yml 설정은 다음 2가지가 있습니다.
feign.client.config
feign:
hystrix:
# true 값 설정시 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 설정과 비교하여 짧은 값이 적용됨
# feign.client.config.default.readTimeout 기본값 : 60_000
# hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 기본값 : 1_000
enabled: false
client:
config:
# FeignClient의 name값으로 타겟팅 가능
default: # 기본값
loggerLevel: BASIC
connectTimeout: 5000 # 3 Way Handshake가 5초가 넘는다면 수신 서버와의 통신 자체에 문제가 있는것.
readTimeout: 5000 # 수신 서버의 처리시간을 고려하여 설정
test: # FeignClient의 name이 test인 인터페이스
loggerLevel: BASIC
connectTimeout: 5000
readTimeout: 5000
hystrix
feign:
hystrix:
# true 값 설정시 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 설정과 비교하여 짧은 값이 적용됨
# feign.client.config.default.readTimeout 기본값 : 60_000
# hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 기본값 : 1_000
enabled: true
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
테스트 케이스
Case 1.
feign.hystrix.enabled=false
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=15000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
실행 로그
feign.RetryableException: Read timed out executing GET http://localhost:22222/test/do
at feign.FeignException.errorExecuting(FeignException.java:213)
...
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
...
################## 걸린 시간 : 15024
Case 2.
feign.hystrix.enabled=false
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=5000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=15000
실행 로그
feign.RetryableException: Read timed out executing GET http://localhost:22222/test/do
at feign.FeignException.errorExecuting(FeignException.java:213)
...
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
...
################## 걸린 시간 : 5029
Case 3.
feign.hystrix.enabled=true
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=15000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
실행 로그
com.netflix.hystrix.exception.HystrixRuntimeException: TestClient#test() failed and no fallback available.
at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:822)
...
feign.RetryableException: Read timed out executing GET http://localhost:22222/test/do
at feign.FeignException.errorExecuting(FeignException.java:213)
...
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
...
################## 걸린 시간 : 5280
Case 4.
feign.hystrix.enabled=true
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=5000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=15000
실행 로그
com.netflix.hystrix.exception.HystrixRuntimeException: TestClient#test() failed and no fallback available.
at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:822)
...
feign.RetryableException: Read timed out executing GET http://localhost:22222/test/do
at feign.FeignException.errorExecuting(FeignException.java:213)
...
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
...
################## 걸린 시간 : 5211
Case 5.
feign.hystrix.enabled=true
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=15000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=15000
실행 로그
com.netflix.hystrix.exception.HystrixRuntimeException: TestClient#test() failed and no fallback available.
at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:822)
...
feign.RetryableException: Read timed out executing GET http://localhost:22222/test/do
at feign.FeignException.errorExecuting(FeignException.java:213)
...
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
...
################## 걸린 시간 : 15157
Case 6.
feign.hystrix.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=15000
실행 로그
com.netflix.hystrix.exception.HystrixRuntimeException: TestClient#test() failed and no fallback available.
at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:822)
...
Caused by: java.util.concurrent.TimeoutException
at com.netflix.hystrix.AbstractCommand.handleTimeoutViaFallback(AbstractCommand.java:997)
################## 걸린 시간 : 15168
Case 7.
feign.hystrix.enabled=true
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=15000
실행 로그
com.netflix.hystrix.exception.HystrixRuntimeException: TestClient#test() failed and no fallback available.
at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:822)
...
Caused by: java.util.concurrent.TimeoutException
at com.netflix.hystrix.AbstractCommand.handleTimeoutViaFallback(AbstractCommand.java:997)
################## 걸린 시간 : 1018
Case 8.
feign.hystrix.enabled=true
실행 로그
com.netflix.hystrix.exception.HystrixRuntimeException: TestClient#test() failed and no fallback available.
at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:822)
...
Caused by: java.util.concurrent.TimeoutException
at com.netflix.hystrix.AbstractCommand.handleTimeoutViaFallback(AbstractCommand.java:997)
################## 걸린 시간 : 1146
Case 9.
아무런 설정을 하지 않음
실행 로그
feign.RetryableException: Read timed out executing GET http://localhost:22222/test/do
at feign.FeignException.errorExecuting(FeignException.java:213)
...
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
...
################## 걸린 시간 : 60008
테스트 케이스의 설정을 다음과 같다.
- Case 1, 2
feign.hystrix.enabled=false인 경우, feign.client.config.default.readTimeout 설정이 적용된다. - Case 3, 4, 5, 6, 7, 8
feign.hystrix.enabled=true인 경우
- 설정값 feign.client.config.default.readTimeout와
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 중 낮은 값이 적용된다. - hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds만 설정할 경우,
feign.client.config.default.readTimeout는 고려하지 않는다. - Case 7, 8이 약 1초가 적용된 이유는 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 의 기본값은 1,000을 따르기 때문이다.
- 설정값 feign.client.config.default.readTimeout와
- Case 9
아무런 설정을 하지 않은 경우, Case1, 2와 동일한 에러 로그가 출력된다.
feign.client.config.default.readTimeout 설정이 적용된것이고, 기본값은 60,000이다. - Case 6, 7, 8, 9
feign.client.config.default.readTimeout 기본값은 60,000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 기본값은 1,000
더 낮은 값은 hystrix 설정이기 때문에 Case 8에서 1,000이 적용됐다.
정리
hystrix를 사용하지 않을 경우 feign.client.config.default.readTimeout 설정을 하고
hystrix를 사용해야 한다면 feign.client.config.default.readTimeout와 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 두가지 값을 설정하되 기본값을 고려해야 한다.
※ Timeout은 10초도 길다고 볼 수 있다.
로직 처리 자체가 문제있는 것이므로 Timeout을 조절하기 보다는 로직을 수정 하는것이 옳바른 방법이다.