Author:放翁(文初)
Date:2010/4/2
過年到現在還沒有更新過blog,就和年前說的一樣,到了淘寶就要真的踏實做實事了(起碼Q3前)。和以前在阿軟不同的是現在更加關注產品的設計和實現,對于新技術的嘗試缺少了一些空間和時間。可以拿程序員對新技術的追求做個類比,就好比結婚前的浪漫,而到了你真的結婚有了家庭和小孩,那需要的是更多的責任感和務實的工作。當然如果生活成為一種生存,那么就失去了意義,如何在責任和浪漫之間找到平衡點,是一個技術人員成長的挑戰。我們不可能永遠是一個長不大的小孩,也不會是老氣橫秋的中年男人。有點廢話了,言歸正傳,談一下這年后短短的一個多月的工作心得,一點分享,一點記錄。
系統透明化
去年就加入了淘寶的虛擬小組(穩定性小組),同時在開放平臺團隊內最大的一個職責也是穩定性。對于客戶來說并不關心你的技術實現是如何fancy,對他來說能夠快速、穩定、方便的滿足他的需求就是一個好網站,一個好系統,一套好服務。因此穩定,高效成為了淘寶主站和開放平臺的根本。前兩天看了黃裳在infoq的一些關于淘寶技術展望的文章,就兩個字“實在”,沒有啥潮流的詞匯,沒有很炫的技術推薦,有的就是如何用最有效的手段滿足用戶需求。
記得在最近一次穩定小組會議上大家談到了這些年發展帶來的問題,其實我們在解決問題的同時也在不斷地引入問題,同時在規模化的驅使下,不斷地采用松耦合及去中心化的設計,但是帶來的問題就是系統復雜度的不斷增加,同時系統間的交互和依賴也變得越來越復雜和混沌。我在Q1的工作計劃中,大部分的工作為了一個目標:系統透明化。
系統透明化能夠為海量請求的系統帶來什么?
1. 實實在在的性能優化。
2. 簡單有效的問題排查和定位。
3. 系統風險預警。
4. 有效地系統健康監控和業務健康監控。
過去我們總在線下做各種壓力測試,同時對于一些優化策略也都是通過線下來驗證,但是實際的業務場景往往會和具體的數據相關,而線下無法做到的就是數據模擬。在開放平臺系統基礎框架重構以后,首先是采用了管道鏈的插拔模式,直接通過對當前運行數據的在線分析就可以看出系統消耗的環節,同時加上控制臺對集群單臺機器的配置推送,這樣比對兩臺不同處理策略的服務器就能夠很明顯看出性能優化的效果以及后續的改進點。舉個例子,在我們業務方需求中要求對某一部分業務數據去掉本地緩存,全部啟用純粹的集中式緩存,我們通過批次的關閉本地緩存,比對了自身系統和外部依賴系統的壓力增長情況,當3/4的機群機器采用純集中式緩存的時候,兩方服務器都出現了load較高的問題,因此考慮采用更細粒度的業務數據來決定是否啟用本地緩存,滿足了用戶請求,同時也大大降低了雙方的壓力情況,同時由于業務數據配置可運行期推送,因此隨著壓力的增大可以在線調整策略。
在新架構上線后,發現運行一段時間會有“內存泄露”的問題,64位機器最后3個G的內存都被吃光。當時就是擔心新架構可能產生一些問題,因此允許系統通過控制臺切換新老引擎。線上一臺新引擎的服務器跑了一段時候就把內存dump出來,然后拖到線下分析,發現有大量的tomcat的Session被保存在Manager中沒有被釋放(1.7G),然后通過線下卸載管道做測試,最終發現是由于其中一個管道需要在運行期獲取到spring的容器,去掉用了request.getsession().getContext方法,結果容器創建了有效期為30分鐘的session,對于平臺這么大的訪問量,其實這種非內存泄露的問題,也足以使得高壓力下OOM。
透明化另一方面就是需要對依賴系統及自身的健康狀況有所了解。當前TOP在這方面主要做的工作被定義成為免疫系統,其主要的職責

流程管道化
這些年一直都在談面向服務,模塊化,這些概念。但是就其目標來說,就是希望能夠讓設計者更多的考慮流程之間的松耦合,無依賴。因為一旦服務之間沒有過多的依賴,服務本身沒有中間狀態,那么任務就可以并行處理,一旦并行處理,那么對于流程的關鍵路徑優化就有很大的幫助。
下面是重構前和重構后的兩個流程對比:
老框架流程:

新框架流程:

具體的框架類圖如下:

看了以后,可能很多同學會說,其實就那么簡單一個設計么,但其實系統的設計目標就是用簡單的設計來滿足復雜的需求。其實對于開放平臺來說,再復雜的業務都是可以抽象成管道,同時大部分情況下都是無狀態的服務管道,基于業務的不同需求,管道的執行會有所不同。
這里設計的幾個原則:
1. 管道之間無關聯性。管道與管道之間完全沒有任何關聯,因為在管道看來就只有輸入和輸出的數據流,其他管道對于它來說是透明的。獨立性降低業務耦合度,支持運行期變更。
2. 管道之間通過上下文的方式交互數據,減少數據輸入帶來的適配依賴。
3. 業務處理權及流程中斷權交給管道,管道可以通過實現ignoreit來判斷是否要處理此次請求,也可以在IPipeResult中設置isBreakPipeChain來主動中斷流程。(對于資源回收最好不要交給一個管道執行,因為隨時可能因為流程中斷而沒有被執行到)
4. 管道設計盡量為無狀態,線程安全,便于擴展,防止產生資源競爭帶來的處理瓶頸。
5. 監控管道執行狀況,必要時自動降級卸載管道,保護系統穩定性。
早先考慮是否能夠啟動線程池來執行管道鏈,這么做的目標是能夠控制超時執行的管道鏈,避免系統的不穩定性。但最大的問題就是線程切換代價以及線程池的容量問題,因此作罷,改為事后記錄降級處理。
安全還是安全
開放平臺成立之初,就要面對著安全的問題,主站有很多的約束和限制,但是開放平臺成為淘寶對外的窗口,為了業務需要,作了必要的妥協,但是安全方面也是一直在抓的事情。最近就處理淘寶訪客應用的問題,有些軟件開發者就利用302轉跳的方式,在商品或者店鋪的頁面上留痕跡,來獲取訪客信息,可謂用盡心思,封一個漏洞找一個漏洞。對于這種轉跳來獲取訪客信息,簡單的處理就這些,禁止get請求(由于都是頁面圖片的get請求轉跳,因此無法簡單的變成post請求),然后如果是post需要加上動態會話碼的校驗,最后在加上對于請求的refer檢查,來屏蔽這類的問題。不過對于釣魚網站,真的沒有啥太好的處理方式,個人感覺最靠譜的就是寫瀏覽器的插件。
標簽化開放
開放平臺現在都是數據服務開放,很多場景下會有標簽化開放的需求。還是看圖說話吧:

剩下的就是基于Map-Reduce的可配置分析引擎的優化,當前支持文件數據源和數據庫數據源,支持增量分析和離線一次性分析,分析模型運行期可改變,提供實時的監控預警。太晚了,最后貼一個開放平臺的技術當前總體架構圖:
