자바 21 가상 스레드 - 이봐, 나의 잠금은 어디에 있나요?
Java를 광범위하게 사용하는 것으로 유명한 넷플릭스는 성능 이점을 위해 가상 스레드를 도입하는 데 열광했습니다. 그러나 Java 21로 마이그레이션하는 동안 엔지니어들은 SpringBoot 3 및 임베디드 Tomcat과 함께 가상 스레드를 사용하는 애플리케이션에서 간헐적인 시간 초과와 응답하지 않는 인스턴스를 경험했습니다. 조사 결과, 애플리케이션이 연결을 닫지 못하는 closeWait 상태에 갇힌 소켓이 급증한 것으로 나타났습니다. 처음에는 스레드 덤프에 유휴 JVM이 표시되었지만, 특정 명령을 사용한 추가 분석 결과 생성되었지만 아직 실행되지 않은 스레드인 "빈" 가상 스레드가 다수 발견되었습니다. 이는 가상 스레드 실행에 문제가 있음을 의미하며, Tomcat이 들어오는 각 요청에 대해 새 가상 스레드를 생성하고 있지만 기본 운영 체제 스레드가 모두 사용 중이라는 것을 의미했습니다. 스레드 덤프에 대한 심층 분석 결과, 이러한 운영 체제 스레드는 코드의 동기화된 블록 내에서 잠금을 획득하기 위해 대기 중인 가상 스레드에 고정되어 있는 것으로 나타났습니다. 원인은 대기 작업을 완료한 후 잠금을 다시 획득할 수 없는 일반 플랫폼 스레드가 보유한 잠금이었습니다. 이 교착 상태로 인해 새로운 가상 스레드가 예약되지 않아 성능 문제가 관찰되었습니다.