以Django爲表明的python web應用部署時採用wsgi協議與服務器對接(被服務器託管),而這類服務器一般都是基於多線程的,也就是說每個網絡請求服務器都會有一個對應的線程來用web應用(如Django)進行處理。python
1. 用戶量大,高併發nginx
如秒殺搶購、雙十一某寶購物、春節搶火車票web
2. 大量的HTTP持久鏈接數據庫
使用同一個TCP鏈接來發送和接收多個HTTP請求/應答,而不是爲每個新的請求/應答打開新的鏈接的方法。編程
對於HTTP 1.0,能夠在請求的包頭(Header)中添加Connection: Keep-Alive。瀏覽器
對於HTTP 1.1,全部的鏈接默認都是持久鏈接。服務器
對於這兩種場景,一般基於多線程的服務器很難應對。網絡
對於前文提出的這種高併發問題,咱們一般用C10K這一律念來描述。C10K—— Concurrently handling ten thousand connections,即併發10000個鏈接。對於單臺服務器而言,根本沒法承擔,而採用多臺服務器分佈式又意味着高昂的成本。如何解決C10K問題?session
Tornado在設計之初就考慮到了性能因素,旨在解決C10K問題,這樣的設計使得其成爲一個擁有很是高性能的解決方案(服務器與框架的集合體)多線程
Tornado全稱Tornado Web Server,是一個用Python語言寫成的Web服務器兼Web應用框架,由FriendFeed公司在本身的網站FriendFeed中使用,被Facebook收購之後框架在2009年9月以開源軟件形式開放給大衆。
特色:
性能: Tornado有着優異的性能。它試圖解決C10k問題,即處理大於或等於一萬的併發,下表是和一些其餘Web框架與服務器的對比:
Tornado框架和服務器一塊兒組成一個WSGI的全棧替代品。單獨在WSGI容器中使用tornado網絡框架或者tornaod http服務器,有必定的侷限性,爲了最大化的利用tornado的性能,推薦同時使用tornaod的網絡框架和HTTP服務器
Django是走大而全的方向,注重的是高效開發,它最出名的是其全自動化的管理後臺:只須要使用起ORM,作簡單的對象定義,它就能自動生成數據庫結構、以及全功能的管理後臺。
Django提供的方便,也意味着Django內置的ORM跟框架內的其餘模塊耦合程度高,應用程序必須使用Django內置的ORM,不然就不能享受到框架內提供的種種基於其ORM的便利。
Tornado走的是少而精的方向,注重的是性能優越,它最出名的是異步非阻塞的設計方式。
$ pip install tornado
$ tar xvzf tornado-4.3.tar.gz $ cd tornado-4.3 $ python setup.py build $ sudo python setup.py install
Tornado should run on any Unix-like platform, although for the best performance and scalability only Linux (with epoll) and BSD (with kqueue) are recommended for production deployment (even though Mac OS X is derived from BSD and supports kqueue, its networking performance is generally poor so it is recommended only for development use). Tornado will also run on Windows, although this configuration is not officially supported and is recommended only for development use.
Tornado應該運行在類Unix平臺,在線上部署時爲了最佳的性能和擴展性,僅推薦Linux和BSD(由於充分利用Linux的epoll工具和BSD的kqueue工具,是Tornado不依靠多進程/多線程而達到高性能的緣由)。
對於Mac OS X,雖然也是衍生自BSD而且支持kqueue,可是其網絡性能一般不太給力,所以僅推薦用於開發。
對於Windows,Tornado官方沒有提供配置支持,可是也能夠運行起來,不過僅推薦在開發中使用。
新建文件hello.py,代碼以下:
# coding:utf-8 import tornado.web import tornado.ioloop class IndexHandler(tornado.web.RequestHandler): """主路由處理類""" def get(self): """對應http的get請求方式""" self.write("Hello Igeek!") if __name__ == "__main__": #建立tornado.web.Application對象並指定IndexHandler來處理來自'/'的請求 app = tornado.web.Application([ (r"/", IndexHandler), ]) #綁定到8000端口 app.listen(8000) tornado.ioloop.IOLoop.current().start()
執行以下命令,開啓tornado:
$ python hello.py
打開瀏覽器,輸入網址127.0.0.1:8000(或localhost:8000),查看效果:
tornado的基礎web框架模塊
封裝了對應一個請求的全部信息和方法,write(響應信息)就是寫響應信息的一個方法;對應每一種http請求方式(get、post等),把對應的處理邏輯寫進同名的成員方法中(如對應get請求方式,就將對應的處理邏輯寫在get()方法中),當沒有對應請求方式的成員方法時,會返回「405: Method Not Allowed」錯誤。
咱們將代碼中定義的get()方法更改成post()後,再用瀏覽器從新訪問(瀏覽器地址欄中輸入網址訪問的方式爲get請求方式),演示以下:
# coding:utf-8 import tornado.web import tornado.ioloop class IndexHandler(tornado.web.RequestHandler): """主路由處理類""" def post(self): # 咱們修改了這裏 """對應http的post請求方式""" self.write("Hello Igeek!") if __name__ == "__main__": app = tornado.web.Application([ (r"/", IndexHandler), ]) app.listen(8000) tornado.ioloop.IOLoop.current().start()
Tornado Web框架的核心應用類,是與服務器對接的接口,裏面保存了路由信息表,其初始化接收的第一個參數就是一個路由信息映射元組的列表;其listen(端口)方法用來建立一個http服務器實例,並綁定到給定端口(注意:此時服務器並未開啓監聽)
tornado的核心io循環模塊,封裝了Linux的epoll和BSD的kqueue,tornado高性能的基石。 以Linux的epoll爲例,其原理以下圖:
返回當前線程的IOLoop實例。
啓動IOLoop實例的I/O循環,同時服務器監聽被打開。
1. 建立web應用實例對象,第一個初始化參數爲路由映射列表。
2. 定義實現路由映射列表中的handler類。
3. 建立服務器實例,綁定服務器端口。
4. 啓動當前線程的IOLoop。