V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
ltttx
V2EX  ›  Python

Web 服务中如何使异步资源满足高并发需求

  •  
  •   ltttx · 2015-06-04 10:55:27 +08:00 · 2989 次点击
    这是一个创建于 3470 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一个资源(S1),每次初始化需要花费(T1)的时间。现在的做法很简单,后台首次启动的情况下,会异步初始化(N)个可用的(S1)放在redis队列(Q1)中。每次用户开始请求(S1)时,简单的从队列(Q1)中取一个(S1)返回给用户,同时后台会判断如果队列里可用资源长度小于(M)时会异步生成一个新的(S1)放进队列(Q1)中。但是这样的方案有问题:

    1. 如果获取资源的速度过快(并发高),会导致资源(S1)还没有初始化完成就返回给用户了,这肯定是不行的,因为有些属性必须是(S1)初始化完成的情况下才能获取。

    针对问题1, 想过使用两个队列进行解决,开始初始化(S1)时,将(S1)push到队列(Q1)中,等(S1)初始化完成推送到(Q2)中,每次取都从(Q2)中获取。但是这样还是存在一些问题...

    1. 此类问题应该是很常见的,奈何知识有限想不到其他什么更好的办法?大家有更好的建议吗?
    8 条回复    2015-06-09 08:43:40 +08:00
    clino
        1
    clino  
       2015-06-04 13:00:54 +08:00
    请求用队列,返回就不一定用队列了吧
    比如用户请求以后生成一个信箱,将请求和信箱号一起发到队列中,异步处理的地方初始化完以后直接把结果发往信箱即可
    这样用户发出请求以后只要一直等自己的信箱有返回就行了

    没搞过实际这种情况,根据楼主的信息初步想的
    pubby
        2
    pubby  
       2015-06-04 13:07:37 +08:00
    预先生成好结果放到队列,只是解决突然的一波请求峰值,持续的高并发还是没法解决。

    最后瓶颈还是在T1耗时的那个步骤,如果无法优化只能堆硬件
    fangjinmin
        3
    fangjinmin  
       2015-06-04 13:17:01 +08:00
    这样只能你通过在生产环境上,取到访问的峰值,在这个峰值基础上优化你的程序。
    监控你的S1资源的个数,根据变化调整你的程序吧。
    mhycy
        4
    mhycy  
       2015-06-04 14:14:47 +08:00
    高并发用缓存...
    数据有更新的时候同时刷新缓存.
    wy315700
        5
    wy315700  
       2015-06-04 14:17:37 +08:00
    去看看排队论

    应该基本上知道用户量,
    然后用户的访问时间是一个近似泊松分布
    根据每个时间段的用户访问量来设计队列大小
    Septembers
        6
    Septembers  
       2015-06-04 14:18:22 +08:00
    wy315700
        7
    wy315700  
       2015-06-04 14:23:07 +08:00
    @Septembers

    差不多吧,感觉排队论里的一些结论很神奇。
    ltttx
        8
    ltttx  
    OP
       2015-06-09 08:43:40 +08:00
    谢谢各位,原提问里的作法确实只是解决了并发峰值的问题(谢谢 @pubby ) 。可能问题本身的需求(让用户快速得到资源S)在现阶段是不大合理的,最简单的解决办法就是让用户等待。这样能规避很多问题,同时能解决潜在的资源浪费问题。也谢谢 @wy315700 , @Septembers , 又学到一招,排队理论。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5126 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:54 · PVG 11:54 · LAX 19:54 · JFK 22:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.