使用 FastAPI 计算全局变量的请求数

ida*_*hal 6 python python-asyncio asgi fastapi uvicorn

我想统计特定 URL 路径中的请求数。

app = FastAPI()
counter = 0

@app.get("/do_something")
async def do_something():
    global counter
    counter += 1
    return {"message": "Hello World"}
Run Code Online (Sandbox Code Playgroud)

这段代码可以吗?计数器应该是线程安全的?阿辛西奥安全吗?这是计算请求的正确方法(没有数据库)吗?在这种情况下,“do_something”函数中的“async”有含义吗?以及如何让它与多个工人一起工作?

ida*_*hal 6

如果您使用 1 个工作线程,您应该使用 asyncio 锁,因为 fastAPI 是异步的。

import asyncio

app = FastAPI()
counter_lock = asyncio.Lock()
counter = 0

@app.get("/do_something")
async def do_something():
    global counter

    async with counter_lock:
        counter += 1

    return {"message": "Hello World"}
Run Code Online (Sandbox Code Playgroud)

但是,如果有超过 1 个工作线程则无法工作,因为它们不共享相同的内存。应该使用缓存机制或数据库,如此处所解释


Coo*_*kie 5

此代码不安全,因为您没有使用锁。我认为您认为 += 操作是原子的,因此无需锁定即可安全使用,但事实并非如此。为了保护你的状态,你需要锁。asyncio 库提供锁https://docs.python.org/3/library/asyncio-sync.html

import asyncio

app = FastAPI()
counter = 0
lock = asyncio.Lock()

@app.get("/do_something")
async def do_something():
    global counter

    async with lock:
        counter += 1
        # some other thread-safe code here

    return {"message": "Hello World"}
Run Code Online (Sandbox Code Playgroud)