張宴

張宴

張宴是一名系統開發工程師,從事於移動網際網路領域,專注於高性能後端技術、平台架構與數據挖掘。曾任金山遊戲運營技術中心開發經理/架構師、趕集網架構師、新浪播客系統開發工程師。

基本介紹

  • 中文名:張宴
  • 國籍:中國
  • 民族:漢族
  • 出生日期:1985年5月19日
  • 職業:網際網路運營
  • 畢業院校:中南民族大學
  • 代表作品:《實戰Nginx:取代Apache的高性能Web伺服器》
  • 性別:男
工作經歷,社會活動,

工作經歷

北京熱拍科技/蘇州原璞信息(2013.01.01─今)
地區:北京市朝陽區 蘇州市工業園區創意產業園
職位:合伙人
公司 4399(2012.02.07─2012.12.31)
地區:北京 ,朝陽區
職位:閃購輕電商移動網際網路創業團隊
北京世紀一家網電子商務有限公司 (2011.09.01─2012.02.06)
地區:北京 ,朝陽區
職位:技術總監
金山遊戲(2008.11.24─2011.08.31)
地區:北京 ,海淀區
職位:運營技術中心 網站開發部 架構師
趕集網 (2008.04.01─2008.11.21)
地區:北京市海淀區清華科技園
職位:架構師
新浪網技術(中國)有限公司 (2007.01.25─2008.03.31)
地區:北京 ,海淀區
職位:原新浪互動社區事業部播客產品部系統工程師

社會活動

