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

1.问题

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

2.啥是异步问题

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

3.个人解决

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

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个。web

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

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

相关文章
相关标签/搜索