1 搭建說明
Tornado應(yīng)該運行在類Unix平臺,在線上部署時為了最佳的性能和擴展性,僅推薦Linux(因為充分利用Linux的epoll工具,是Tornado不依靠多進程/多線程而達到高性能的原因)
對于Windows,Tornado沒有提供配置支持,但是也可以運行起來,不過僅推薦在開發(fā)中使用
2 一個簡單的Demo
驗證Tornado是否安裝成功,http://127.0.0.1:9888/
service.py
import tornado.web
'''
tornado的基礎(chǔ)web框架模塊
'''
import tornado.ioloop
'''
tornado的核心IO循環(huán)模塊,封裝了linux的epoll,是tornado高效的基礎(chǔ)
'''
#類比試圖類
#一個業(yè)務(wù)處理類
class IndexHandler(tornado.web.RequestHandler):
#處理get請求的
def get(self,*args,**kwargs):
#對應(yīng)請求的方法
#給瀏覽器響應(yīng)信息
self.write("Hello World")
#處理post請求的
def post(self,*args,**kwargs):
pass
if __name__ == "__main__":
#實例化一個app對象, Application是tornado web框架的核心應(yīng)用類,是與服務(wù)器對應(yīng)的接口
#里面保存了路由映射表,有一個listen方法用來創(chuàng)建一個http服務(wù)器的實例,并綁定端口
app = tornado.web.Application([
(r"/",IndexHandler)
])
#綁定監(jiān)聽端口,不同的服務(wù)綁定的端口是不一樣的
#注意:此時服務(wù)器并沒有開啟監(jiān)聽
app.listen(9888)
'''
IOLoop.current():返回當前線程的IOLoop實例
IOLoop.current().start():啟動IOLoop實例的I/O循環(huán)(死循環(huán)),同時開啟監(jiān)聽
'''
tornado.ioloop.IOLoop.current().start()
客戶端與服務(wù)器的請求與響應(yīng)

3 高性能原理
客戶端連接服務(wù)器會產(chǎn)生一個socket,通過socket完成讀寫。socket交給linux-epoll去管理,tornado-IOLoop一直問linux-epoll是否連接的請求


4 搭建一個httpserver服務(wù)器
server.py
import tornado.web
import tornado.httpserver
import tornado.ioloop
class IndexHandler(tornado.web.RequestHandler):
def get(self,*args,**kwargs):
self.write("Hello World")
if __name__ == "__main__":
app = tornado.web.Application([
(r"/",IndexHandler)
])
#app.listen(9888)
#實例化一個http服務(wù)器對象
httpServer = tornado.httpserver.HTTPServer(app)
#綁定端口
httpServer.listen(9888)
tornado.ioloop.IOLoop.current().start()
6 單進程與多進程
注意:tornado默認開啟的都是單進程,那么如何開啟多進程呢?
import tornado.web
import tornado.httpserver
import tornado.ioloop
class IndexHandler(tornado.web.RequestHandler):
def get(self,*args,**kwargs):
self.write("Hello World")
if __name__ == "__main__":
app = tornado.web.Application([
(r"/",IndexHandler)
])
#app.listen(9888)
#實例化一個http服務(wù)器對象
httpServer = tornado.httpserver.HTTPServer(app)
#將服務(wù)器綁定到制定的端口
httpServer.bind(9888)
#啟動多個進程,默認開啟一個進程,只為None或者小于等于0,開啟cpu的核數(shù)量的進程
httpServer.start(5)
tornado.ioloop.IOLoop.current().start()
雖然tornado給我們提供了一次性啟動多個進程的方法,但是由于一些問題,不建議使用。
建議手動啟動多進程,綁定不同的端口
問題原因:
1、每個子進程都會從父進程中復(fù)制一份IOLoop的實例,如果在創(chuàng)建子進程前修改了IOLoop,會影響所有的子進程
2、所有的子進程都是由一個命令啟動的,無法做到不停止服務(wù)的情況下修改代碼
3、所有的進程共享一個端口,想要分別監(jiān)控很困難。
7 外部獲取啟動參數(shù)options
tornado為我們提供了一個便捷的tornado.options模塊
作用:全局的參數(shù)的定義、存儲和轉(zhuǎn)換
命令行啟動并傳遞參數(shù)
import tornado.web
import tornado.httpserver
import tornado.ioloop
import tornado.options
#用來定義options變量的方法
'''
name 選項變量名,必須保證其唯一性
default 設(shè)置變量的默認值,默認為None
type 設(shè)置選項變量的類型,從命令行或配置文件導(dǎo)入?yún)?shù)時,tornado會根據(jù)類型轉(zhuǎn)換輸入的值
help 選項變量的提示信息
'''
tornado.options.define("port",default=9888,type=int,help=None)
#tornado.options.define("list",default=[],type=str,help=None)
class IndexHandler(tornado.web.RequestHandler):
def get(self,*args,**kwargs):
self.write("Hello World")
if __name__ == "__main__":
#轉(zhuǎn)換命令行參數(shù),并保存到到options
tornado.options.parse_command_line()
app = tornado.web.Application([
(r"/",IndexHandler)
])
httpServer = tornado.httpserver.HTTPServer(app)
#使用變量的值
httpServer.bind(tornado.options.options.port)
#啟動多個進程,默認開啟一個進程,只為None或者小于等于0,開啟cpu的核數(shù)量的進程
httpServer.start(1)
tornado.ioloop.IOLoop.current().start()
python service2.py --port=8000