張宴VS.岑文初
張宴:在項目的架構設計中,對於未來可能發生的需求變更,你是如何考慮的?如何應對?
岑文初:需求變更可以分為業務性和非業務性兩類。
金山張宴VS.淘寶岑文初金山張宴VS.淘寶岑文初
對於業務性需求變更,思維方式應當按如下順序進行:
第一,是否已經有類似功能,需要做些改進就可以滿足需求;
第二,沒有類似功能,是否可以抽取部分已有功能,再做部分封裝即可實現;
第三,完全沒有可以復用的內容,考慮一下後續可能的業務需求。
也許上面的內容比較虛,但業務一定是根據場景來做出實際判斷,而這三點其實就是一個理念——不斷最佳化業務代碼,復用的思考會促進不斷地合理化結構(因為大部分情況下,復用性越小的代碼其結構本身存在耦合性過強的問題)。
非業務性需求變更主要是指由於系統自身套用場景發生變化(包括處理的數據量、業務規則複雜度等),而使得需要對現有系統做結構性調整。下面我舉個例子。
開放平台的日誌分析系統,在數據量不斷增大和計算實時性要求增強的情況下,由單機多執行緒計算演變為多機分散式協作計算,從全量檔案分析轉變為增量基於數據流分析。但整體結構卻沒有發生太大變化。
最初,系統日訪問量為六千萬,數據分析報表每日出一次,分析器僅僅用於業務行為分析統計、單機每日拖取全量日誌檔案、多執行緒切割分析後合併。系統設計中有統計模型抽象層和簡單的任務管理層:統計模型抽象層就是將傳統的統計分析抽象成為對無結構化的數據做MapReduce計算,模型規則引擎可以根據配置直接分析無結構化定義的日誌數據;任務管理層在第一階段只是負責任務多執行緒內分配和管理。
當日誌量每日達到兩億,分析器每日分析數據涵蓋了系統、ISV、服務提供方,業務多角度分析和數據挖掘、單機I/O及CPU就成為瓶頸。因此,首先修改任務管理層,將原來多執行緒的任務管理和分配,擴展為支持多機任務管理和分配(基於TCP層的數據互動協定)。數據通信層理所當然地成為承載多機協作的基礎層,因為本身沒有太多的複雜流程在裡面,就直接實現NIO的通信層。這次需求變更的代價就是擴展了任務分配協定以支持多機協作工作,本地的數據合併轉變為通信傳輸後的本地數據合併,但對上層業務分析引擎沒有任何影響。
當日誌量每日達到八億,分析器已經套用於整個系統的監控和告警及業務趨勢分析等各方面,全量每日分析滿足不了業務需求,於是由每日全量分析改變為實時增量分析。這次需要修改任務管理層:首先,擴展了Slave的數據源獲取方式,除了支持檔案獲取,還支持HTTP數據流的獲取;其次,擴展了Master對於任務周期的管理,任務列表可以被周期性重置,同時可以周期性導出增量數據,因此實時分析可以通過使用較短周期(分鐘級別)的任務列表管理、任務分配、結果合併和增量導出,實現實時的大數據量分析。這次需求變更僅僅是對任務管理的周期做了更靈活的擴展,同時在Slave上做了多數據源數據的獲取,對於本身的任務管理、合併、計算都沒有任何影響。總之,對於非業務性的需求改變,需要能夠將業務性設計和系統設計隔離開來,同時明晰系統設計邊界,支持外部接口的可擴展,這樣就能夠支撐由於系統套用場景的變化帶來的系統架構的變化。
許式偉VS.張宴
許式偉:作為系統架構師,您一般會從哪些方面來保證網站的高可用性(降低故障時間)?
張宴:很多因素都會導致網站發生故障,從而影響網站的高可用性,比如伺服器硬體故障、軟體系統故障、IDC機房故障、程式上線前測試未發現的Bug、遭受分散式攻擊、突發訪問人數劇增等。
盛大許式偉VS. 金山張宴盛大許式偉VS. 金山張宴
一套良好的網站系統架構,應該儘可能地避免只有一台伺服器、一個資料庫、一套軟體節點等單點故障的存在。單點故障一旦發生,將直接導致網站服務不可用,恢復正常服務所需的時間也比較長,甚至還可能無法恢復。負載均衡集群、雙節點熱備、分散式處理等都可以用來解決單點故障,比如提供相同業務的Web伺服器、MySQL資料庫從庫,都可以構建負載均衡集群。一旦集群中的一台伺服器、一個服務出現故障,自動實時摘除,對用戶來說是不可感知的,不會影響到整個網站的訪問,可以為運維工程師留下足夠的時間去排查和解決故障。
對於重要的MySQL資料庫主庫,我們習慣於從硬體層和軟體層來實現熱備,避免單點。越是複雜的設備,發生故障的機率越大。在磁碟沒有損壞的情況下,應用程式導致伺服器宕機的機率,遠高於簡單的磁碟陣列宕機的機率。所以,從硬體層解決的話,可以在兩台伺服器上安裝相同的資料庫版本、進行相同的配置,用SAS或SCSI線連線一台磁碟陣列,將資料庫數據檔案存放到盤陣上。正常情況下用伺服器A掛載盤陣分區,啟動MySQL,綁定虛擬IP;如果伺服器A宕機,則用伺服器B掛載盤陣分區,啟動MySQL,接管虛擬IP。從軟體層解決的話,則可以藉助DRBD等軟體做鏡像。
IDC機房發生故障的機率較小,但如果發生的話,影響面也是最大的。如果所有伺服器都託管在一個IDC機房,一旦該機房遭遇長時間流量攻擊、斷電、斷網、地方政策性封網等,通常只能聯繫IDC去處理,除此之外束手無策,解決時間也比較長。如果成本允許,將網站伺服器分布在兩個以上的IDC機房,當某個IDC發生故障時,可以臨時切換DNS域名解析來優先恢復服務。
雖然程式代碼上線前,經過了測試人員的嚴格測試,但測試環境和生產環境畢竟有差異,所以一些會急劇影響性能、正常服務的Bug往往在程式上線之後,才會被發現,這就要求我們在發現Bug後,能夠迅速回滾到上一正常版本。我們在SVN的基礎上,開發了Web代碼發布系統,會將每個發布版本之間的檔案變更記錄下來,一鍵實現程式代碼在多台Web伺服器上的發布和回滾。
遭遇DDOS分散式拒絕服務攻擊,使用防火牆來對付半連線、假IP,還算比較容易。而那種專挑複雜動態應用程式URL進行的分散式CC攻擊,來源為真實IP、真實HTTP請求,具有模擬正規瀏覽器User-Agent、單個IP的每秒請求數不高、有成千上萬個攻擊源等特徵,很難與正常訪問區分開,比較難對付。但是,正常通過瀏覽器訪問一個URL,會載入該URL中引入的JavaScript腳本、CSS樣式、圖片等檔案。遇到CC攻擊,需要及時分析日誌,找出訪問量異常上漲的URL,然後用事先寫好的shell腳本找出哪些IP的請求只訪問了該URL,而不載入該URL引入的檔案,對這些IP進行自動封鎖。
對於網遊站點來說,訪問量受廣告集中時間段投放、線上活動的影響較大,頻寬峰值時間不固定,對於靜態內容,可以使用商業CDN,按實際使用量計費。對於動態內容,如果遇到突發訪問人數劇增,超過現有伺服器處理能力,最簡單的臨時處理辦法就是增加伺服器。上架新伺服器需要時間,但是,同一個IDC機房內,可以藉助其他業務的伺服器,在不同連線埠開啟一組新進程,加入到原有負載均衡池中。另外,可以臨時關閉一些Web中的次要功能,來減少伺服器消耗。
許式偉:您在任務切分上,有什麼經驗分享?您通過哪些手段保證任務的獨立性?
張宴:相信很多人都遇到過這種情況:在一個老項目上修改、增加一些新功能所花費的時間,不比重新來做一個包含所有功能的新項目時間用得少。一個需要長期維護的項目,不可避免地會面臨老員工的離職、新員工的接手,很多時候,項目代碼的可維護性將決定一個項目的生存周期。讓一個新員工在規定開發時間的壓力下,去面對一個文檔不夠詳細、陌生的、功能複雜的龐大項目,短時間弄明白所有功能邏輯不是一件容易的事。所以,任務需要切分,將一個大的任務切分成一個個小模組之後,各模組之間可以做到代碼獨立,互不影響,可維護性也大大增強。
關於任務切分,在第一個項目:金山遊戲官網的《用戶行為分析系統》中,由於數據挖掘計算需要消耗較高的記憶體、CPU資源,一台伺服器的處理能力不夠,而商業的分散式數據倉庫價格又太貴,所以,只有從程式套用中下手,進行任務切分。我們先按需要挖掘的數據指標,將整個數據挖掘任務切分成多個數據挖掘外掛程式,每個外掛程式可以在不同的伺服器上運行,多個外掛程式可以同時在多台伺服器上。多個數據挖掘外掛程式之間,如果用到相同的某項數據,那么,就將該項數據以冗餘方式,複製幾份提供給需要的外掛程式,從而實現外掛程式之間無互動、無關聯,保證了超大數據量下外掛程式的運算速度。
在第二個項目:金山遊戲新版運營管理系統中,則將整個任務切分成了PHP Web管理界面、PHP Web API功能接口、C/C++中間件引擎三部分。這是一種分層結構切分,最上層的“PHP Web管理界面”調用“PHP Web API功能接口”,“PHP Web API功能接口”調用運行在遊戲伺服器端的“C/C++中間件引擎”,“C/C++中間件引擎”與“遊戲伺服器端進程”通過TCP、UDP二進制協定、信號、命令行等多種方式通信。四者之間相對獨立,代碼無關聯,通過一層層API接口實現互動。“PHP Web管理界面”負責通用界面實現。“PHP Web API功能接口”內部,又按接入的遊戲模組、子功能模組進行了更細的切分,各功能模組之間通過內部API互動。“C/C++中間件引擎”大而全,不處理具體指令,但兼容TCP、UDP、HTTP、HTTPS/SSL、信號、命令行等大多數通信方式,負責和各種類型的遊戲服務端互動。這是一套完全由API接口驅動的系統架構,一款新遊戲接入運營管理系統時,只需在“PHP Web API功能接口”中增加一個模組;一個遊戲新管理功能的增加,只需要在“PHP Web API功能接口”中增加一個子模組。通過任務切分,將複雜功能簡單化,也將原來接入一款新遊戲所需要的幾個月時間,縮短為1~2周。

相關詞條

熱門詞條

聯絡我們