簡體   English   中英

線程如何在 web 應用程序中工作?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM