티스토리 뷰
출근길에 Out Of Memory Alert을 받았다. 원인은 아침에 kakao plus 친구로 진행한 광고였다. 순간적으로 분당 5,000건으로 Request가 급격하게 증가했다. 하지만 이 서버는 하루중 가장 요청을 받이 받을때에는 5,000건도 원활하게 Request를 처리한다. 그렇다면 왜 Out Of Memory가 발생했을까? Heap Dump를 추출하여 확인해 보았다. 특정 ConcurrentHashMap에서 전체 사용 가능한 Memory의 70% 정도를 사용하고 있었다. 이상했다. 이런 비슷한 상황이 있을것 같아 구글링을 해보았는데 역시나 있었다. 이 상황의 원인과 해결방법은 아래 Blog를 참고했다.
원인은 Controller에서 특정 Page로 Redirect하는 방법이었다.
@GetMapping(value = "/link/{key}")
public String redirectLinkPage(@PathVariable(name = "key") String key) {
...
String linkUrl = getLinkUrl(...);
return "redirect:" + linkUrl; // <- 위험 포인트!
}
"redirect:linkUrl"이 return되면 아래와 같은 과정을 거치는데, 이 때 viewName을 Caching하는 과정에서 문제가 발생 수 있다.
org.springframework.beans.factory.config.BeanPostProcessor
-> AnnotationAwareAspectJAutoProxyCreator
-> ConcurrentHashMap<Object, Boolean> Map에 viewName:필요 여부(boolean) 를 갯수 제한 없이 저장
구체적으로 말하면 위 코드중 getLinkUrl(...)은 동적으로 URL을 생성하는 메소드이다. 이 메소드를 통해 생성되는 URL은 N개이고 Unique한 속석을 가지는 Parameter가 붙는다. 즉 Request 마다 새로운 URL이 생성되고, 이 URL을 제한 없이 Caching 하면서 결국 Out Of Memory가 발생하게 된다. 고정된 형태의 URL을 리턴한다면 이 이슈는 발생하지 않는다.
참고:
https://taetaetae.github.io/2019/01/10/spring-redirect-oom/
https://www.baeldung.com/spring-redirect-and-forward
https://github.com/spring-projects/spring-framework/issues/14698
https://github.com/spring-projects/spring-framework/issues/7831
'Programming > Spring' 카테고리의 다른 글
RetryTemplate (0) | 2019.07.24 |
---|---|
[주의] Controller Parameter Mapping Exception (0) | 2019.07.09 |
[주의] DI 우선 순위 (0) | 2019.06.27 |
SmartLifecycle (0) | 2019.06.10 |
JDBC Template (0) | 2019.05.05 |
- Total
- Today
- Yesterday
- Spring JDBC Template
- Property
- Akka
- 복합키 Mapping
- RetryTemplate
- SmartLifecycle
- Typesafe Config
- @Primary
- Mapping
- Spring
- spring spel
- java generic
- Query DSL
- java Equals
- Criteria
- Registrar
- JPA
- Discriminate Mapping
- JPA Criteria
- Charles proxy
- java EqualsAndHashCode
- DI
- Embedded Mapping
- Spring Registrar
- Sprint RetryTemplate
- Join Table
- docker
- scikit-learn
- guava
- Embeddable Mapping
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |