tornado 到底是個什麼東西呢?
- 如果它是個webserver ,那麼後端如何搭配Django使用 ,又能否搭配Node.js 或 PHP?
- 如果作為web架構,nginx對於她來說意義在哪裡? 在實際使用中是否會影響Tornado本身的非同步IO設計?
- Tornado與node.js 的實現的目的 ,和設計方式上的不同之處在哪裡 ( 不談語言 )?
-----------------------------
補充:以下是看官方說明和 Google 了一番後的理解:
- 它可以作為一個裸 webserver 來使用 ,就是說它的後端可以運行 Django、web.py。
- 它是一個簡單 Python 架構,url 基於正則,有自己的模板實現,但是沒有 orm。這部分看起來類似於 web.py。
- 非阻塞非同步 IO,類似於 node.js。
- 它的前端可以放 Nginx ,感覺類似於 Nginx、Apache 之於 Tomcat。
就是說它作為 web 架構比 Django 簡單,又支援非同步 IO,且更不需要前端的 webserver ?
我已經混亂了, Tornado是 Nginx、Django、Node.js 的結合體?又或是 Nginx * 20% + Django * 40% + Node.js * 40% ?
回複內容:
我來回答一下答主補充的問題:
> 就是說它作為 web 架構比 Django 簡單,又支援非同步 IO,且更不需要前端的 webserver ?
> 我已經混亂了, Tornado是 Nginx、Django、Node.js 的結合體?又或是 Nginx * 20% + Django * 40% + Node.js * 40% ?
你需要搞清楚幾個概念:
1,web server是監聽連接埠,負責HTTP連結管理、資料收發、HTTP協議實現等底層上的處理。
2,Web架構定義的是單個HTTP請求處理的流程。
3,nginx是反向 Proxy伺服器,是一個特殊的web server應用,和web server並不是同級的概念。
Tornado既是web server又是web架構,這兩者並不矛盾。
舉例來說,你寫了一個tornado應用之後,直接把tornado連接埠跑在8000,這個時候,通過localhost:8000/foo就能訪問到你的網頁。這裡分兩步,tornado完成了底部IO事件的監聽和資料接受等工作,這是tornado完成了其作為web server的使命。然後你通過按照tornado架構定義的流程,在對應的地方寫了個get函數,實現了這個頁面的具體內容,這是tornado作為web 架構體現了作用。
那麼nginx有什麼用?
他是個反向 Proxy,反向 Proxy顧名思義,其作用就是將接收到的HTTP請求按照一定的規則轉寄給後端其他伺服器處理。
比如在你的一台機器上跑了三個tornado應用:foo1,foo2,foo3,連接埠分別為8000,8001,8003,你希望使用者可以直接通過80連接埠來訪問這些應用。這個時候你就可以用nginx來達到這個目的了。讓nginx跑在80連接埠,當他接收到請求時,如果是/foo1,就轉寄給8000連接埠處理;如果是/foo2,就轉寄給8001連接埠處理,foo3類似。
所以,tornado和nginx並沒有什麼聯絡。實際上,很多架構都實現了一些簡易web server,用於調試。tornado的web server是非同步,以可以處理大量的非活躍長串連著稱。所以其web server是他的一個特性feature,在介紹的時候就會提及自己是一個很酷的webserver了。
回到主題,題主你在你機器上裝裝nginx、用tornado寫個hello world就都清楚了。
祝折騰快樂Tornado既是一個web server,也是web framework。而它作為web server 採用的是asynchronous IO的網路模型,這是一種很高效的模型。
web framework的定義(http://wiki.python.org/moin/WebFrameworks
)
A Web framework is a collection of packages or modules which allow developers to write Web applications or services without having to handle such low-level details as protocols, sockets or process/thread management.
Tornado作為web server,提供了web framework的api,可以來直接構建自己的web程式。同時,Tornado支援WSGI ( http://www.python.org/dev/peps/pep-0333/
),也就是說它可以有能力其它的一些python的架構一起使用,比如django, bottle, flask等。不妨看下bottle在不同server下的效能評測,其中就有tornado( http://bottlepy.org/page/2009-12-19_Comparing_HelloWorld_Performance
)。額外說的是,WSGI的架構是不支援非同步,所以如果有非同步呼叫的邏輯的web程式,Tornado也是選擇之一。
沒有使用過Node.js,但官網說:
Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications.
可以把Node.js理解成基於V8的javascript運行環境或工具包,它屬於偏底層的抽象,擴充了javascript寫服務端程式的能力。所以基於它也會有不同的web framework。從這個角度來看,Node.js和Tornado其實不在一個層次上。
不過相同的是 Node.js 和 Tornado都採用的的單進程單線程非同步IO的網路模型。它們都可以寫非同步非阻塞的程式,不過我覺得因為javascript的語言特性,Node.js對非同步回調非阻塞的風格堅持比Tornado更徹底一點。不過通常多進程時,一個進程的短時間阻塞也是可以接受的。
使用Nginx是因為一些單進程服務無法利用多核CPU,同時也會有單機的限制,所以通常會在多個伺服器啟動多個進程執行個體,使用Nginx在前端作為反向 Proxy伺服器來分發web請求,同時負載平衡。Nginx是C寫的,有更好的並發性,可配置性,對靜態檔案也有更好的支援。當然這是Nginx的常用情景,其實也可以直接使用Nginx來構建web應用,可以參考OpenResty項目( http://openresty.org/
)。
其實網路模型、web server、web framework是三個不同層次,它們之間並不衝突,是選擇的關係。理解前,不妨先理清概念:)建議樓主閱讀一下這篇論文 C10K problem,雖然有點老了http://www.kegel.com/c10k.html
其實,你也可以說nginx是一個framework,不過是針對C的。
裸WebServer表示他支援HTTP協議,既然支援HTTP協議,你前面放啥反向都無所謂,nginx apache squid varnish。或者也可以用wsgi模組,只是採用了特殊的通訊協議。
為什麼要在tornado前面放nginx,原因在於,Python雖然有多線程,但是Python的解譯器有GIL http://en.wikipedia.org/wiki/Global_Interpreter_Lock
這點非常影響了Python和Tornado利用多核的能力,所以只能通過多進程來利用多核。既然多進程,一般就需要在前端放置nginx haproxy做為負載平衡的反向 Proxy,或是使用這些應用伺服器的wsgi模組來管理進程的生命週期等等。另外對於靜態檔案的服務,也是nginx之類的更具有優勢。(他們直接把請求轉寄到tornado的進程中,你根本不用管請求怎麼來的,專心寫你的程式。)
其他很多指令碼語言的架構都有類似問題,比如ruby,而Nodejs更加是連線程都沒有了。
Nodejs的核心在於,他使用了JavaScript天生擅長的事件/回調機制來實現非同步。
Python對於匿名函數和閉包支援不夠好,所以Tornado通過了類來和回調方法來實現非同步,這裡沒有事件的概念。(沒深入研究過Tornado,大致是這麼瞭解的)
另外Tornado封裝了很多常用的諸如靜態檔案處理、Router、模板等等,而Nodejs基本上是一個純粹的協議架構,這些功能都需要自己去寫。Nodejs+Express差不多就可以等於Tornado的功能了。
而如果是要做一個中介軟體或中介層,做一些進階點的協議處理,可能nodejs更加能勝任。
在tornado裡面去調用用php或者nodejs所開發的服務,這是沒問題的,主要要看架構上如何設計。tornado是一個非同步http架構,fb最早是拿tornado做feed流上提醒用的,tornado內建了一個asynchttpclient,這個特別適合基於rest web service做網站,使用@gen.coroutine 和yield基本上就可以把非同步代碼變成同步代碼了。tornado代碼量不大,特別適合有興趣的人,自己研究用。
不過tornado問題也不小,做網站的話,最主要的是,tornado是單線程的(雖然可以通過fork來搞多進程),而web後端多用rdbms,特別是mysql主要的driver都是同步阻塞的,也就是說訪問資料庫會阻塞tornado,所以對做網頁的限制比較大。都是長篇啊。。其實把 epoll 瞭解瞭解,然後 tornado 裡 ioloop 那裡看明白就好了首先我覺得web server和web架構這兩個功能本身並不衝突,因為http server的功能就是串連接入,商務邏輯處理,返回頁面。因此tornado, node.js, django, nginx都可以實現這樣的功能,只是使用情境的不同,導致他們或歸為web server或歸為web架構。
首先說說nginx,主要應用情境是反向 Proxy,負責前端串連接入,繼而向後請求後端服務。而nginx本身提供一些負載平衡的功能可以加強web服務的負載能力。但同時nginx也可以作為web架構,只是其c語言開發成本較大,所以用的人比較少而已。不過@agentzh 開發的openresty可以用Lua去寫nginx的擴充,這也增強了nginx作為web架構處理商務邏輯的能力。
再說說node.js,node的定位並不完全是web server和web架構,它更多的是實現了一套javascript在伺服器上的運行時,但由於其本身非同步網路的特點,所以作為一個網路服務架構非常合適,可以看到node實現的httpserver實際上非常簡單,這也誕生了express這種目標就是web架構的中介軟體。
django我只有個大概的瞭解,感覺它的定位是一個web服務的全套解決方案(如rails),提供了orm,抽象後台管理等web服務常用的功能,因此它的目標定位是web架構,但由於是同步的(很多年沒關注了,現在改沒改不知道),所以比較影響接入能力,所以前面一般要掛個非同步反向 Proxy。
而tornado的定位也更像是輕量級web架構,提供非同步能力,但對於商務邏輯處理的支援比django要簡單,因此和node一樣比較適合做服務中介軟體。
從商務邏輯處理的角度來說,雖然非同步處理能力已經有了比較大的提升,但node和tornado都是單進程的,因此一般要啟多個執行個體,前端再用nginx做接入和負載平衡。
所以從架構選型的角度,nginx做前端接入,後面服務邏輯的選擇就看需求了,如果只是最基本的web服務,如cms之類的,django比較方便,可以省下很多開發量。而node和tornado做複雜web系統的中介軟體比較合適……大家的回答都有點片面,更多的關注web架構成,其實tornado遠遠不止這些,且聽我慢慢到來
1.高效能的網路程式庫,這可以和gevent,twisted,libevent等做對。提供了非同步io支援,逾時事件處理,在此基礎上提供了tcpserver,httpclient,尤其是curlhttpclient在現有http用戶端中肯定排第一。可以用來做爬蟲,遊戲伺服器,據我所知業界已有使用tornado作為遊戲伺服器
2.web架構,這可以和django,flask對。提供了路由,模板等web架構必備組件。與其他區別是tornado是非同步,天然適合長輪訓,這也是friendfeed發明tornado的原因,
當前flask也可以支援,但必須借住gevent等
3.較為完備的http伺服器,這點可以和nginx,apache對比,但只支援http1.0,所以使用nginx做前段不僅是為了更好利用多核,也是讓其支援http1.1
4.完備的wsgi伺服器,這可以和gunicore,gevent wsgi server做對比,也就是說可以讓flask運行在tornado之上,讓tornado加速flask
5.提供了完備的websocket支援,這讓html5的遊戲等提供了便利。像知乎長輪訓就是使用了websocket,但websocket手機支援的不是很好,前段時間不得不使用定時ajax發送大量請求,期待手機瀏覽器趕快奮起直追
tornado,你值得擁有tornado內建了一個web伺服器,效能不錯,但由於實現簡化了很多功能,建議跑在nginx後面
tornado本身又是一個web架構,但是沒有預先實現很多功能,只保留比較必要的組件,這個和Django就有點相反的思路。
雖然思路相反,但Django其實也是圍繞著一個設計精良的core來實現的,如果單獨把這個core抽取出來其實和Tornado的規模和功能都差不多。它的功能豐富(甚至是複雜)只不過是一種“一站式架構”的理念的體現而已。
簡單來說,就是它們一個是簡約架構,一個是把可能需要的組件都預設配給你的架構。喜歡用哪個看個人愛好。前者的麻煩是遇到某些問題要自己重新實現,後者的麻煩是如果它預置給你的不能滿足要求也要自己重新實現,歸根到底就是找到一個平衡點,盡量方便開發就可以了。
非同步方面個人不推薦node.js,js用在服務端還是很少的,很多組件都不齊全,要成熟還得比較久,用Python可以有很多現有的組件使用。
最後,如果關心效能,請嘗試pypy,在Linux下網路IO方面毫不遜色node.js,不過大部分情況下效能問題都不在Python寫的東西中,而在資料庫。1. 輕架構,從web.py開始,flask,bottle這些都是輕架構,tornado則是輕架構的代表
2. 高效能非同步架構,直接基於ioloop寫東西,你就覺得tornado不僅僅是web架構了
3. 佇列服務器,我們實現一個兩級tornado伺服器模型,前面的負責web分配和並發,後面負責單線程高cpu計算,輕鬆解決了單線程高運算量的block問題
WSGI功能可以忽略不計了
理解了tornado的特性之後,我們發現唯一需要和tornado配合的就是nginx,既可以做負載平衡,又可以擋住靜態檔案請求。除此以外你還需要個mysql,試試torndb。
使用tornado可以大大的減少web系統中使用的組件數量,用最少的代碼量和極其精簡的架構實現你的系統。Tornado 是一個web伺服器。django是一個快速web程式編寫架構。node.js是一種編程環境。你直接用Tornado 寫網站也可以,但是它只有最基本的功能,你寫個網站工作量不小,而DJANGO則可以協助你快速的編寫網站程式,而後部署在Tornado 或者其他web伺服器上。node.js則是類似PYTHON的一種編程環境,它可以實現很多東西。我認為你要做個網站,真正現實的就是PHP、rails、django,真正重要的快速實現你的想法,效能之類的東西開始並不重要。