Quora 的 WebNode2 和 Livenode 是怎樣的?
假設提問者已經看了Quora的幻燈片(http://www.quora.com/Shreyes-Seshasai/Posts/Tech-Talk-webnode2-and-LiveNode)。因此就不討論重複的內容了。Quora放出的幻燈片寫得很詳細,照著實現一個其實不難。我在去年利用業餘時間做過一個Demo,做過內部分享。這裡說下幾點體會:
1. 看WebNode2的語法很酷,但在生成html的邏輯上和大部分編譯過的模版沒什麼不不同。反而會引起更多的字元串list的追加或extend,屬於python生成html的瓶頸之一。所以對實現是有一定挑戰的。個人一度懷疑在Quora把io瓶頸最常見的Web服務跑在增加執行效率的PyPy上是和這一點有關;
2. WebNode2提供了一個模塊化開發的框架,通過約束讓一個功能的javascript,視圖和後端行為(controller)被定義在一個組件下Component下。這不是一個全新的設計,因為桌面軟體一直是這樣做的。也不識一個難的設計,因此「模塊化」的思想人人都能夠接受。我要做的僅僅是參考幻燈片的代碼設計一個Compnent基類,設法將子類映射成tornado的UIModule,再定義一個地址為server_call做路由,就可以直接在tornado里使用了。這步的難點不是設計而是推行,因為做到這樣要求後端代碼去和前端一樣追求模塊化,並且改變現有Web服務框架培養的開發習慣。大部分國內的後端程序員對Web開發的認識還停留在Web服務框架、前端/後端分離、MVC這樣傳統的概念上,接受不了後端組件化開發,也不認為這玩意能提升生產力。
3. WebNode2設計下的組件不是平行的,而是樹形的。這是出於幾方面的需要:1). 更小粒度的組件復用。 比如關注一個問題的按鈕,其邏輯和所需數據在整站都應該是一樣的,因此應該只需要編寫一次; 2) LiveList和LiveBlock需要,因為容器內部元素的更新會引起容器checksum的變化,如果容器是元素的父節點就很直接的做到; 3) 更小的LiveNode,保證實時更新的數據傳輸開銷更小;4) 數據預載入優化,通過自頂向下遍歷,子節點在被解析前可以根據其聲明提前獲取數據。知乎現在也開始用類似的技術;
4. DepTracker, render time捕獲的數據&<-&>組件之間的依賴關係就放到了這裡,由於數據的改變會引起cache失效,因此Quora把捕捉依賴和cache的聲明放在了一起。我在做Demo時是用redis做存儲,沒有測試其壓力。Quora使用8台基於窗口id sharding的機器做DepTracker,說明生產時它的壓力是很大的;
5. LiveNode 有了WebNode2和DepTracker的基礎,LiveNode就水到渠成了:WebNode2下每個組件的視圖、js都定義在一起,那麼遇到它的數據失效,只需要重新渲染一次,js入口、html等都打包push給客戶端就行了。知乎有long pull的實現基礎,因此增加幾行代碼就可以實現LiveNode的功能;
6. LiveNode session。這步幻燈片里沒有講,但它是的確存在的:1) 如果留意下Quora的分頁機制,就會發現它不是一個「翻頁」機制,而是改變當前列表個數的請求,所處的LiveList知道列表個數變化,然後將新增的子節點傳了過來。因此不管你如何排序,列表如何新增,翻頁時都不會出現節點重複或丟失的問題。 這要求在後端為每一個LiveList維護:子節點的checksum列表,子節點個數。
最後說下關於WebNode2和LiveNode的最佳的資料還是Quora放出的幻燈片,該有的都有了,沒有的推敲一下也能猜出來。至於能不能把Demo變成生產環境里運行的系統,取決於幾個因素:1) 後端架構能力,畢竟整站的實時化很多指標都會翻倍,架構上沒準備好是不行的。尤其是一些取決於實時技術的交互實現,慢了一點體驗就會很差;2) 和現有技術的兼容性,比如3裡面提到的樹形組件,我是最近才想到如何在保留tornado的模版的情況下實現類似的技術的;3) 你的團隊更關心哪方面技術作為競爭力,國內大部分互聯網公司的核心競爭力在運營,能夠應對運營需求變化的技術才是最關鍵的技術。這樣規模的系統升級,不能作為團隊目標整體應對風險,單憑工程師的喜好是做不到的。比較靠譜的是把一兩個技術點拆出來,想想怎麼在現有的系統里應用。推薦閱讀:
TAG:Quora |