• 用python写web一定要去破解的异步请求问题.经历web.py和tornado,完破!


    1.问题

    上个学期,给学校写了一个数据服务,主要从oracle里面读取一些数据供查询使用,非常快速的用web.py搭建了起来。调试顺利,测试正常,上线!接下来就是挨骂了,我铁定知道会卡,但是没想到会那么卡。在线10几个人就已经无法访问了。我自己这里调试还是可以正常访问的,那就是负载量不够呗。上nginx,起8个进程。好了不少喂,但是还是有学生抱怨,时而正常,时而不正常。我就知道,快速完成的东西,大量用户的东西,这次web.py有些顶不住了,期间还不死心上了一些组件来优化进程访问,不一一细说,因为都没有明显好转,啥独角兽,啥uwsgi,啥fastCGI,统统效果不明显。肯定也是我水平不够。这时候不得不再拿出几年前用来解决异步请求的tornado来。

    2.啥是异步问题

    以web.py为例,一般性开发管理系统由于使用的用户比较少,几乎可以忽略这个问题,或者通过增加负载用多进程来解决这个问题,因为一个简单的小系统同时又8~10人在线使用就很不错了。web.py在单个进程服务的时候,如果一个请求消耗的时间很长,另外的请求就会被阻塞,等待第一个请求得到响应完成后才会被响应,这就是阻塞问题,解决阻塞问题的方法就是启用异步请求。本来在其他开发语言里这是个简单的问题,但是在python里,因为Python自身的设计就是单进程的,稍微麻烦了一些,仔细研究还有很多好玩的事情。

    3.我的解决

    第一步是换一个支持异步的tornado,第二步是在tornado中启用异步。tornado的异步也有不少的方法,但是从应用角度来看,我觉得最终我选择的这个方法对于原有系统结构的冲击比较小。

    3.1 创建响应请求的基类WxBaseView

    #coding=utf-8
    __author__ = 'jy@cjlu.edu.cn'
    from concurrent.futures import ThreadPoolExecutor
    from tornado.web import RequestHandler
    from web.utils import storage
    opt_users = d_users()
    class WxBaseView(RequestHandler):
        executor = ThreadPoolExecutor(100)
    
    

    3.2 所有url实现类继承这个基类

    #coding=utf-8
    from tornado.concurrent import run_on_executor
    class List(WxBaseView):
        @run_on_executor
        def get(self):
            self.set_header("Content-Type", "text/html; charset=UTF-8")
            self.set_header("Access-Control-Allow-Origin", "*")
            self.write("hello tornado!")
        @run_on_executor
        def post(self):
            self.write("hello tornado!")
    

    这里注意一个要点,就是在响应函数get和post前增加@run_on_executor这个装饰器,而这个装饰器其实调用的是我们在基类里设置的ThreadPoolExecutor,这里我们设置了这个线程池是100个。

    4.对于web.py项目迁移到tornado

    这个的修订方法对于解决用web.py快速开发的业务系统来说,代价非常的小,而且上线效果马上见效,比啥优化都有效。因为你再也不用因为一个耗时请求卡住整个进程了。100个线程池已经足以对付300个以上的在线用户了。

  • 相关阅读:
    mysql日志
    验证栈序列
    限流方案分析
    集合
    数据结构-树
    链表的中间节点
    PHP实现链表
    php扩展安装方式
    2017 Multi-University Training Contest
    用LCT解一类动态图的问题
  • 原文地址:https://www.cnblogs.com/pcode/p/9202258.html
Copyright © 2020-2023  润新知