用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

相關文章
相關標籤/搜索