视图的增量计数器

视图的增量计数器

本文介绍了每次访问 Flask 视图的增量计数器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在用户访问我的 Flask 应用程序中的页面时增加一个计数器.如果有两个用户访问该页面,则计数应增加 2.我尝试了以下操作,但计数始终为 1.如何为每次访问增加值?

I want to increment a counter when users access a page in my Flask app. If two users access the page, the count should increase by 2. I tried the following but the count is always 1. How do I increment the value for each access?

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

推荐答案

并发计数很难.假设计数为 0.如果两个用户都以足够近的间隔击中端点,他们可能每个人都得到值 0,将其增加到 1,然后将其放回原处.两个用户点击了端点,但结果计数是 1,而不是 2.要解决这个问题,您需要使用支持原子递增的数据存储(例如,一次只有一个进程可以执行的操作).

Counting concurrently is hard. Assume the count is 0. If two users both hit the endpoint at close enough intervals, they may each get the value 0, increment it to 1, and put it back. Two users hit the endpoint, but the resulting count is 1, not 2. To get around this, you need to use a data store that supports incrementing atomically (as in, an operation that only one process can do at a time).

你不能使用简单的 Python global 因为 WSGI 服务器会产生多个进程,所以它们每个都有自己独立的全局副本.重复的请求可能由不同的进程处理,导致不同的、不同步的值.

You can't use a simple Python global because WSGI servers will spawn multiple processes, so they will each have their own independent copy of the global. Repeated requests could be handled by different processes, resulting in different, unsynchronized values.

最简单的解决方案是 Python multiprocessing.Value.只要在创建值后生成进程,这就会同步跨进程对共享值的访问.

The simplest solution is a Python multiprocessing.Value. This synchronizes access to a shared value across processes, as long as the processes are spawned after the value is created.

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
        out = counter.value

    return jsonify(count=out)

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

还有一些注意事项:


There are still some caveats:

  • 数据仅在管理器活着时才存在.如果您重新启动服务器,计数器也会重置.
  • 如果应用进程分布在多台机器上,共享内存会遇到与全局变量相同的问题:它们只在本地机器上同步,而不是跨网络同步.

对于现实世界的场景,Redis 是一个更强大的解决方案.服务器独立于 Web 应用程序,具有持久性选项,并且可以进行原子增量.它还可以用于应用程序的其他部分,例如缓存.

For real world scenarios, Redis is a much more robust solution. The server is independent of the web application, has options for persistence, and can do atomic increments. It can also be used for other parts of the application, such as caching.

这篇关于每次访问 Flask 视图的增量计数器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 13:51