[英]How thread works in web application?
我試圖了解每個 web 請求如何在 rails 應用程序中工作。 為了理解我的邏輯,我寫了這個虛擬 controller。
class TestsController < ApplicationController
def index
puts 'Going to Sleep'
sleep 30.seconds
render json: { message: 'ok' }
end
end
我使用 puma 作為我的應用程序服務器。 我在生產模式下運行 Rails 服務器,並在瀏覽器的 5 個不同選項卡中訪問了locahost:3000/tests
。 我的理解是因為 puma 是並發服務器,每個請求將在不同的線程下運行,這就是為什么第一個請求阻塞的請求不會阻塞第二個請求的請求,因為該請求將由單獨的線程處理。
但是當我在終端中查看服務器日志時,我看到消息Going to Sleep
出現在第一個請求上,然后 ruby 進入睡眠狀態 30 秒。 對於第二個請求和其他請求,我在日志文件中沒有看到消息Going to Sleep
30 秒(直到第一個請求完成睡眠)。 這讓我很困惑,我認為對於瀏覽器上不同選項卡上的每 5 個請求,我會立即看到消息Going to Sleep
並且非請求會相互阻止。 但看起來我錯了。
有人可以向我解釋一下它是如何工作的嗎? 我的第一個請求是阻止其他請求。 這不是問題嗎? 在現實世界的應用程序中,如果我讓 api 調用第 3 方應用程序,並且如果得到響應所需的時間比它會阻止其他用戶的請求? 或者我是否需要從不同的 ip 地址發出 http 請求才能使並發工作? 請解釋。
UPDATA
下面是我的 puma 配置
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
這個問題的答案是 Rails 沒有阻塞,但您的瀏覽器是。
瀏覽器經常重用現有的套接字連接以減少網絡流量。 在這種情況下,打開一個新選項卡到完全相同的 URL 將嘗試重用與服務器的現有套接字連接。
瀏覽器本質上是試圖通過已經打開的連接將請求傳送到服務器。 由於此套接字連接正忙於等待您的Tests
controller 的index
操作,瀏覽器將阻塞。
要查看 Rails 確實會同時從同一個 controller 執行相同的操作,您必須從另一個瀏覽器打開新請求,或者您也可以使用wget
之類的工具從命令行測試它:
> wget -O - http://locahost:3000/tests &
> wget -O - http://locahost:3000/tests &
您將看到兩個請求都將通過 go 正常,因為它們每個都與服務器建立新的唯一連接。
結論:
導軌工作正常。 並發和線程按預期工作。 只是您的瀏覽器被阻止,因為它試圖重用已經打開的套接字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.