DevOps研習社:品質決定成敗——漫談非功能性需求本期看點
本篇文章主要分析了應用的非功能性需求,F5如何幫助應用實現業務邏輯之外的功能。例如:高可用性、安全性、可維護性等等。
朱傑
F5金融事業部技術顧問
F5金融事業部技術顧問,專注於應用的使用者體驗,具有豐富的應用交付、UI/UE工作經驗。
軟體的非功能需求
在網際網路的世界裡,“使用者就是上帝”這句話只體現在支付環節。
而在日常生活中,幾乎每一個人都清楚的知道,不論是產品還是服務,品質決定競爭力,而對於一個軟體、應用或者App來說,功能是生命線,確定能否安身立命,而非功能需求則是它的品質。
一個軟體、應用或者App的特性表現在兩個方面,功能性與非功能性。功能性好理解,硬指標,開發過程中的里程碑,一定要啃下的山頭,而非功能性需求更偏“軟”,如App好不好用,速度快不快,設計是否反人類等。在我們的日常生活中,非核心、非會員,只要帶了一個“非”字,往往都不是那麼重要的,可不能因為非功能性帶了一個“非”字就常規鄙視它,。在遙遠的古代(10年前),IT市場上的物資(應用)十分匱乏,這個時候,生存是文明的第一需要,能夠實現主線功能就有能力去市場上衝衝浪,佔佔山頭,使用者也普遍具有超高的容忍度和耐心,即使有些許不爽也只能忍受著用著“卡/醜/難”的App;但在App如過江之卿的今天,使用者們翻身奴隸把歌唱,分分鐘可以解除安裝掉一個哪怕只有一點點讓自己不爽的App,轉身下載一個同類的,所需的成本不過滑動幾下手指頭。
所以,在這個使用者心目中最好的資訊時代裡,即使是歷史巨頭如故步自封,也會在一日之間山河破碎,動搖根基,同樣的,哪怕名不見經傳的App,如視使用者為上帝,想起所難,及其所及,可能會一朝成名天下知。
在當下的App爆發式增長,並且同質化嚴重的情況下,非功能需求這些個“軟服務”會更好的體現出App差異化的特點,向用戶傳遞特定觀點,提供優質服務,從而能夠俘獲使用者的“芳心”。
說了這麼多,讓我們來看看非功能需求都包括哪些“軟”指標。下面是ISO/IEC 25010 軟體質量管理模型:
可以看到,除了功能性外,影響軟體產品質量的關鍵因素還包括效率、相容性、易用性、安全性、可靠性、可維護性和可移植性7個維度,每個維度又包括了許多方面,涉及到架構、內容、互動、運營、安全等,這些都屬於非功能需求的範疇。
非功能需求服務化
我們先來看一看非功能需求場景化的一些例子,這些例子只是我個人考慮到的,真實的場景數量會遠遠超出這些:
查德一看,其實也沒什麼,無非的各種對開發者嚴厲,對使用者友好的要求,但若是要仔細想一想,這些需求怎麼樣去一一實現它,就會覺得比較頭疼了,放在哪裡、哪個部門、哪個階段貌似都不能一勞永逸,高枕無憂,因為有的需求需要的是伺服器資源,如“支援動態使用者1500以上”,有些需求需要的是開發過程解決,比如“系統支援多種瀏覽器”,還有的需求是需要應用釋出之後,運維團隊來實現,比如“普通修改一天內完成”,再有甚者,需要多種資源,多個團培配合著來,比如“應用熱點/流量熱點分析”等。
仔細想想,這可能也是非功能需求這一塊普遍做的不如預期的原因,一個定義在軟體質量模型裡面的屬性,竟然要指揮架構、運維甚至運營部們協作工作,可以想象其中的難度。
可以預見,要在非功能需求這塊下功夫,甚至要打穿部門之間的壁壘,讓不同的部門同時參與,互相協作,這是一個也過往完全不同的文化氛圍,這不由讓我們想到了DevOps這個炙手可熱的名詞,這算不算是殊途同歸呢?
弄清了需要參與哪些人和部門後,我們再進一步來剖析具體的非功能需求應該放在軟體生命週期的哪個階段,亦或是以哪種形式存在:
效率
效率,關注點是業務量與資源容量的佔比,以及業務流量的合理分配,對這一塊提出的要求是宜儘量貼近適應實際的生產需求,並且具備應對業務量的變化(快速增長或者下降)的能力,不宜資源閒置浪費或因為資源排程的不靈活造成的生產影響,這兩點開起來似乎有些矛盾,不過那是放在姿態的資源分配上,如果採用動態的資源分配方法,那麼就像三維看二維一樣,是有合理的解決途徑的。關於效率的需求在開發和運維過程中都存在,並且是一個動態的需求;
相容性
相容性,軟體之間是否能夠正確地互動和共享資訊。相容性對於軟體的意義取決於開發小組用什麼來定義,以及軟體執行的系統要求的相容性級別。相容性包括向後和向前相容:向後相容是指可以使用軟體的以前版本。向前相容是指可以使用軟體的未來版本。在特定的時間內,可能存在多個版本同時存在的情況,並因此誕生出新的使用者需求,如易用性需求,通俗來說就是使用者體驗;
易用性
易用性,是非功能需求裡面最火的一個話題,也是最能體現軟體是否按“使用者就是上帝”的態度來設計的評判標準之一,易用性是與一組規定或者潛在的使用者為使用其軟體所需做的努力和對這樣的使用所作的評價有關的一組屬性。具體包括:易理解性、易學習性、易操作性等。這類非功能需求是與UI/UE設計有著直接關係的,也就是說這類屬性會關聯到具體的技術性功能需求,也因此,UE到底是劃分在功能性需求還是非功能性需求上,尚有一些爭議,但是主流觀點都認為,這是非功能性需求的一個典型部分;
安全性
安全性,包括傳輸加密,儲存加密,可破解性,以及各種未被授權的使用者行為如何防範和控制等,這裡的安全不單針對外部普通使用者,也針對內部不同級別的許可權使用者的的控制,不單指服務端,也包括傳輸通道,客戶端,細到精巧的技術滲透如慢速撞庫,粗到混合流量的DDoS攻擊,都需要考慮在內,在生活中我們做任何事情都需要安全感,在資訊世界中這種需要更被放大了許多。在安全性的考慮上,需要綜合考慮架構層、網路層和應用層的安全,還有一個非常重要的因素就是安全的ROI,這裡不單單指投入的金錢,更指投入的資源,因為,往往安全性和易用性可能是成反比的,所以,靈活適用是安全的一個重要前提;
可靠性
可靠性,在規定的一段時間和條件下軟體維持其效能水平的能力有關的一組屬性。具體包括:
成熟性
與有軟體故障引起失效的頻度有關的軟體屬性。
容錯性
與在軟體故障或違反指定介面的情況下維持規定的效能水平的能力有關的軟體屬性。如離線錄入支援等。
易恢復性
與在是小發生後重建其效能水平並恢復直接受影響資料的能力,以及為達到此目的所需時間和努力有關的軟體屬性。如表單資料自動儲存等。
這類非功能需求通常是全域性的,他除了與系統執行環境、平臺選擇、程式碼質量相關之外,還會涉及部分技術性功能需求,他別是容錯性、易恢復性的實現都需要一些具體的功能來支援;
可維護性
可維護性,維護性是指與進行指定的修改所需的努力有關的一組屬性。具體包括:
易分析性
與為診斷缺陷或者失效原因及為判定待修改的部分所需努力有關的軟體屬性。如日誌記錄系統等。
易改變性
與進行修改排除錯誤或者適應環境變化所需努力有關的軟體屬性。
穩定性
與修改所造成的未預料結果的風險有關的軟體屬性。
易測試性
與確認已修改軟體所需的努力有關的軟體屬性。
這部分通常是開發團隊最容易投入時間和成本的地方,諸如動態屬性支援、UI介面生成、流程引擎等都是為了提高系統的可維護性,因此它顯然是會引申出相關的技術性功能需求的。更進一步的時,在應用釋出的運維和運營工作中,對可維護性的需求也是越來越來,因此,一些需要頻繁變化或者做安全隔離的非功能需求的實現可以從軟體開發包裡單拉出來,形成單獨的服務交付層,用來實現更多的對可維護性要求高的目標;
可移植性
可移植性,簡單來說是軟體是否具備在不同的環境中轉移的能力,具體包括:
適應性
與軟體無需採用有別於為該軟體準備的活動和手段就可能適應不同的規定環境有關的軟體屬性。如全球技術支援等。
易安裝性
與在指定的環境下安裝軟體所需努力有關的軟體屬性。如線上更新、安裝包自動生成等。
遵循性
使軟體遵循與可移植性有關的標準或約定的軟體屬性。
易替換性
與軟體在該環境中用來替代指定的其他軟體的機會和努力有關的軟體屬性。
這部分除了需要通過選擇正確的開發工具、平臺來支援外,也會涉及一些技巧性的功能需求,如全球語言支援等。
好了,上述我們分析了這麼多,我們發現非功能需求的有一些共同點:
1
當不僅存在於開發階段,還存在於運維階段與運營階段;
2
在實現自身需求的同事,會涉及或者引發新的需求;
3
對實現手段的靈活程度和後續的管理與維護的便捷度有要求。
基於以上三個特點,我們發現基於非功能性需求的實現不論是單單放在開發階段,還是隻放在運維階段,都是不完美的,因此,我們大膽假設,獨立設計一個應用服務層,使用者實現非功能需求的場景,並且貫穿與開發與運維的生命週期內。
非功能需求在運維工作中的體現
在日常的運維工作中,我們經常面對非功能需求的目標場景,只是也許我們意識不到,大到多活中心應用釋出與運維,跨雲中心應用釋出與運維,DNS智慧解析,跨中心Cookie會話保持,小到使用者身份識別與流量˙轉發,長連線MBLB的拆分及轉發,Http引數優化又或者是URL重寫,以及加強認證授權管理等,都屬於可靠性、安全性、易用性的範疇,還有更多數不完的實際工作任務都可以歸到肺功能需求這一塊,為什麼原來僅僅是在軟體質量模型裡的需求現在已經延伸到了運維工作中,是因為開發與運維的界限慢慢模糊化了,對應用品質的追求的過程中人們也慢慢找到了規律,積攢了經驗。而在運維工作裡,我們早就已經有了一個概念,叫做應用交付層,這一層能夠提供計算、分流、安全、解除安裝等功能,並且能夠無視資料中心數量與形態的變化,與應用緊密結合在一起,旨在為使用者提供高品質的應用和服務。
但是,目前來說這部分的工作還是存在著明顯的不足,因為這些僅僅還是屬於運維部門的工作,而且效率也遠遠談不上高效,通常都是以在固定的工程時間窗口裡完成有限的變更這種手段來完成,而對於應用的不瞭解導致能完成的工作也極其有限,這種方式讓我們看到了企業追求卓越品質的意願,但是與實際上使用者與市場的需求想去甚遠。
針對運維工作中提供非功能需求實現與維護的場景,我們為了彌補環境多樣化、效率低、需求不明確等諸多不足,應該做到以下幾點:
01
構建跨平臺的應用服務交付層,建設一致交付的能力,滿足可靠性的要求;
02
應用服務交付層應具備優秀的應用交付服務能力,滿足效率的要求;
03
實現應用的部分非功能性需求解耦,滿足易用性與可維護性的要求。
完成了上面三點,還不夠,前文已經提到,非功能性需求不是在一個環節、一個階段內能夠完美搞定的,所以,我們要打通渠道開發的那條線,想要打通開發那條線,不是說說就可以了的,必須具備開發的一些“屬性”:
01
要能夠實現服務交付即程式碼,及所有運維平面的工作,能夠通過程式碼來實現;
02
要能夠與運維平面的服務等級與能力保持一致性;
03
實現的非功能需求的服務能力要是安全的,可控的;
04
所有開發測程式碼實現的非功能需求,可以無縫轉化為服務交付層的服務能力。
非功能需求在開發工作中的體現
前面談了運維工作中的非功能需求的實現,以及如何與開發工作中的肺功能需求結合,那麼下面我們來談談在開發工作中如何較好的實現和管理非功能需求場景。
我見過不少的網際網路應用,在本身的程式碼層裡已經寫入了一些非功能需求的實現,但是可謂是慘不忍睹,稍好一些的一個例子是,在前端頁面用JS來監聽事件,判斷使用者的行為,來做一些安全的審查和表格填寫的審計,比如,使用者輸入了類似注入攻擊的欄位,又或者是有些輸入沒有輸入必須要填的資訊等,這樣的實現手段落後不說,實際上還存在多重風險:
1如果在業務釋出的時候有經過WAF,那麼這裡的程式碼實際上就重複了,不但沒有提高應用的品質,反而降低了效率;2較多的js事件監聽,會造成潛在的安全風險;3不能適應敏捷的變更,如果涉及到這裡寫死了的策略需要更改,就需要改應用。
除了上述的例子,還有數不清的類似的情況,因為開發人員關心的是主線功能的設計與實現,而現在的敏捷開發更是引入了Sprint的概念,時間分秒必爭,到了非功能需求的實現的時候就可能會出現敷衍瞭解,亦或者鎖邊從一些公共的或者缺乏有效管理的庫或者源拉一個就用,這樣不論是對效率、安全、以及維護的便捷性來說都不是一個好的辦法。
那麼,按照在運維側的思路,我們是否也可以為我們的應用獨立設計一個服務交付層,將非功能性的需求實現放在這裡,而這些需求可以採用更專業的實現的同時,同時也隔離了一些公共程式碼和庫的安全問題,更妙的因為程式碼實現的場景能夠無縫的部署在運維側,所以能夠和運維打通,互通有無,能做更多的事情,提升應用的品質。
如上圖,我們可以在程式碼code階段就設計為App code 和ADC Code,然後再build階段先整合App的code,然後做測試,在Deploy階段的時候由CI Server從github上拉取ADC的code,然後一起部署App和ADC Service到伺服器或者容器平臺,ADC的code部門還可以再細分成ADC code 和Security Code,後者用來做應用層的安全防護,在這樣的情境下,在每一次code的階段就設計好ADC 和Security的實現,和App Code 同時Deploy,實現了整體應用和安全交付的CI/CD和快速迭代,極大的提高了生產和運維效率。
如果想實現開發側的應用交付層的設計,需要具備以下的能力:
1要能夠實現獨立的服務交付層,與應用核心程式碼解耦;2要夠無縫的整合CI/CD;3實現的功能無開發語言無關為佳。
DevOps提升App品質
前文提到,軟體的非功能需求決定了軟體的品質,在某些程度上與DevOps是不謀而合的。在DevOps的文化裡,不緊緊的打通了運維與開發的屏障,更是將各個階段形成了一個生生不息的迴圈,形成一個持續整合、持續交付的生態,如果說DevOps是一種文化,一種氛圍,追求高品質的App是目的,那麼,努力發展非功能需求的實現及優化則是一種行之有效的手段。
由於實現了非功能需求的服務化,在一個良好的DevOps的氛圍裡,我們甚至可以利用這些服務來做線上BI甚至精準營銷,由運營側提出需求,指定基於App的使用者行為分析圖,然後分析收集的資料,反向推動優化非功能需求的實現甚至是主線功能需求的優化,從而達到提升客戶滿意度,提升市場佔有率的目的。由於我們已經打通了應用交付服務的關節,所以這些資料和分析與每個部門各自為戰比起來,要精準、快