1,httpserver
修改上篇文章簡(jiǎn)單tornado案例的代碼如下:
import tornado.web
import tornado.ioloop
import tornado.httpserver # 新引入httpserver模塊
class IndexHandler(tornado.web.RequestHandler):
"""主路由處理類"""
def get(self):
"""對(duì)應(yīng)http的get請(qǐng)求方式"""
self.write("Hello Itcast!")
if __name__ == "__main__":
app = tornado.web.Application([
(r"/", IndexHandler),
])
# ------------------------------
# 我們修改這個(gè)部分
# app.listen(8000)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(8000)
# ------------------------------
tornado.ioloop.IOLoop.current().start()
在這一修改版本中,我們引入了tornado.httpserver模塊,顧名思義,它就是tornado的HTTP服務(wù)器實(shí)現(xiàn)。
我們創(chuàng)建了一個(gè)HTTP服務(wù)器實(shí)例http_server,因?yàn)榉?wù)器要服務(wù)于我們剛剛建立的web應(yīng)用,將接收到的客戶端請(qǐng)求通過(guò)web應(yīng)用中的路由映射表引導(dǎo)到對(duì)應(yīng)的handler中,所以在構(gòu)建http_server對(duì)象的時(shí)候需要傳出web應(yīng)用對(duì)象app。http_server.listen(8000)將服務(wù)器綁定到8000端口。
實(shí)際上一版代碼中app.listen(8000)正是對(duì)這一過(guò)程的簡(jiǎn)寫。
關(guān)于app.listen()
app.listen()這個(gè)方法只能在單進(jìn)程模式中使用。
對(duì)于app.listen()與手動(dòng)創(chuàng)建HTTPServer實(shí)例
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(8000)
這兩種方式,建議大家先使用后者即創(chuàng)建HTTPServer實(shí)例的方式,因?yàn)槠鋵?duì)于理解tornado web應(yīng)用工作流程的完整性有幫助,便于大家記憶tornado開(kāi)發(fā)的模塊組成和程序結(jié)構(gòu);在熟練使用后,可以改為簡(jiǎn)寫。
2,單進(jìn)程與多進(jìn)程
修改上面httpserver版本代碼如下:
import tornado.web
import tornado.ioloop
import tornado.httpserver
class IndexHandler(tornado.web.RequestHandler):
"""主路由處理類"""
def get(self):
"""對(duì)應(yīng)http的get請(qǐng)求方式"""
self.write("Hello Itcast!")
if __name__ == "__main__":
app = tornado.web.Application([
(r"/", IndexHandler),
])
http_server = tornado.httpserver.HTTPServer(app)
# -----------修改----------------
http_server.bind(8000)
http_server.start(0)
# ------------------------------
tornado.ioloop.IOLoop.current().start()
http_server.bind(port)方法是將服務(wù)器綁定到指定端口。
http_server.start(num_processes=1)方法指定開(kāi)啟幾個(gè)進(jìn)程,參數(shù)num_processes默認(rèn)值為1,即默認(rèn)僅開(kāi)啟一個(gè)進(jìn)程;
如果num_processes為None或者<=0,則自動(dòng)根據(jù)機(jī)器硬件的cpu核芯數(shù)創(chuàng)建同等數(shù)目的子進(jìn)程;如果num_processes>0,則創(chuàng)建num_processes個(gè)子進(jìn)程。
我們?cè)谇懊鎸懙膆ttp_server.listen(8000)實(shí)際上就等同于:
http_server.bind(8000)
http_server.start(1)
關(guān)于多進(jìn)程
雖然tornado給我們提供了一次開(kāi)啟多個(gè)進(jìn)程的方法,但是由于:
每個(gè)子進(jìn)程都會(huì)從父進(jìn)程中復(fù)制一份IOLoop實(shí)例,如果在創(chuàng)建子進(jìn)程前我們的代碼動(dòng)了IOLoop實(shí)例,那么會(huì)影響到每一個(gè)子進(jìn)程,勢(shì)必會(huì)干擾到子進(jìn)程IOLoop的工作;
所有進(jìn)程是由一個(gè)命令一次開(kāi)啟的,也就無(wú)法做到在不停服務(wù)的情況下更新代碼;
所有進(jìn)程共享同一個(gè)端口,想要分別單獨(dú)監(jiān)控每一個(gè)進(jìn)程就很困難。
不建議使用這種多進(jìn)程的方式,而是建議手動(dòng)開(kāi)啟多個(gè)進(jìn)程,并且綁定不同的端口。