Tornado框架知識系列之二

weixin_34129145發表於2017-08-01

1,httpserver

修改上篇文章簡單tornado案例的程式碼如下:

import tornado.web
import tornado.ioloop
import tornado.httpserver # 新引入httpserver模組

class IndexHandler(tornado.web.RequestHandler):
    """主路由處理類"""
    def get(self):
        """對應http的get請求方式"""
        self.write("Hello Itcast!")

if __name__ == "__main__":
    app = tornado.web.Application([
        (r"/", IndexHandler),
    ])
    # ------------------------------
    # 我們修改這個部分
    # app.listen(8000)
    http_server = tornado.httpserver.HTTPServer(app) 
    http_server.listen(8000)
    # ------------------------------
    tornado.ioloop.IOLoop.current().start()

在這一修改版本中,我們引入了tornado.httpserver模組,顧名思義,它就是tornado的HTTP伺服器實現。

我們建立了一個HTTP伺服器例項http_server,因為伺服器要服務於我們剛剛建立的web應用,將接收到的客戶端請求通過web應用中的路由對映表引導到對應的handler中,所以在構建http_server物件的時候需要傳出web應用物件app。http_server.listen(8000)將伺服器繫結到8000埠。

實際上一版程式碼中app.listen(8000)正是對這一過程的簡寫。

關於app.listen()

app.listen()這個方法只能在單程式模式中使用。

對於app.listen()與手動建立HTTPServer例項

http_server = tornado.httpserver.HTTPServer(app) 
http_server.listen(8000)

這兩種方式,建議大家先使用後者即建立HTTPServer例項的方式,因為其對於理解tornado web應用工作流程的完整性有幫助,便於大家記憶tornado開發的模組組成和程式結構;在熟練使用後,可以改為簡寫。

2,單程式與多程式

修改上面httpserver版本程式碼如下:

import tornado.web
import tornado.ioloop
import tornado.httpserver 

class IndexHandler(tornado.web.RequestHandler):
    """主路由處理類"""
    def get(self):
        """對應http的get請求方式"""
        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)方法是將伺服器繫結到指定埠。

http_server.start(num_processes=1)方法指定開啟幾個程式,引數num_processes預設值為1,即預設僅開啟一個程式;

如果num_processes為None或者<=0,則自動根據機器硬體的cpu核芯數建立同等數目的子程式;如果num_processes>0,則建立num_processes個子程式。

我們在前面寫的http_server.listen(8000)實際上就等同於:

http_server.bind(8000)
http_server.start(1)

關於多程式

雖然tornado給我們提供了一次開啟多個程式的方法,但是由於:

  • 每個子程式都會從父程式中複製一份IOLoop例項,如果在建立子程式前我們的程式碼動了IOLoop例項,那麼會影響到每一個子程式,勢必會干擾到子程式IOLoop的工作;

  • 所有程式是由一個命令一次開啟的,也就無法做到在不停服務的情況下更新程式碼;

  • 所有程式共享同一個埠,想要分別單獨監控每一個程式就很困難。

不建議使用這種多程式的方式,而是建議手動開啟多個程式,並且繫結不同的埠。

相關文章