Spring Boot REST API - 요청 시간 초과?
요청의 일부로 서드파티 서비스를 호출하는 Spring Boot REST 서비스가 있습니다.모든 자원(예를 들어 5초)에 타임아웃을 설정하여 요청 처리(수신에서 응답까지 체인 전체)가 5초 이상 걸릴 경우 컨트롤러는 실제 응답이 아닌 HTTP 503으로 응답합니다.이것이 Spring 속성일 경우(예: 설정)는 매우 편리합니다.
spring.mvc.async.request-timeout=5000
아직 운이 안 좋았어요WebMvc Configuration Support를 확장하고 configureAsync Support를 덮어쓰려고 시도했습니다.
@Override
public void configureAsyncSupport(final AsyncSupportConfigurer configurer) {
configurer.setDefaultTimeout(5000);
configurer.registerCallableInterceptors(timeoutInterceptor());
}
@Bean
public TimeoutCallableProcessingInterceptor timeoutInterceptor() {
return new TimeoutCallableProcessingInterceptor();
}
아무 행운도 없이
모든 서드파티 콜의 시간을 수동으로 재야 하며, 시간이 너무 오래 걸리면 타임아웃 예외를 발생시켜야 합니다.그래요?아니면 모든 요청 엔드포인트를 커버할 수 있는 더 쉽고 종합적인 솔루션이 있을까요?
반품하셔야 합니다.Callable<>
네가 원한다면spring.mvc.async.request-timeout=5000
일하기 위해.
@RequestMapping(method = RequestMethod.GET)
public Callable<String> getFoobar() throws InterruptedException {
return new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(8000); //this will cause a timeout
return "foobar";
}
};
}
그@Transactional
annotation은 타임아웃 파라미터를 사용합니다.이 파라미터에서는 특정 메서드의 타임아웃을 초단위로 지정할 수 있습니다.@RestController
@RequestMapping(value = "/method",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@Transactional(timeout = 120)
Spring Boot 2.2에 대한 새로운 답변이 필요합니다.server.connection-timeout=5000
는 권장되지 않습니다.각 서버의 동작은 다르기 때문에 서버 고유의 속성이 권장됩니다.
SpringBoot에는 기본적으로 Tomcat이 내장되어 있습니다(Jetty 등으로 재구성하지 않은 경우).다음과 같은 서버별 애플리케이션 속성 사용server.tomcat.connection-timeout
또는server.jetty.idle-timeout
.
Wilkinson의 코멘트:
접속 타임 아웃을 설정하면, 클라이언트가 접속했을 때만 타임 아웃이 됩니다만, 요구를 송신하기에는 너무 느립니다.클라이언트가 응답을 최대 30초 동안 대기하려면 클라이언트 측에서 응답을 설정해야 합니다.서버 측에서 요청을 처리하는 데 최대 30초밖에 걸리지 않도록 하려면 요청을 처리하는 스레드를 강제로 중지할 수 없으므로 이 작업을 보장할 수 없습니다.
설정을 시도해 볼 수도 있습니다.spring.mvc.async.request-timeout
Spring Cloud Netflix Hystrix 스타터를 통해 잠재적으로 신뢰성이 낮거나 느린 원격 통화를 처리할 수 있습니다.서킷 브레이커 패턴을 실장하고 있습니다.이 패턴은 정확하게 이 분류를 목적으로 하고 있습니다.
해 보세요.server.connection-timeout=5000
application.properties로 이동합니다.공식 문서:
server.connection-timeout= # 커넥터가 연결을 닫기 전에 다른 HTTP 요청을 기다리는 시간(밀리초 단위).설정하지 않으면 커넥터의 컨테이너별 기본값이 사용됩니다.값 -1을 사용하여 타임아웃 없음(즉, 무한)을 나타냅니다.
한편, 클라이언트측의 타임 아웃에 대해서는, 다음의 회답에서 이미 설명한 대로 서킷 브레이커 패턴을 사용해 처리할 수 있습니다.https://stackoverflow.com/a/44484579/2328781
RestTemplate를 사용하는 경우 다음 코드를 사용하여 타임아웃을 구현해야 합니다.
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(clientHttpRequestFactory());
}
private ClientHttpRequestFactory clientHttpRequestFactory() {
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(2000);
factory.setConnectTimeout(2000);
return factory;
}}
xml 설정
<bean class="org.springframework.web.client.RestTemplate">
<constructor-arg>
<bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"
p:readTimeout="2000"
p:connectTimeout="2000" />
</constructor-arg>
Spring 속성 파일에서는 이 속성의 숫자만 지정할 수 없습니다.단위도 지정해야 합니다. 말하면 .spring.mvc.async.request-timeout=5000ms
★★★★★★★★★★★★★★★★★」spring.mvc.async.request-timeout=5s
5번으로 하다
어떤 대답도 문제를 해결하지 못하는 것 같아요.Spring Boot의 임베디드 서버에 요청 처리 최대 시간을 알려주셔야 할 것 같습니다.그 방법은 사용하는 임베디드 서버의 종류에 따라 다릅니다.
Undertow의 경우 다음을 수행할 수 있습니다.
@Component
class WebServerCustomizer : WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
override fun customize(factory: UndertowServletWebServerFactory) {
factory.addBuilderCustomizers(UndertowBuilderCustomizer {
it.setSocketOption(Options.READ_TIMEOUT, 5000)
it.setSocketOption(Options.WRITE_TIMEOUT, 25000)
})
}
}
Spring Boot 공식문서
Springboot REST 서비스의 비동기 스레드 실행자를 설정할 수 있습니다.setKeepAliveSeconds()는 요청 체인의 실행 시간을 고려해야 합니다.ThreadPoolExecutor의 keep-alive(초)를 설정합니다.기본값은 60 입니다.이 설정은 런타임에 JMX를 통해 변경할 수 있습니다.
@Bean(name="asyncExec")
public Executor asyncExecutor()
{
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(3);
executor.setMaxPoolSize(3);
executor.setQueueCapacity(10);
executor.setThreadNamePrefix("AsynchThread-");
executor.setAllowCoreThreadTimeOut(true);
executor.setKeepAliveSeconds(10);
executor.initialize();
return executor;
}
다음으로 REST 엔드포인트를 다음과 같이 정의할 수 있습니다.
@Async("asyncExec")
@PostMapping("/delayedService")
public CompletableFuture<String> doDelay()
{
String response = service.callDelayedService();
return CompletableFuture.completedFuture(response);
}
언급URL : https://stackoverflow.com/questions/34852236/spring-boot-rest-api-request-timeout
'programing' 카테고리의 다른 글
레일 3의 JS/ERB 템플릿에서 JSON 처리 (0) | 2023.03.19 |
---|---|
Angular를 사용하여 객체를 배열에 푸시하는 방법JS (0) | 2023.03.19 |
Oracle SQL에서의 커스텀 오더 (0) | 2023.03.19 |
각도:약속, 지도, 세트 및 반복자를 찾을 수 없습니다. (0) | 2023.03.19 |
Android - JSON Array 및 JSON 객체 생성 (0) | 2023.03.19 |