首先附上tornado官方網(wǎng)站?tornado?(看官網(wǎng)最全)
安裝tornado:
pip install?tornado
先從hello world開始
import tornado.ioloop
import tornado.web
#定義處理類型
class MainHandler(tornado.web.RequestHandler):
? ??#添加一個處理get請求方式的方法
? ? def get(self):
? ? ? ? self.write("Hello, world")
def make_app():
? ? return tornado.web.Application([
? ? ? ? (r"/", MainHandler),
? ? ])
if __name__ == "__main__":
? ? app = make_app()? #創(chuàng)建一個應用對象
? ? app.listen(8888) # 設置端口
? ? tornado.ioloop.IOLoop.current().start()?#啟動web程序,開始監(jiān)聽端口的連接
Tornado的優(yōu)勢
1.輕量級web框架
2.異步非阻塞IO處理方式
3.出色的抗負載能力
4.優(yōu)異的處理性能,不依賴多進程/多線程,一定程度上解決C10K問題
5.WSGI全棧替代產(chǎn)品,推薦同時使用其web框架和HTTP服務器
Tornado 代碼解析
tornado.web:tornado的基礎web框架
????RequestHandler:封裝對請求處理的所有信息和處理方法
????get/post/..:封裝對應的請求方式
????write():封裝響應信息,寫響應信息的一個方法
tornado.ioloop:核心io循環(huán)模塊,封裝linux的epoll和BSD的kqueue, tornado高性能處理的核心。
????current()返回當前線程的IOLoop實例對象
????start()啟動IOLoop實力對象的IO循環(huán),開啟監(jiān)聽
程序調試之debug配置
????#自動重啟+取消緩存模板+取消緩存靜態(tài)文件+提供追蹤信息tornado.web.Application([(..)], debug=True)注:開發(fā)之初可以設置debug=True方便調試,開發(fā)完畢改為False.
get方式傳遞參數(shù)
????get_query_arguments(name,default=_ARG_DEFAULT,strip=True)
????get_query_argument(name ,strip=True)
post方式傳遞參數(shù)
????get_body_arguments(name, default=_ARG_DEFAULT,strip=True)
????get_body_argument(name ,strip=True)
request/json
# -*- coding:utf-8 -*-
from tornado.web import Application, RequestHandler
from tornado.ioloop import IOLoop
class IndexHandler(RequestHandler):
? ? def get(self):
? ? ? ? print self.request
? ? ? ? json_str = {"username": "admin", "password": "123123"}
? ? ? ? self.write(json.dumps(json_str))
if __name__ == "__main__":
? ? app = Application([(r"/", IndexHandler)])
? ? app.listen(8000)
? ? IOLoop.current().start()
異步非阻塞
import time
import logging
import tornado.ioloop
import tornado.web
import tornado.options
from tornado import gen
from concurrent.futures import ThreadPoolExecutor
class NoBlockingHnadler(tornado.web.RequestHandler):
? ? @gen.coroutine
? ? def get(self):
? ? ? ? print(11111111111)
? ? ? ? yield gen.sleep(10)
? ? ? ? self.write('Blocking Request')
class BlockingHnadler(tornado.web.RequestHandler):
? ? def get(self):
? ? ? ? print(11111111111)
? ? ? ? time.sleep(10)
? ? ? ? self.write('Blocking Request')
def make_app():
? ? return tornado.web.Application([
? ? ? ? (r"/block", BlockingHnadler),
? ? ? ? (r"/noblock", NoBlockingHnadler),
? ? ], autoreload=True)
if __name__ == "__main__":
? ? app = make_app()
? ? app.listen(8888)
? ? tornado.ioloop.IOLoop.current().start()
這里要強調的是:這里的異步非阻塞是針對另一請求來說的,本次的請求該是阻塞的仍然是阻塞的。
多進程運行
coroutine 是給Non-blocking 函數(shù)提供異步協(xié)程的方式運行, ThreadPoolExecutor 則可以給blocking 的函數(shù)提供異步的方式運行,但是由于是多線程的,Python 使用多線程對性能來說是需要謹慎的,大量的計算量的情況可能會造成性能的下降。
import tornado.web
from tornado import gen
from tornado.httpserver import HTTPServer
class IndexHandler(tornado.web.RequestHandler):
? ? def get(self):
? ? ? ? self.write('index')
@gen.coroutine
def doing():
? ? yield gen.sleep(10)
? ? raise gen.Return('Non-Blocking')
class NonBlockingHandler(tornado.web.RequestHandler):
? ? @gen.coroutine
? ? def get(self):
? ? ? ? result = yield doing()
? ? ? ? self.write(result)
def make_app():
? ? return tornado.web.Application([
? ? ? ? (r"/index", IndexHandler),
? ? ? ? (r"/nonblocking", NonBlockingHandler),
? ? ])
def main():
? ? app = make_app()
? ? server = HTTPServer(app)
? ? server.bind(8888)
? ? server.start(2)? # 設置啟動多少個進程
? ? tornado.ioloop.IOLoop.current().start()
if __name__ == "__main__":
? ? main()
coroutine 是給Non-blocking 函數(shù)提供異步協(xié)程的方式運行, ThreadPoolExecutor 則可以給blocking 的函數(shù)提供異步的方式運行,但是由于是多線程的,Python 使用多線程對性能來說是需要謹慎的,大量的計算量的情況可能會造成性能的下降。