You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

aiohttp多用户访问时出现实例变量值共享是什么原因?

问题结论

该现象和aiohttp的运行模式无关,是类实例的使用方式错误导致的。

原因说明

你在模块导入阶段、全局作用域下实例化的对象,是服务进程内全局共享的单例。aiohttp默认通过web.run_app启动时是单进程异步模型,所有用户请求的处理协程都运行在同一个事件循环中,共享进程内的所有全局对象:

  • 单用户访问时,所有操作都作用在这一个实例上,逻辑不会出现异常
  • 多用户并发访问时,任意一个请求调用instance.changevalue()修改的都是这份全局共享的实例属性,修改结果会被所有后续请求(包括其他用户发起的请求)直接读取,自然就会出现跨设备的状态串扰问题。

修复方案

不要在全局作用域实例化存储用户状态的可变对象,根据业务场景选择对应实现:

  • 如果实例状态不需要跨请求保留:直接在每个路由处理函数内部做实例化,每个请求持有独立的实例,请求处理完成后实例自动回收,完全不会出现跨请求污染
    from aiohttp import web
    
    # 仅定义类,不要在全局作用域实例化
    class StateClass:
        def __init__(self):
            self.user_value = 0
        def changevalue(self, val):
            self.user_value = val
    
    async def route_handler(request):
        # 每个请求进来创建专属实例
        req_instance = StateClass()
        # 后续业务逻辑操作当前请求的req_instance即可
        return web.Response(text=f"current value: {req_instance.user_value}")
    
    app = web.Application()
    app.add_routes([web.get("/", route_handler)])
    
    if __name__ == "__main__":
        web.run_app(app)
    
  • 如果需要在同个用户的多个请求间保留状态:基于会话ID做状态隔离,把不同用户的状态存在独立的会话存储中,不要把状态直接挂在全局对象上。

补充:异步服务开发中要特别注意,所有全局作用域的可变对象都是跨请求共享的,任何修改都会影响所有并发请求,涉及用户专属状态的对象一定要做请求/会话级别的隔离。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:51:28