簡體   English   中英

在瓶子中的線程之間共享狀態

[英]Share state between threads in bottle

在運行在pythonanywhere上的Bottle應用程序中,我希望對象在請求之間保持不變

如果我寫這樣的話:

X = {'count': 0}

@route('/count')
def count():
    X['count'] += 1
    tpl = SimpleTemplate('Hello {{count}}!')
    return tpl.render(count=X['count'])

計數增加,這意味着X在請求之間保持不變。

我目前正在pythonanywhere上運行它,這是一項托管服務,在這里我無法控制Web服務器(我認為是nginx?)線程,負載平衡(如果有)等。

我的問題是,這是巧合嗎,因為它僅使用一個線程,而我進行測試的負載卻很小?

更一般而言,這將在什么時候停止工作? 例如,我有多個線程/套接字/實例/負載均衡服務器等...?

除此之外,即使我必須移至准系統服務器,做這樣的工作(堅持到瓶子)我最好的選擇是什么。

這是Bottle文檔必須針對其請求對象說的話:

LocalRequest的線程安全實例。 如果從請求回調中訪問,則此實例將始終引用當前請求(即使在多線程服務器上)。

但是我不完全理解這意味着什么,或者像我所使用的那樣,全局變量在多線程方面的地位如何。

TL; DR:您可能需要使用外部數據庫來存儲狀態。

如果您的應用程序很小,並且您計划始終只運行一個服務器進程,那么您當前的方法可以工作; 您需要做的“所有”操作是鎖定對共享狀態的每次訪問(!)(示例代碼中的dict X )。 (我在這里用“ all”括起來,因為它可能變得比起初聽起來更復雜。)

但是,由於您正在詢問多線程,因此我假設您的應用程序不只是玩具,這意味着您計划接收大量流量和/或希望同時處理多個請求。 在這種情況下,您將需要多個進程,這意味着您的方法(將狀態存儲在內存中)無法工作。 內存不跨進程共享。 跨進程共享狀態的(一般)方法是在外部(例如,在數據庫中)存儲狀態。

您熟悉Redis嗎? 那將在我的候選人短名單上。

我通過與PythonAnywhere支持人員聯系來尋求答案,他說:

當您使用免費的 PythonAnywhere帳戶運行網站時,只有一個進程可以處理您的所有請求-因此,像您使用的那樣使用全局變量就可以了。 但是,只要您想擴大規模並獲得(例如)一個黑客帳戶,您就會擁有多個進程(而不是線程)-當然,每個進程都有其自己的全局變量,因此一切都會進行錯誤。

因此,該部分討論了PythonAnywhere的細節,說明了它為什么起作用以及何時停止在那里工作。

第二部分的答案,關於如何在多個Bottle進程之間共享變量,一旦他們了解到數據庫在這種情況下將無法正常運行,我也會得到他們的支持(最有幫助!)。

當然,不同的流程不能共享變量,最可行的解決方案是:

編寫自己的緩存服務器來處理將內容保存在內存中的過程。您將有一個始終運行的進程,並且Web API請求將以某種方式對其進行訪問(內部REST API?)。 它可以將內容保留在內存中[...]

附言:我沒想到會有其他回復告訴我將狀態存儲在數據庫中,我發現我要問的事實意味着我有充分的理由不使用數據庫,這很浪費時間!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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