軟件的非功能需求
在互聯網的世界里,“用戶就是上帝”這句話只體現在支付環節。
而在日常生活中,幾乎每一個人都清楚的知道,不論是產品還是服務,品質決定競爭力,而對于一個軟件、應用或者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的用戶行為分析圖,然后分析收集的數據,反向推動優化非功能需求的實現甚至是主線功能需求的優化,從而達到提升客戶滿意度,提升市場占有率的目的。由于我們已經打通了應用交付服務的關節,所以這些數據和分析與每個部門各自為戰比起來,要精準、快速、高效的多。
原文轉自:http://www.uml.org.cn/RequirementProject/201910312.asp