자체 호스팅 포럼에서 502 및 503 오류가 자주 발생해요

제가 직접 호스팅하는 포럼(https://intfiction.org/)이 지난 몇 주간 매우 느려졌고, 502 및 503 오류가 자주 발생하고 있습니다.

안정 버전(stable branch) 2026.1.5를 사용 중입니다.

여기서 해당 오류를 검색해 보았지만, 명확한 원인을 찾지 못했습니다:

  • 포럼은 정상적으로 빌드되고 시작됩니다.
  • 서버 용량이 충분한 것으로 보입니다 (디스크 공간 13.5GB 여유, RAM 1.6/1.9G, 스왑 1.7/2.2G).

httop을 확인해 보니 부하 평균(load average)이 높은 것으로 보입니다: 1.67, 1.55, 3.12. 이 프로세스가 때때로 CPU의 40% 이상을 사용하기도 합니다: unicorn worker[0] -E production -c config/unicorn.conf.rb.

포럼 로그에서 다음과 같은 오류가 많이 보입니다:

Job exception: execution expired

net-smtp-0.5.1/lib/net/smtp.rb:663:in 'TCPSocket#initialize' 
net-smtp-0.5.1/lib/net/smtp.rb:663:in 'IO.open' 
net-smtp-0.5.1/lib/net/smtp.rb:663:in 'Net::SMTP#tcp_socket' 
net-smtp-0.5.1/lib/net/smtp.rb:672:in 'block in Net::SMTP#do_start' 
timeout-0.5.0/lib/timeout.rb:222:in 'block in Timeout.timeout' 
timeout-0.5.0/lib/timeout.rb:229:in 'Timeout.timeout' 
net-smtp-0.5.1/lib/net/smtp.rb:671:in 'Net::SMTP#do_start' 
net-smtp-0.5.1/lib/net/smtp.rb:642:in 'Net::SMTP#start' 
mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:154:in 'Mail::SMTP#start_smtp_session' 
mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:108:in 'Mail::SMTP#deliver!' 
mail-2.9.0/lib/mail/message.rb:269:in 'Mail::Message#deliver!' 
/usr/local/lib/ruby/3.4.0/delegate.rb:87:in 'Delegator#method_missing'
/var/www/discourse/lib/email/sender.rb:296:in 'Email::Sender#send' 
/var/www/discourse/lib/email/processor.rb:151:in 'Email::Processor#handle_failure' 
/var/www/discourse/lib/email/processor.rb:31:in 'Email::Processor#process!' 
/var/www/discourse/lib/email/processor.rb:13:in 'Email::Processor.process!' 
/var/www/discourse/app/jobs/regular/process_email.rb:8:in 'Jobs::ProcessEmail#execute' 
/var/www/discourse/app/jobs/base.rb:318:in 'block (2 levels) in Jobs::Base#perform' 
rails_multisite-7.0.0/lib/rails_multisite/connection_management/null_instance.rb:49:in 'RailsMultisite::ConnectionManagement::NullInstance#with_connection'
rails_multisite-7.0.0/lib/rails_multisite/connection_management.rb:17:in 'RailsMultisite::ConnectionManagement.with_connection'
/var/www/discourse/app/jobs/base.rb:305:in 'block in Jobs::Base#perform' 
/var/www/discourse/app/jobs/base.rb:301:in 'Array#each' 
/var/www/discourse/app/jobs/base.rb:301:in 'Jobs::Base#perform' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in 'Sidekiq::Processor#execute_job' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in 'block (4 levels) in Sidekiq::Processor#process' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in 'Sidekiq::Middleware::Chain#traverse' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in 'block in Sidekiq::Middleware::Chain#traverse' 
/var/www/discourse/lib/sidekiq/suppress_user_email_errors.rb:6:in 'Sidekiq::SuppressUserEmailErrors#call' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in 'Sidekiq::Middleware::Chain#traverse' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in 'block in Sidekiq::Middleware::Chain#traverse' 
/var/www/discourse/lib/sidekiq/discourse_event.rb:6:in 'Sidekiq::DiscourseEvent#call' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in 'Sidekiq::Middleware::Chain#traverse' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in 'block in Sidekiq::Middleware::Chain#traverse' 
/var/www/discourse/lib/sidekiq/pausable.rb:131:in 'Sidekiq::Pausable#call' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in 'Sidekiq::Middleware::Chain#traverse' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in 'block in Sidekiq::Middleware::Chain#traverse' 
sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in 'Sidekiq::Job::InterruptHandler#call' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in 'Sidekiq::Middleware::Chain#traverse' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in 'block in Sidekiq::Middleware::Chain#traverse' 
sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in 'Sidekiq::Metrics::ExecutionTracker#track' 
sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in 'Sidekiq::Metrics::Middleware#call' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in 'Sidekiq::Middleware::Chain#traverse' 
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in 'Sidekiq::Middleware::Chain#invoke' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in 'block (3 levels) in Sidekiq::Processor#process' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in 'block (6 levels) in Sidekiq::Processor#dispatch' 
sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in 'Sidekiq::JobRetry#local' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in 'block (5 levels) in Sidekiq::Processor#dispatch' 
sidekiq-7.3.9/lib/sidekiq/config.rb:39:in 'block in <class:Config>' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in 'block (4 levels) in Sidekiq::Processor#dispatch' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in 'Sidekiq::Processor#stats' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in 'block (3 levels) in Sidekiq::Processor#dispatch' 
sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in 'Sidekiq::JobLogger#call' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in 'block (2 levels) in Sidekiq::Processor#dispatch' 
sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in 'Sidekiq::JobRetry#global' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in 'block in Sidekiq::Processor#dispatch' 
sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in 'Sidekiq::JobLogger#prepare' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in 'Sidekiq::Processor#dispatch' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in 'block (2 levels) in Sidekiq::Processor#process' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in 'Thread.handle_interrupt' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in 'block in Sidekiq::Processor#process' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in 'Thread.handle_interrupt' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in 'Sidekiq::Processor#process' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in 'Sidekiq::Processor#process_one' 
sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in 'Sidekiq::Processor#run' 
sidekiq-7.3.9/lib/sidekiq/component.rb:10:in 'Sidekiq::Component#watchdog' 
sidekiq-7.3.9/lib/sidekiq/component.rb:19:in 'block in Sidekiq::Component#safe_thread' 

또한 Redis와 관련된 메시지도 많이 보고 있습니다:

Job exception: Connection timed out - user specified timeout: 1.0s (redis://localhost:6379)

Your Redis network connection is performing extremely poorly.
Last RTT readings were [403941, 62224, 151840, 1536008, 3440226], ideally these should be < 1000.
Ensure Redis is running in the same AZ o

하지만 이것이 Redis가 원인이 되는 것인지, 아니면 단순히 증상인지는 알 수 없습니다.

방금 ./launcher rebuild app을 실행해 보았지만, 상황이 나아지지 않았습니다. 이 서버에서 무엇이 잘못되고 있는지 진단하는 방법에 대한 아이디어가 있을까요?

RAM을 조금 더 늘려보시는 게 좋을 것 같습니다. 도움이 될 수 있습니다.

top을 보다가 몇 가지 더 발견했습니다:

postgres: 15/main: discourse discourse [local] idle 프로세스가 1분 넘게 CPU 사용률이 90%까지 올라가는 것을 확인했습니다.
수정: 포럼이 일일 백업 작업을 수행 중이었기 때문에 이것이 원인이었던 것 같습니다.

이 서버에서 메일 수신기를 실행 중인데, 스팸 메일 웨이브에 자주 노출되는 것 같습니다:

들어오는 스팸 이메일이 계속 쏟아지는 것은 도움이 되지 않습니다.

하지만 동의합니다 - 가능하면 RAM을 추가하세요. 두 배로 늘리세요.