2017-03-08 26 views
5

Kullanıcılar Flask uygulamasında bir sayfaya eriştiğinde bir sayacı artırmak istiyorum. İki kullanıcı sayfaya erişirse, sayım 2 artar. Aşağıdakileri denedim ama sayı her zaman 1'dir. Her erişim için değeri nasıl artırırım?Bir Şişelik görünümüne her erişim için artış sayacı

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

cevap

7

Eş zamanlı olarak saymak zor. Sayımın 0 olduğunu varsayalım. İki kullanıcı da son noktayı yeterince yakın aralıklarla vurursa, her biri 0 değerini alır, 1'e kadar artırır ve geri koyabilirler. İki kullanıcı son noktaya çarptı, ancak sonuç sayısı 1 değil, 2'dir. Bunu aşmak için atomik olarak artan bir veri deposunu kullanmanız gerekir (her seferinde sadece bir işlemin yapabileceği bir işlem olduğu gibi).

Basit bir Python global kullanamazsınız, çünkü WSGI sunucuları birden fazla işlem üretecektir, böylece bunların her birinin kendi bağımsız bağımsız kopyası vardır. Tekrarlanan istekler, farklı süreçler tarafından ele alınabilir ve farklı, senkronize olmayan değerler elde edilir.

En basit çözüm Python multiprocessing.Value'dur. Bu, süreç oluşturulduktan sonra süreçler ortaya çıktığı sürece, işlemler arasında paylaşılan bir değere erişimi senkronize eder.

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 

hala bazı uyarılar vardır:

  • veriler sadece sürece yönetici hayatta olduğu gibi devam eder. Sunucuyu yeniden başlatırsanız, sayaç da sıfırlanır.
  • Uygulama işlemleri birden çok makineye dağıtılıyorsa, paylaşılan bellek, globals ile aynı sorunlara sahiptir: bunlar ağ üzerinden değil, yalnızca yerel makinede senkronize edilir.

Gerçek dünya senaryoları için, Redis çok daha güçlü bir çözümdür. Sunucu, web uygulamasından bağımsızdır, kalıcılık için seçenekleri vardır ve atomik artışlar yapabilir. Ayrıca, uygulamanın önbelleğe alınması gibi diğer kısımları için de kullanılabilir.