Heroku에서 Puma와 함께 Thruster 사용 고려: Keepalive 연결 지연 문제 해결

Consider Thruster with Puma on Heroku | Island94.org

작성자
Ruby Weekly
발행일
2025년 07월 26일

핵심 요약

  • 1 Heroku 환경에서 Puma 웹 서버가 keepalive 연결을 처리하는 방식 때문에 예기치 않은 지연이 발생할 수 있습니다.
  • 2 Heroku의 새로운 Router 2.0이 keepalive를 지원하면서 이 문제가 더욱 부각되었으며, Heroku는 Puma 설정 변경을 권장합니다.
  • 3 Thruster를 사용하여 Heroku 라우터와 Thruster 간에는 keepalive를 유지하고 Thruster와 Puma 간에는 keepalive를 비활성화하여 성능 문제를 효과적으로 우회할 수 있습니다.

도입

본 문서는 Heroku 환경에서 Ruby on Rails 애플리케이션의 성능 최적화와 관련된 중요한 이슈를 다룹니다. 특히, Puma 웹 서버가 keepalive 연결을 처리하는 과정에서 발생하는 예기치 않은 지연 현상에 초점을 맞춥니다. Heroku가 새로운 네트워크 라우터인 'Router 2.0'을 도입하면서 연결 keepalive를 지원하게 되었고, 이는 Heroku 라우터와 애플리케이션 dyno 간의 TCP 핸드셰이크 수를 줄여 잠재적으로 지연 시간을 단축할 수 있는 기회를 제공했습니다. 그러나 이러한 변화는 Puma의 특정 동작 방식과 결합하여 부하가 걸렸을 때 요청 처리 순서 및 우선순위에서 예측 불가능한 지연을 초래할 수 있음을 지적합니다. Heroku는 이 문제에 대해 상세한 분석을 제공하며, Puma의 keepalive 연결 비활성화 또는 `max_fast_inline` 설정을 비활성화하는 등의 해결책을 제시했습니다. 하지만 본 문서에서는 이러한 기존의 해결책 외에 'Thruster'를 활용하는 제3의 대안을 제안하며, 이 방식이 어떻게 Puma의 keepalive 관련 성능 문제를 효과적으로 완화할 수 있는지 탐구합니다.

Puma의 keepalive 관련 지연 문제를 해결하기 위한 Heroku의 공식적인 권장 사항은 Puma 내부 설정을 조정하는 것입니다. 여기에는 Puma의 연결 keepalive를 완전히 비활성화하거나, max_fast_inline 설정을 비활성화하는 방법이 포함됩니다. 그러나 이러한 방법들은 잠재적으로 keepalive가 제공하는 성능 이점을 상쇄할 수 있습니다. 본 문서에서 제안하는 세 번째이자 더 효과적인 대안은 ‘Thruster’를 활용하는 것입니다. Thruster는 Go 언어로 작성된 프록시 서버로, Heroku 라우터와 애플리케이션 dyno 사이에서 연결을 중계하는 역할을 합니다. 이 접근 방식의 핵심은 다음과 같습니다:

  • Heroku 라우터와 Thruster 간의 연결: Heroku 네트워크 상에서 Heroku 라우터와 애플리케이션 dyno 내에서 실행되는 Thruster 간의 요청은 연결 keepalive를 사용할 수 있습니다. Thruster는 Go의 net/http 라이브러리를 기반으로 하며, 기본적으로 keepalive를 지원하므로 이 부분에서 성능 이점을 유지할 수 있습니다.
  • Thruster와 Puma 간의 로컬 연결: 애플리케이션 dyno 내부에서 Thruster와 Puma 간의 로컬 요청은 연결 keepalive를 비활성화할 수 있습니다. 이 연결은 모두 동일한 dyno 내에서 발생하므로 TCP 핸드셰이크로 인한 네트워크 지연이 발생하지 않아 성능에 미치는 영향이 미미합니다. 이로써 Puma의 keepalive 관련 문제를 우회하면서도 전체적인 성능 저하를 방지할 수 있습니다.

Thruster를 Puma와 함께 Heroku에 통합하는 과정은 비교적 간단합니다. 다음 세 단계를 따르면 됩니다:

  1. thruster gem 추가: Gemfile에 thruster gem을 추가합니다.
  2. Procfile 업데이트: Procfileweb: HTTP_PORT=$PORT TARGET_PORT=3001 bundle exec thrust bin/rails server와 같이 업데이트하여 Thruster가 Puma 앞에 위치하도록 합니다.
  3. Puma keepalive 비활성화: Puma 설정 파일에서 enable_keep_alives false를 추가하여 Puma의 keepalive를 비활성화합니다.

저자는 이미 x-sendfile 지원의 이점 때문에 Heroku에서 Puma와 함께 Thruster를 사용하고 있었음을 밝히며, Thruster가 추가 프로세스임에도 불구하고 자원 사용량이 매우 미미하다고 강조합니다. 실제 측정 결과, Rails 앱이 Puma에서 200MB를 사용하는 반면 Thruster는 약 13MB만을 사용하여 리소스 오버헤드가 작음을 입증합니다. 이는 Thruster가 성능 문제를 해결하면서도 시스템 자원에 큰 부담을 주지 않는 효율적인 솔루션임을 시사합니다.

결론

결론적으로, Heroku 환경에서 Puma 웹 서버의 keepalive 연결 관련 성능 문제는 Heroku Router 2.0의 도입과 함께 더욱 중요한 고려 사항이 되었습니다. 기존의 Puma 설정 변경을 통한 해결책은 잠재적인 성능 저하를 수반할 수 있습니다. 본 문서에서 제시된 Thruster를 활용한 접근 방식은 Heroku 라우터와 애플리케이션 간의 keepalive 이점을 유지하면서도 Puma 내부의 keepalive 관련 문제를 효과적으로 우회하는 현명한 대안을 제공합니다. 이는 Heroku 라우터와 Thruster 사이에서는 keepalive를 활용하고, Thruster와 Puma 사이에서는 로컬 연결의 특성을 활용하여 keepalive를 비활성화함으로써 가능해집니다. 또한, Thruster가 자원 사용량이 매우 적다는 점은 이 솔루션의 실용성을 더욱 높입니다. 따라서 Heroku에서 Ruby on Rails 애플리케이션의 성능 최적화를 고려하는 개발자들에게 Thruster는 Puma의 keepalive 문제에 대한 강력하고 효율적인 해결책으로 적극 권장될 수 있습니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!