2017-03-08 45 views
5

我想在用戶訪問我的Flask應用中的頁面時增加計數器。如果兩個用戶訪問該頁面,計數應該增加2.我嘗試了以下操作,但計數總是1.如何增加每個訪問的值?對每個訪問Flask視圖的增量計數器

@app.route('/count') 
def make_count(): 
    count = 0 
    value = count + 1 
    return jsonify(count=value) 

回答

7

同時計數是困難的。假設計數爲0.如果兩個用戶都以足夠的時間間隔點擊端點,則它們每個都可以獲得值0,將其增加到1並放回。兩個用戶點擊了端點,但結果數爲1,而不是2.要解決這個問題,您需要使用支持自動增量的數據存儲(如同一個進程一次只能執行一個操作一樣)。

你不能使用簡單的Python global,因爲WSGI服務器會產生多個進程,所以他們每個人都有自己獨立的全局副本。重複的請求可能由不同的進程處理,導致不同的非同步值。

最簡單的解決方案是Python multiprocessing.Value。只要進程在創建值後生成,就可以跨進程同步對共享值的訪問。

from flask import Flask, jsonify 
from multiprocessing import Value 

counter = Value('i', 0) 
app = Flask(__name__) 

@app.route('/') 
def index(): 
    with counter.get_lock(): 
     counter.value += 1 

    return jsonify(count=counter.value) 

app.run(processes=8) 
# access http://localhost:5000/ multiple times quickly, the count will be correct 

還有一些注意事項:只要管理者還活着

  • 的數據僅仍然存在。如果您重新啓動服務器,計數器也會重置。
  • 如果應用程序進程分佈在多臺機器上,則共享內存會遇到與全局進程相同的問題:它們只在本地計算機上同步,而不是在網絡上進行同步。

對於真實世界的場景,Redis是一個更強大的解決方案。服務器獨立於Web應用程序,具有持久性選項,並且可以執行原子增量。它也可以用於應用程序的其他部分,例如緩存。