2、在項目的架構設計中,對于未來可能發生的需求變更,你是如何考慮的?如何應對?
需求變更可以分成業務性和非業務性兩類。
非業務性主要是指由于系統自身應用場景發生變化(處理的數據量,業務規則復雜度),使得需要對現有系統做結構性調整。
舉個例子:
開放平臺的日志分析系統,在數據量不斷增大和計算即時性要求增強的情況下,由單機多線程計算演變為多機分布式協作計算,從全量文件分析轉變為增量基于數據流分析。但整體結構卻沒有發生太大變化,如下圖:

最初,每日訪問量6千萬,數據分析報表每日一出,分析器僅僅用于業務行為分析統計,單機每日拖取全量日志文件,多線程切割分析后合并。系統設計中有統計模型抽象層和簡單的任務管理層,統計模型抽象層就是將傳統的統計分析抽象成為對無結構化的數據做MapReduce的計算,模型規則引擎可以根據配置直接分析無結構化定義的日志數據,任務管理層在第一階段只是負責任務多線程內分配和管理。
當日志量每日達到2億,分析器每日分析數據涵蓋了系統,ISV,服務提供方,業務多角度分析和數據挖掘,單機IO及CPU成為瓶頸。因此,首先修改第二層,將原來多線程的任務管理和分配,擴展支持多機任務管理和分配(基于TCP層的數據交互協議)。第三層里所當然的出現成為承載多機協作的基礎層,因為本身沒有太多的復雜流程在里面,就直接實現NIO的通信層。這次需求變更的代價就是擴展了任務分配協議,支持多機協作工作,本地的數據合并,轉變為通信傳輸后的本地數據合并,但對上層業務分析引擎沒有任何影響。
當日志量每日達到8億,分析器已經應用于整個系統的監控和告警及業務趨勢分析等各個方面,全量每日分析不滿足業務需求,則由每日全量分析,改變為時時增量分析。這次修改了第二層,首先擴展了slave的數據源獲取的方式,除了支持文件獲取,還支持http數據流的獲取,其次,擴展了master對于任務周期的管理,任務列表可以周期被重置,同時可以周期性導出增量數據,因此即時分析可以通過使用較短周期(分鐘級別)的任務列表管理,任務分配,結果合并和增量導出,實現即時的大數據量分析。這次需求變更,可以發現僅僅是對任務管理的周期做了更靈活的擴展,同時在Slave上做了多數據源數據的獲取,對于本身任務管理,合并,計算都沒有任何影響。
總結來說,對于非業務性的需求改變,需要能夠將業務性設計和系統設計隔離開來,同時明晰系統設計邊界,支持外部接口的可擴展,這樣就能夠支撐由于系統應用場景的變化帶來的系統架構的變化。
對于業務性需求變更,思維方式應當如下(有順序):
1. 是否已經有類似功能,需要做些改進就可以滿足需求。
2. 沒有類似功能,是否可以抽取部分已有功能,再做部分封裝即可實現。
3. 完全沒有可以復用的內容,考慮一下后續可能的業務需求。
也許大家看了比較虛,但是業務一定是根據場景來做出自己的實際判斷,而上面說的三點其實就是一個理念,不斷優化業務代碼,復用的思考會促進不斷的合理化結構(因為復用性越小的代碼大部分情況下結構本身存在耦合性過強的問題)。
3、在開放平臺中,如何防范對于API應用接口的安全入侵、拒絕服務攻擊?如何應對突發的訪問請求激增情況?
API的安全問題主要涉及兩個方面:用戶隱私安全和服務自身安全。
用戶隱私安全主要通過對應用的身份認證及用戶主動授權的兩方面來保證。當然現在很多開放平臺對于授權的時效性放的還比較松,這樣會導致用戶一次授權,而被應用無限制使用的風險(用戶往往找不到平臺解除授權的地方)。淘寶開放平臺,對應用做了級別劃分和類型劃分,首先在服務訪問范圍上,不同級別和類型的應用可訪問的服務范圍就被區別開來,因此高風險性的數據類服務只對Hosting的應用合作伙伴開放,不同類型的應用訪問的服務也有所差別。其次,用戶授權也根據應用類型的不同及服務本身的安全級別會有不同的授權時效性及授權提示,使得不同應用操作用戶數據會限制在不同時長內。最后,還提供了用戶主動查詢應用訪問數據的情況及解綁授權的入口,給用戶提供主動解除風險的機會。
服務自身安全,主要是應用自身主動和被動攻擊(例如網站沒有作數據緩存和防爬蟲的功能,在爬蟲爬取網頁的同時,導致大量的無用服務請求)。當前開放平臺主要通過兩種模式多種維度來防止服務激增的問題。兩種模式:一種是主動在業務流程處理中按照簡單規則計算并做訪問流量控制,例如通過利用集中式和本地Cache作為計數器根據簡單規則來屏蔽過量訪問。另一種是通過記錄日志,交由外部分析系統增量分析,外部分析器根據各種復雜關聯性業務規則最后將分析后的決策推送給業務系統去做過量訪問控制。多種維度:IP,應用身份,用戶身份,User Agent,訪問的服務。這些維度可以簡單的單個控制,也可以是組合控制,例如,IP維度可以用在業務數據可能都是非法的情況下去屏蔽,由于規則很簡單,可以直接放在主動模式下,而應用身份+用戶身份比較復雜的控制,放在被動模式下,同時規則可以根據業務基線(不同日同時段,不同周同日的統計結果)的變化調整。從技術角度上來說,通過將業務線程池和容器線程池分開(類似于Servlet3容器線程生命周期不再固化與單一的方法),可以自己定義業務線程權重和處理流速來保證后端業務系統能力不會由于前端請求量激增時產生惡性循環。
4、在開放平臺中,面對不同背景、習慣的用戶和開發者,如何能夠讓他們使用起來更便捷、易用?
開放平臺在這方面主要做了和將要做這些事情:
1. 多語言SDK自動生成。淘寶當前有300多個API,而且服務還在不斷地增加,每次SDK的升級和發布都采用模板化方式自動生成,同時多語言的支持可以給開發者減小開發成本。這里就要談到SDK的業務部分和非業務部分的抽象和隔離,更加有利于服務的增加和減少。
2. 服務數據化到服務流程化的轉變。對于不同領域的開發者來說,淘寶的服務其實并不是都需要或者無差別的,例如淘江湖軟件和商家管理軟件就有很大差異,因此對于淘寶這樣行業性認知要求比較高的服務使用成本降低需要通過將服務由專家來做一定的流程化定制,避免使用的高門檻。
3. 提供demo和doc直接附加在SDK中,讓開發者比較直接的能夠看到使用方式,并且簡單的運行一些具體的實例,增加感性認識。
4. 提供wiki和社區,為服務升級和變更提供足夠的信息傳播渠道。
5. 提供線上運行環境和控制臺,用直觀體驗降低門檻。
5、在優化程序,降低系統資源消耗上,有哪些經驗可以分享?
1.優化程序很多程度上是從全局去看,而不是從局部去看,局部的優化可能導致全局的性能下降。例如,A系統和B系統是強依賴的,A的處理能力被提升后,到B的單位時間請求量會增加,而此時B服務能力達到瓶頸,單位事務處理時間就會增加,而A的處理能力增強并不一定會提高在A階段的單位處理時間,因此整體事務處理時間增加,同時系統穩定性降低。因此優化需要關注更多的依賴,特別需要事先審視自己系統是依賴流入還是依賴流出系統。
2.優化流程首先要切分流程的步驟,然后找到瓶頸的步驟,而優化瓶頸點有兩種方式,一種直接優化減少瓶頸點資源消耗和處理時間,另一種是利用并行化方式,縮短資源生命周期,增加資源利用率從而減少對于資源消耗,為瓶頸點的資源使用增加能力。
3.合理利用外部計算資源,在可維護性和性能上找到平衡點。例如開放平臺的結果返回處理通常情況下需要將對象根據規則定義轉變為通用的格式。這部分工作可以交由開放平臺集群來統一處理,也可以將規則處理后移到業務系統,前者的優勢在于映射規則變動升級容易,后者可以把計算工作分攤到各個業務集群上,基于映射規則的成熟和無業務性,因此計算外移是提高本系統性能的一種方式。
4.可以將不同資源消耗型的應用部署在一起,合理利用資源(CPU消耗型,內存消耗型)。
5.在做海量數據處理時,不要認為Java原生的東西都是無消耗的,那么是去拿一個時間戳,切分一個字符串,匹配一個字符等等,盡量以最直接和簡單的方式實現邏輯,用原生數據類型做為系統中間過程處理內容(例如系統中就用long型做日期類處理)。
上面提到的也許看起來很抽象,但過于具體的細節優化其實遍及每個角落,優化最重要的就是找到全局的問題所在,同時在優化后是否會產生新的問題,導致了性能反而不如優化前,同時系統穩定性也是優化所需要考慮的問題。
6、在高并發應用中,Cache的作用不可忽視,在Cache的使用上,有哪些問題需要去注意?
1.集中式緩存不是無代價的。從存儲的數據量到交互次數上都需要去考慮如何降低成本,在海量并發請求的系統中,存儲標識還是內容,多次交互還是一次交互,都會對系統產生很大影響。適當的可以使用多級緩存(remote + local),然后根據數據敏感度設置有效時間,簡單的處理數據失效問題。
2.Cache不可用如何降級。對業務系統來說,需要考慮Cache如何降級,也就是業務流程是否可以繼續下去。另一方面如果Cache失效會從其他數據源獲取數據,那么就需要考慮Cache的瞬間失效產生的峰值是否會直接擊垮后端數據源。
3.Cache如果采用數據源作為不命中的主動獲取途徑,那么需要防止無效的數據請求攻擊透過Cache直接進入后端數據源。一般可以考慮用布隆算法來做增量白名單。
4.注意使用好Cache提供的原子操作來避免并發帶來的問題,例如add , replace, inc ,dec等等。
5.需要去了解Cache的命中率和使用容量情況,不要為了技術而技術,需要更多的分析業務場景,最大限度利用Cache的優勢,同時減小存儲消耗的代價。
7、開源產品,很多時候可以用來借鑒設計思路、進行二次開發、引用部分類庫,應用到業務產品中。你是如何看待開源產品和業務產品之間的關系?
業務產品對于開源技術的選型需要慎重,同時切記跟風,今天FB用了什么,明天TW用了什么,最重要的是自己的業務場景,如果可以用簡單的技術實現,則優先考慮簡單的技術借鑒部分開源設計的思想去做,同時量體裁衣簡化系統設計,往往開源項目發展到一定規模會朝通用化方式發展,使用成本,附加功能,系統的松耦合,都會給中小型系統高速系統帶來一定的負擔。
使用開源項目最重要的是了解它解決的問題是什么?應用于什么場景,不同場景下的優勢和劣勢在什么地方,自身場景中使用的部分成熟度如何,最后做好足夠的測試和驗證,聽來的總是虛的,因為業務場景不同,就算技術框架相同,結果也不同。