Tornado源碼閱讀總覽

最近花了2周時間斷斷續續地閱讀了 Tornado 的源碼,寫了“Tornado源碼解析”這個系列專題。由於寫得比較散,這裏簡單做一個索引與導讀。

爲什麼要選擇 Tornado 這個框架?先給大家講一個小故事:

“[web.py inspired the] web framework we use at FriendFeed [and] the webapp framework that ships with App Engine…”

— Brett Taylor, co-founder of FriendFeed and original tech lead on Google App Engine

FriendFeed 創始人用了 web.py 作爲他們的框架,然後愛上了web.py 。後來他發現web.py的一些不足,然後就創造了一個很像 web.py 的框架 Tornado,性能會強上一些。

更多關於 Tornado 的細節可以參看專題裏面具體小節的內容,下面我們開始導讀。

1. 爲什麼要閱讀Tornado的源碼?

From: 爲什麼要閱讀Tornado的源碼?

Tornado 由前 google 員工開發,代碼非常精練,實現也很輕巧,加上清晰的註釋和豐富的 demo,我們可以很容易的閱讀分析 tornado. 通過閱讀 Tornado 的源碼,你將學到:

  • 理解 Tornado 的內部實現,使用 tornado 進行 web 開發將更加得心應手。
  • 如何實現一個高性能,非阻塞的 http 服務器。
  • 如何實現一個 web 框架。
  • 各種網絡編程的知識,比如 epoll
  • python 編程的絕佳實踐

2. 一覽衆山小

我們先了解 Tornado 的框架組成,才知道哪些部分是核心內容,應該重點看,哪些可以遲些再看。

1. Core web framework

  • tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application兩個重要的類
  • tornado.httpserver — 一個無阻塞HTTP服務器的實現
  • tornado.template — 模版系統
  • tornado.escape — HTML,JSON,URLs等的編碼解碼和一些字符串操作
  • tornado.locale — 國際化支持

2. Asynchronous networking 底層模塊

  • tornado.ioloop — 核心的I/O循環
  • tornado.iostream — 對非阻塞式的 socket 的簡單封裝,以方便常用讀寫操作
  • tornado.httpclient — 一個無阻塞的HTTP服務器實現
  • tornado.netutil — 一些網絡應用的實現,主要實現TCPServer類

3. Integration with other services

  • tornado.auth — 使用OpenId和OAuth進行第三方登錄
  • tornado.database — 簡單的MySQL服務端封裝
  • tornado.platform.twisted — 在Tornado上運行爲Twisted實現的代碼
  • tornado.websocket — 實現和瀏覽器的雙向通信
  • tornado.wsgi — 與其他python網絡框架/服務器的相互操作

4. Utilities

  • tornado.autoreload — 生產環境中自動檢查代碼更新
  • tornado.gen — 一個基於生成器的接口,使用該模塊保證代碼異步運行
  • tornado.httputil — 分析HTTP請求內容
  • tornado.options — 解析終端參數
  • tornado.process — 多進程實現的封裝
  • tornado.stack_context — 用於異步環境中對回調函數的上下文保存、異常處理
  • tornado.testing — 單元測試

要讀哪些內容?

你可以參看這篇文章來了解需要讀哪些文件:Tornado源碼必須要讀的幾個核心文件

Core web framework 部分,tornado.web 包含web框架的大部分主要功能,這個需要重點看,它包含RequestHandler和Application兩個重要的類。Application 是個單例,總攬全局路由,創建服務器負責監聽,並把服務器傳回來的請求進行轉發(__call__)。RequestHandler 是個功能很豐富的類,基本上 web 開發需要的它都具備了,比如redirect,flush,close,header,cookie,render(模板),xsrf,etag等等。關於這個模塊的解析,可以參看以下三篇文章:

  • Tornado RequestHandler和Application類
  • Application對象的接口與起到的作用
  • RequestHandler的分析

接下來是 tornado.httpserver,一個無阻塞HTTP服務器的實現。從 web 跟蹤到 httpserver.py 和 tcpserver.py。這兩個文件主要是實現 http 協議,解析 header 和 body, 生成request,回調給 appliaction,一個經典意義上的 http 服務器(written in python)。衆所周知,這是個很考究性能的一塊(IO),所以它和其它很多塊都連接到了一起,比如 IOLoop,IOStream,HTTPConnection 等等。這裏 HTTPConnection 是實現了 http 協議的部分,它關注 Connection 嘛,這是 http 纔有的。至於監聽端口,IO事件,讀寫緩衝區,建立連接之類都是在它的下層–tcp裏需要考慮的,所以,tcpserver 纔是和它們打交道的地方。關鍵部分是 HTTP 層與 TCP 層的工作原理:

  • HTTP層:HTTPRequest,HTTPServer與HTTPConnection
  • Tornado在TCP層裏的工作機制

剩下的 tornado.template,tornado.escape 之類的可以先不閱讀,會使用就行。

接下來是 Asynchronous networking 底層模塊,特別是底層的網絡模塊。

tornado.ioloop 是核心的I/O循環,需要重點看。如果你用過 select/poll/epoll/libevent 的話,對它的處理模型應該相當熟悉。簡言之,就是一個大大的循環,循環裏等待事件,然後處理事件。這是開發高性能服務器的常見模型,tornado 的異步能力就是在這個類裏得到保證的:

  • Tornado高性能的祕密:ioloop對象分析
  • Tornado IOLoop instance()方法的講解
  • Tornado IOLoop start()裏的核心調度
  • Tornado IOLoop與Configurable類

然後是tornado.iostream,對非阻塞式的 socket 的簡單封裝,以方便常用讀寫操作。這個也是重要模塊。IOStream。顧名思義,就是負責IO的。說到IO,就得提緩衝區和IO事件。緩衝區的處理都在它自個兒類裏,IO事件的異步處理就要靠 IOLoop 了:

  • 對socket封裝的IOStream機制概覽
  • IOStream實現讀寫的一些細節

如果有興趣,可以閱讀更多源碼,比如epoll.py。其實這個文件也沒幹啥,就是聲明瞭一下服務器使用 epoll。選擇 select/poll/epoll/kqueue 其中的一種作爲事件分發模型,是在 tornado 裏自動根據操作系統的類型而做的選擇,所以這幾種接口是一樣的(當然效率不一樣):

  1. 預備知識:我讀過的對epoll最好的講解
  2. epoll與select/poll性能,CPU/內存開銷對比

讀完這些部分,就可以算是認爲讀完 Tornado 的核心源碼了,當然還有許多許多的其它功能可以讀,但是主框架已經讀完,其它也就是枝葉部分了。這個專題也會慢慢完善下去,這裏僅僅作個階段性導讀。

<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
閱讀(1528) | 評論(0) | 轉發(0) |
給主人留下些什麼吧!~~
評論熱議
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章