摘要:架構(gòu)設(shè)計(jì)實(shí)體化單元測(cè)試敏捷開(kāi)發(fā)講究要快速的修改代碼,我們往往會(huì)發(fā)現(xiàn),代碼修改的越頻繁,越多,這似乎是一個(gè)無(wú)法解決的矛盾。
本文由云+社區(qū)發(fā)表,作者:韓偉互聯(lián)網(wǎng)開(kāi)發(fā)的核心問(wèn)題
當(dāng)我1999年進(jìn)入互聯(lián)網(wǎng)行業(yè)工作的時(shí)候,華為剛剛通過(guò)了著名的CMM認(rèn)證。當(dāng)時(shí)作為一個(gè)小程序員,非常向往業(yè)界經(jīng)典的軟件開(kāi)發(fā)模式。因?yàn)榭瓷先?,如果企業(yè)實(shí)行了CMM,我們程序員就不用再天天為了老板一個(gè)拍腦袋的主意而加班開(kāi)發(fā)了,各種各樣的奇葩需求和無(wú)理變更,也會(huì)煙消云散。但是,在接下來(lái)的十幾年,幾乎沒(méi)有那個(gè)互聯(lián)網(wǎng)公司再去通過(guò)CMM認(rèn)證。
是否CMM這種軟件開(kāi)發(fā)模式,就根本不適合互聯(lián)網(wǎng)行業(yè)呢?這是一直以來(lái)我都在思考的問(wèn)題。反而是跟隨著互聯(lián)網(wǎng)企業(yè)的一步步長(zhǎng)大,我無(wú)意識(shí)的體驗(yàn)了很多現(xiàn)在流行概念的早期實(shí)踐:敏捷、重構(gòu)、持續(xù)集成、DevOps,這些實(shí)踐一開(kāi)始都非常的幼稚粗糙,但是卻真正的伴隨著互聯(lián)網(wǎng)業(yè)務(wù)的逐步成長(zhǎng)。所以,在討論互聯(lián)網(wǎng)服務(wù)的開(kāi)發(fā)模式時(shí),我認(rèn)為必須要先搞清楚互聯(lián)網(wǎng)服務(wù)開(kāi)發(fā)的核心問(wèn)題是什么。
本質(zhì):服務(wù),而不是產(chǎn)品軟件到底是“服務(wù)”還是“產(chǎn)品”,這個(gè)話題一直都非常具有爭(zhēng)議。作為程序開(kāi)發(fā)者,實(shí)際上是非常希望軟件能夠是一個(gè)產(chǎn)品,因?yàn)檐浖暮罄m(xù)維護(hù)和修改,往往是“導(dǎo)致”項(xiàng)目失敗的最常見(jiàn)原因。然而事與愿違的是,在互聯(lián)網(wǎng)企業(yè)中,打多數(shù)的軟件項(xiàng)目,表現(xiàn)出來(lái)的是典型的“服務(wù)”特征:
沒(méi)有明確的需求合同。這導(dǎo)致了沒(méi)有辦法為軟件設(shè)計(jì)固定的開(kāi)發(fā)方案,也難以確定長(zhǎng)期目標(biāo)。
沒(méi)有預(yù)付款和客戶(hù)驗(yàn)收?;ヂ?lián)網(wǎng)服務(wù)用戶(hù)來(lái)了就用,爽了就給錢(qián),不爽了就走,連溝通的機(jī)會(huì)都不會(huì)有。
甚至連明顯的銷(xiāo)售環(huán)節(jié)都沒(méi)有。很多互聯(lián)網(wǎng)公司只有市場(chǎng)推廣部門(mén),而沒(méi)有所謂“銷(xiāo)售”部門(mén),因?yàn)橥茝V就幾乎等于銷(xiāo)售,在推廣的同事,就必須把銷(xiāo)售的事情一起做了。
因此,在互聯(lián)網(wǎng)行業(yè)中,軟件開(kāi)發(fā)更多的是以一種服務(wù)的形式存在。這種特征,在對(duì)需求的分析管理;開(kāi)發(fā)技術(shù)的選擇;集成與測(cè)試;運(yùn)營(yíng)和客服四個(gè)方面,都導(dǎo)致了不同于“產(chǎn)品”型軟件的巨大差異:
對(duì)于一項(xiàng)服務(wù)來(lái)說(shuō),需求是持續(xù)變化的,你可以找到一些通用的模式,但是必須保持變化。
開(kāi)發(fā)效率是第一重要的,因?yàn)槭袌?chǎng)競(jìng)爭(zhēng)中,應(yīng)對(duì)需求變化快的單位將獲得更多的客戶(hù)。
由于服務(wù)必須保持長(zhǎng)期的穩(wěn)定可用,又要具備快速的更新部署能力,所以系統(tǒng)集成的效率和質(zhì)量要求非常高。所幸的是系統(tǒng)運(yùn)行的環(huán)境大多數(shù)都是在可控制的空間里(比如開(kāi)發(fā)公司自己的機(jī)房?jī)?nèi))。
服務(wù)是公司和客戶(hù)的一種持續(xù)溝通和交互的過(guò)程,并非一個(gè)單向的發(fā)售行為,所以互聯(lián)網(wǎng)服務(wù)需要更多細(xì)致的運(yùn)營(yíng)和維護(hù)的工具,否則難以做到迅速而細(xì)致的滿足海量的互聯(lián)網(wǎng)用戶(hù)的需求。
小米的MIUI開(kāi)發(fā)節(jié)奏
管理:手段.vs.工具在各種項(xiàng)目管理的課程里面,陳述了大量針對(duì)人去工作的方法。各種會(huì)議、報(bào)告、表格、評(píng)估、測(cè)量多不勝數(shù),然而軟件項(xiàng)目進(jìn)度的控制,依然是一個(gè)難度堪比登月的事情?!獙?duì)于很多項(xiàng)目經(jīng)理來(lái)說(shuō),程序員們基本是一個(gè)黑盒子,他們自己都不知道一個(gè)事情需要多長(zhǎng)時(shí)間干完,就更別提別人怎么去預(yù)估和控制。這里最大的問(wèn)題,我覺(jué)得是:我們往往總是想著怎樣“控制”住軟件項(xiàng)目的進(jìn)度,而忽視了如何減少不利于項(xiàng)目進(jìn)度的因數(shù)。實(shí)際上影響軟件開(kāi)發(fā)進(jìn)度的主要因數(shù),一般有一下幾個(gè):
程序員的能力水平。有一些項(xiàng)目其中的技術(shù),是程序員完全沒(méi)接觸過(guò)的類(lèi)型,這里包含了學(xué)習(xí)、調(diào)試的時(shí)間。
開(kāi)發(fā)過(guò)程中的各種修改變更。由于對(duì)可行性、需求確認(rèn)等方面的因數(shù),開(kāi)發(fā)往往會(huì)走“回頭路”。有些項(xiàng)目做到一般會(huì)發(fā)現(xiàn)技術(shù)上不可行,需要修改需求;而另外一些項(xiàng)目是在項(xiàng)目做到一半甚至快完成的時(shí)候,需求方發(fā)現(xiàn)需要修改產(chǎn)品設(shè)計(jì),因?yàn)樵诋a(chǎn)品可體驗(yàn)之前,完全無(wú)法想象到最后會(huì)是現(xiàn)在的樣子。
各種和開(kāi)發(fā)無(wú)關(guān)的過(guò)程中的事務(wù)。這里包括開(kāi)會(huì)、寫(xiě)報(bào)告、溝通、等待開(kāi)發(fā)電腦編譯、處理開(kāi)發(fā)服務(wù)器故障、各種開(kāi)發(fā)環(huán)境和測(cè)試環(huán)境的問(wèn)題處理等等……這些事情往往都看起來(lái)不是非?!坝屑夹g(shù)含量”,但是實(shí)際上會(huì)嚴(yán)重影響開(kāi)發(fā)進(jìn)度。因?yàn)殚_(kāi)發(fā)工作需要一個(gè)穩(wěn)定、專(zhuān)心的工作環(huán)境,頻頻的被各種事務(wù)打斷,會(huì)讓程序員反復(fù)的花費(fèi)時(shí)間去“進(jìn)入”工作狀態(tài)——面對(duì)成千上萬(wàn)行程序代碼,要找到之前寫(xiě)到哪個(gè)部分,其實(shí)不是那么簡(jiǎn)單。
針對(duì)上面說(shuō)的幾個(gè)問(wèn)題,很多都可以通過(guò)應(yīng)用更好的開(kāi)發(fā)工具來(lái)解決。比如一些新的需求類(lèi)型,我們可以求助于互聯(lián)網(wǎng)上豐富的開(kāi)源軟件和開(kāi)源庫(kù);面對(duì)需求變更,我們可以使用設(shè)計(jì)模式、單元測(cè)試等工具;開(kāi)發(fā)中的事務(wù)問(wèn)題,更是可以有大量業(yè)界先進(jìn)工具可用:SVN,Git,Jira,Project,IDE,Chef,Docker……
與其我們拿著鞭子抽打程序員,還不如給程序員更好的開(kāi)發(fā)工具,這樣對(duì)于項(xiàng)目進(jìn)度的推動(dòng),其實(shí)更有好處。
資產(chǎn):代碼.vs.流程互聯(lián)網(wǎng)公司是由人組成的,人是會(huì)流動(dòng)的,有一些小型的公司,往往會(huì)因?yàn)橐粌蓚€(gè)核心員工的離職,造成整個(gè)系統(tǒng)的代碼無(wú)法看懂,無(wú)法修改,從而最后導(dǎo)致公司完蛋。這種糟糕的情況,不止一次的出現(xiàn)過(guò)。然而,如果我們能有一套完善的開(kāi)發(fā)流程,或者是習(xí)慣,以及配合良好的開(kāi)發(fā)環(huán)境,加上有一定質(zhì)量的代碼,是完全能做到把項(xiàng)目代碼,在不同程序員之間順利交接的。可惜我們很多公司管理者,并不重視程序員用什么工具開(kāi)發(fā)軟件,也不知道如何去提高代碼的可讀性,所以造成我們的項(xiàng)目特別害怕人員變動(dòng)。如果我們把人員變動(dòng)看成是一個(gè)必然會(huì)發(fā)生的事情,那么我們就會(huì)更重視整個(gè)代碼的開(kāi)發(fā)環(huán)境和開(kāi)發(fā)過(guò)程,從一開(kāi)始就把開(kāi)發(fā)規(guī)范確定下來(lái),規(guī)定使用什么環(huán)境,應(yīng)用何種工具,并且堅(jiān)持執(zhí)行,同時(shí)在實(shí)踐過(guò)程中不斷的改進(jìn)。只有這樣有預(yù)備的去做,最后才會(huì)保留的住公司真正的資產(chǎn)。
一家互聯(lián)網(wǎng)公司,我們?cè)谠u(píng)估其開(kāi)發(fā)資產(chǎn)的時(shí)候,并不應(yīng)看他“擁有”多少行代碼,因?yàn)檫@些代碼是無(wú)法直接賣(mài)錢(qián)的。而互聯(lián)網(wǎng)公司的開(kāi)發(fā)速度,以及這個(gè)速度背后的能力才是最重要的。
敏捷開(kāi)發(fā)的意義和實(shí)踐敏捷開(kāi)發(fā)是我們現(xiàn)在最常見(jiàn)的一個(gè)“開(kāi)發(fā)模式”,然而很多時(shí)候,我們看到“敏捷”兩個(gè)字,似乎就是讓程序員多加點(diǎn)班,或者忽略一些過(guò)程加快把代碼弄出來(lái),而真正理解“敏捷”含義的并不多。實(shí)際上,敏捷并不會(huì)加快單位代碼的開(kāi)發(fā)速度!敏捷最主要的目標(biāo),是應(yīng)對(duì)需求不明確和需求變更,而這兩者正式互聯(lián)網(wǎng)服務(wù)中最常見(jiàn)的情況。
需求變更的原因在互聯(lián)網(wǎng)服務(wù)中,由于沒(méi)有直接的“客戶(hù)”下單要求,所以很多需求,都是由公司內(nèi)部的人“代表”的,最典型的就是我們的“老板”們了。正式因?yàn)闆](méi)有明確的“下訂單”的過(guò)程,所以很多傳統(tǒng)的需求分析變得沒(méi)法做了,因?yàn)椴还苁抢习暹€是產(chǎn)品經(jīng)理,都是面對(duì)著成千上萬(wàn)的客戶(hù)去猜測(cè)他們的需求,如果他們自己能代表客戶(hù)還好,如果猜錯(cuò)了,項(xiàng)目的代碼肯定要修改。很多互聯(lián)網(wǎng)公司都非常重視“數(shù)據(jù)”,原因就是這些“數(shù)據(jù)”往往代表了用戶(hù)對(duì)產(chǎn)品的看法,而這些看法成了互聯(lián)網(wǎng)產(chǎn)品設(shè)計(jì)的唯一客觀標(biāo)準(zhǔn)。然而這些數(shù)據(jù)本身,會(huì)包含了大量復(fù)雜性,由于統(tǒng)計(jì)方式、產(chǎn)品形態(tài)、季節(jié)時(shí)間等等,都會(huì)產(chǎn)生偏差。我們的項(xiàng)目需求,往往就是在這些偏差中確定。這就難免產(chǎn)生需求的變更了。
互聯(lián)網(wǎng)的客戶(hù)個(gè)體多,服務(wù)內(nèi)容豐富,功能變化快,是互聯(lián)網(wǎng)項(xiàng)目中需求變更很多的主要原因。因此這也讓敏捷開(kāi)發(fā),成為互聯(lián)網(wǎng)項(xiàng)目開(kāi)發(fā)中最重要的方法。——敏捷強(qiáng)調(diào)的是用原型來(lái)驗(yàn)證需求,在互聯(lián)網(wǎng)服務(wù)里就是,盡快推出服務(wù),通過(guò)數(shù)據(jù)來(lái)驗(yàn)證想法。如果我們能越頻繁的修正原型,就能越快的接近真正的需求,也就是說(shuō),如果我們的互聯(lián)網(wǎng)服務(wù)能越快的修正各種問(wèn)題,同時(shí)越快的推出新的版本,就能讓用戶(hù)越牢固的“黏在”這個(gè)服務(wù)上。
架構(gòu)設(shè)計(jì)實(shí)體化:?jiǎn)卧獪y(cè)試敏捷開(kāi)發(fā)講究要快速的修改代碼,我們往往會(huì)發(fā)現(xiàn),代碼修改的越頻繁,BUG越多,這似乎是一個(gè)無(wú)法解決的矛盾。然而,在敏捷開(kāi)發(fā)方法論中,有一個(gè)重要的措施,就是用來(lái)防止這種修改造成的BUG增加的。這就是——單元測(cè)試。 單元測(cè)試本質(zhì)上,充當(dāng)著自動(dòng)的QA人員的角色,如果我們把所有的設(shè)計(jì)和需求,都先按單元測(cè)試的形式“固化”編寫(xiě)下來(lái),那么我們?cè)谛薷拇a后,就能快速的、自動(dòng)的、反復(fù)的去驗(yàn)證我們的代碼有沒(méi)有問(wèn)題。如果這些測(cè)試足夠全面和詳細(xì),那么我們是不會(huì)擔(dān)心代碼修改導(dǎo)致大量的BUG的,因?yàn)閱卧獪y(cè)試會(huì)自動(dòng)幫我們支出問(wèn)題所在。一旦我們知道了問(wèn)題,修正起來(lái)反而變成是最簡(jiǎn)單的事情了。
假如一個(gè)項(xiàng)目的代碼丟失了,但全面的單元測(cè)試都還在,那么要重建這個(gè)項(xiàng)目并不困難,因?yàn)樗械男枨?,都被蘊(yùn)含在這些測(cè)試代碼中,程序員們幾乎不需要去重新啃文檔,談需求,他們只要把代碼弄成能通過(guò)單元測(cè)試就好了。這種需求的“代表物”不但是程序員開(kāi)發(fā)的概念和目標(biāo),而且還可以自動(dòng)的幫程序員去驗(yàn)證他們的實(shí)現(xiàn)。所以,如果你要使用敏捷開(kāi)發(fā),要嘗試頻繁修改原型,就一定要使用TDD(測(cè)試驅(qū)動(dòng)開(kāi)發(fā)),特別是高度重視單元測(cè)試的作用。
統(tǒng)一軟件設(shè)計(jì)思路的重要性曾幾何時(shí),我們認(rèn)為,使用什么語(yǔ)言開(kāi)發(fā),用結(jié)構(gòu)化編程,還是面向?qū)ο缶幊獭@些一般人難以深入理解的事情,都是程序員這伙頑固的家伙的怪癖,基本屬于私人喜好的范疇。外人既不應(yīng)該深入干預(yù),也沒(méi)辦法去影響,因?yàn)槿绻悴蛔R(shí)好歹去在這些事情上冒犯程序員,他們隨時(shí)可能一言不合就辭職。既然我們只需要可以運(yùn)行的代碼,我們?yōu)槭裁疵帮L(fēng)險(xiǎn)去激怒程序員呢?然而,在互聯(lián)網(wǎng)服務(wù)的開(kāi)發(fā)過(guò)程中,代碼本身并不是某一個(gè)固定的、靜態(tài)的東西,它需要不斷的與時(shí)俱進(jìn),需要跟隨這業(yè)務(wù)的發(fā)展而變化,同時(shí)也會(huì)從某一個(gè)程序員手里,流向整個(gè)開(kāi)發(fā)團(tuán)隊(duì)。在這種情況下,軟件開(kāi)發(fā)習(xí)慣、代碼的風(fēng)格、程序的設(shè)計(jì)思路,就變成一個(gè)非常重要的事情了。
代碼交流:面向?qū)ο?/b>確實(shí)現(xiàn)在還存在大量的討論,說(shuō)“面向?qū)ο蟛皇侨f(wàn)能的”。說(shuō)得對(duì),但是,世界上有什么東西是萬(wàn)能的呢?我只能說(shuō),在需求變更非??斓那闆r下,面向?qū)ο笏枷?,是現(xiàn)在我們能選擇的最好工具了。在“數(shù)據(jù)結(jié)構(gòu)+算法=程序”的時(shí)代,軟件主要是以計(jì)算任務(wù)為主,電腦是為了代替人腦進(jìn)行超乎想像的運(yùn)算任務(wù)而存在。而在互聯(lián)網(wǎng)時(shí)代,軟件主要的任務(wù)已經(jīng)變成了處理這個(gè)真實(shí)世界的信息了。信息的存儲(chǔ)、交換的任務(wù),已經(jīng)遠(yuǎn)遠(yuǎn)超過(guò)了“計(jì)算”的任務(wù)數(shù)量。雖然我們知道,所謂的信息處理,最底層還是依賴(lài)大量的“計(jì)算”,然而,我們的程序員們,早已不再需要編寫(xiě)大量“計(jì)算”的代碼,我們面臨的挑戰(zhàn),是如何用代碼準(zhǔn)確而快速的表達(dá)這個(gè)世界。
面向?qū)ο笏枷氚ǚ治觥⒃O(shè)計(jì)、編碼三個(gè)部分(OOA/OOD/OOP)。這些思想看起來(lái)繁文縟節(jié),似乎非常啰嗦。然而,其核心思想?yún)s非常簡(jiǎn)單:從表達(dá)過(guò)程,轉(zhuǎn)向表達(dá)對(duì)象。人類(lèi)的思維中,對(duì)象、或物體,是一個(gè)個(gè)具備自己的信息特征的個(gè)體,而行為和過(guò)程,往往是依附于這些個(gè)體的。比如鳥(niǎo)會(huì)飛、賬號(hào)會(huì)鎖定、汽車(chē)會(huì)死火等等。所以如果我們的代碼,是以表達(dá)對(duì)象,把信息和行為統(tǒng)一起來(lái),是最接近于我們的認(rèn)識(shí)規(guī)律的。
在互聯(lián)網(wǎng)開(kāi)發(fā)領(lǐng)域,由于網(wǎng)絡(luò)無(wú)處不在,涉及到的領(lǐng)域異常廣泛,如果我們沒(méi)有一個(gè)能把代碼世界和現(xiàn)實(shí)世界聯(lián)系的紐帶,我們的項(xiàng)目將非常難以理解。——難以理解的項(xiàng)目,就難以變化,從而就失去了互聯(lián)網(wǎng)最顯著的特征。所以我認(rèn)為,面向?qū)ο蟮乃枷耄敲恳粋€(gè)互聯(lián)網(wǎng)開(kāi)發(fā)人員都應(yīng)該理解的,并且應(yīng)該是面對(duì)大部分業(yè)務(wù)時(shí),首先考慮選擇的。
代碼架構(gòu)與重構(gòu)我見(jiàn)過(guò)無(wú)數(shù)的代碼架構(gòu)圖,里面畫(huà)滿了進(jìn)程和服務(wù)器的拓?fù)洌鞣N線條上標(biāo)注了通訊協(xié)議,編碼格式,還有各種流程圖和協(xié)作圖,然而,這些架構(gòu)設(shè)計(jì),無(wú)一例外的對(duì)于需求變更毫無(wú)幫助。因?yàn)樗鼈兠枋龅氖且环N現(xiàn)狀,甚至連現(xiàn)狀都不是,只是一種猜測(cè),一種關(guān)于現(xiàn)狀的猜測(cè)。隨著項(xiàng)目代碼的不斷變化,代碼數(shù)量和關(guān)系都會(huì)膨脹,這種進(jìn)程、通訊級(jí)別的結(jié)構(gòu),除了越來(lái)越復(fù)雜以外,根本對(duì)于指導(dǎo)項(xiàng)目如何應(yīng)對(duì)各種“代碼腐化”毫無(wú)用處。
因此我們想到了流行的“重構(gòu)”,然而,如果我們只是重構(gòu)進(jìn)程的關(guān)系,通信的層次,那些錯(cuò)綜復(fù)雜的代碼調(diào)用關(guān)系一樣存在。各種回調(diào)、事件、耦合還是讓代碼無(wú)法理解。我們只是在試圖把混亂塞到一些瓶子里面,并沒(méi)有解決混亂本身。所以,我們需要的另外一個(gè)思想武器:代碼結(jié)構(gòu)。只有我們從另外一個(gè)角度,另外一個(gè)視圖去觀察代碼,才能把握代碼之間耦合的情況。正如建筑里的平面圖和立面圖,都是不可或缺的。
所以我們應(yīng)該高度重視“代碼架構(gòu)”,也就是描述代碼之間的關(guān)系的架構(gòu),而不是進(jìn)程之間的關(guān)系的架構(gòu)。在關(guān)注代碼互相調(diào)用、耦合的關(guān)系上,我們能把混亂復(fù)雜的代碼關(guān)系理清,整理出一個(gè)便于理解,便于修改的代碼外觀。這些工作看起來(lái)完全是針對(duì)開(kāi)發(fā)人員的,但是實(shí)際上,這些工作是能提高整個(gè)開(kāi)發(fā)效率的。它能讓代碼從難以修改,變得容易修改,從而得以支持快速的業(yè)務(wù)需求變化,這是對(duì)業(yè)務(wù)、對(duì)產(chǎn)品最重要的支持能力。
持續(xù)集成的意義和實(shí)踐不管是敏捷開(kāi)發(fā)的快速迭代,還是重構(gòu)系統(tǒng),我們都將頻繁的編譯代碼、部署、測(cè)試,也就是所謂的集成。如果我們的系統(tǒng)集成效率太低,那么快速的迭代可能變成慢速的迭代,重構(gòu)系統(tǒng)的頻率也會(huì)大大降低。有一些項(xiàng)目,每一次集成,都要最少經(jīng)歷兩三個(gè)小時(shí),如果不順利的話,搞一個(gè)通宵都未必能完成。“發(fā)版本”是很多程序員和運(yùn)維管理人員的常見(jiàn)加班原因。對(duì)于這個(gè)問(wèn)題,很多小型公司開(kāi)始的時(shí)候,并沒(méi)有給與足夠的重視,認(rèn)為這些事情不過(guò)是程序員或者運(yùn)維的本分工作之一,也是最日常的工作。真正得到出問(wèn)題了,才發(fā)現(xiàn)重要性。
在任何一個(gè)互聯(lián)網(wǎng)應(yīng)用業(yè)務(wù)中,我們都會(huì)需要“發(fā)版”:出新功能、修改BUG、啟動(dòng)運(yùn)營(yíng)活動(dòng)、甚至是機(jī)房搬遷。所有的這些,如果沒(méi)有一套合適的工具來(lái)保障,每次發(fā)版都會(huì)是一場(chǎng)噩夢(mèng)。所以持續(xù)集成(CI),很自然的成為互聯(lián)網(wǎng)企業(yè)中最流行的、研究最廣泛的技術(shù)之一。
所有資產(chǎn)納入版本管理持續(xù)集成的所有東西,都應(yīng)該來(lái)源于版本管理系統(tǒng)(SVN/Git)。除此之外,軟件資產(chǎn)不應(yīng)該存放在任何其他地方。版本管理系統(tǒng)應(yīng)該是開(kāi)發(fā)團(tuán)隊(duì)的保險(xiǎn)箱和金庫(kù),除了代碼以外,所有的數(shù)據(jù)文件,配置,腳本,文檔,都應(yīng)該放入這個(gè)保險(xiǎn)庫(kù)。由于版本管理系統(tǒng)可以追溯到任何一個(gè)是時(shí)間點(diǎn),這可以讓故障恢復(fù),問(wèn)題回溯有良好的支持。
關(guān)于源代碼使用版本管理系統(tǒng),已經(jīng)有很長(zhǎng)歷史了。但是互聯(lián)網(wǎng)服務(wù)中,除了代碼,還有很多其他的資源,比如圖片、數(shù)據(jù)、腳本等等。除了產(chǎn)品項(xiàng)目外,我們的很多額外系統(tǒng),比如運(yùn)維工具、產(chǎn)品文檔等等,都是需要妥善保管的,這些也都應(yīng)該存放到版本管理系統(tǒng)中。
一般現(xiàn)在的版本管理系統(tǒng),都有“分支”的功能,簡(jiǎn)單來(lái)說(shuō)就是類(lèi)似于“拷貝”了一份新的資源出來(lái),在這之上的修改,可以由我們選擇合并到其他分支或者放棄。所以SVN的常用方案,是啟動(dòng)三個(gè)類(lèi)型的分支:trunk/branch/tag,專(zhuān)門(mén)針對(duì)“測(cè)試”、“開(kāi)發(fā)”、“運(yùn)營(yíng)”。如果我們按預(yù)定的分支模型來(lái)設(shè)計(jì)版本管理系統(tǒng)的使用,那么我們的持續(xù)集成就可以很細(xì)致的選擇集成哪一個(gè)版本的內(nèi)容。
而在Git里面,每個(gè)使用者,都可以擁有自己的資源庫(kù),這對(duì)于開(kāi)發(fā)測(cè)試可以更加的靈活,但是對(duì)于使用者的要求更高一些:在不同的資源庫(kù)合并的過(guò)程中,需要更好的版本管理策略。持續(xù)集成系統(tǒng)可以自己擁有一個(gè)或者多個(gè)Git資源庫(kù),這樣他們可以完全脫離版本管理服務(wù)器來(lái)獨(dú)立運(yùn)行。
自動(dòng)化部署我們?cè)?jīng)無(wú)數(shù)次的登錄服務(wù)器,無(wú)數(shù)次的拷貝文件,無(wú)數(shù)次的修改配置,無(wú)數(shù)次的導(dǎo)入數(shù)據(jù)到數(shù)據(jù)庫(kù),無(wú)數(shù)次的……如果我們對(duì)這些重復(fù),而且容易出錯(cuò)的工作熟視無(wú)睹,我們將永遠(yuǎn)的被這些本該機(jī)器去做的事情困住。 自動(dòng)化部署,是整個(gè)持續(xù)集成工作中最重要的步驟。當(dāng)我們每次發(fā)版都要很仔細(xì)的修改很多文件的時(shí)候,我們是無(wú)法避免在某次倒霉的事故后被挨批的。只有我們能把部署工作,也用我們的開(kāi)發(fā)能力去解決,編寫(xiě)自動(dòng)部署工具之后,我們才真正的能提升部署這個(gè)事情到一個(gè)新的臺(tái)階————我們終于可不再擔(dān)心發(fā)版。
和自動(dòng)化測(cè)試一樣,自動(dòng)部署腳本,也是把一系列的技術(shù)需求,從紙面文檔+人手處理,改成用代碼實(shí)體化,并且可積累改善的方法。自動(dòng)化部署工具在開(kāi)源界也非常熱門(mén),比如jekins,還有chef等等,都是為了解決部署問(wèn)題而發(fā)明的軟件工具。也許對(duì)于你來(lái)說(shuō),自己用bash開(kāi)發(fā)一套腳本才是合乎你的品味,但是不管怎樣,一定要有這樣的工具。就算要花費(fèi)較長(zhǎng)的開(kāi)發(fā)時(shí)間,調(diào)動(dòng)項(xiàng)目開(kāi)發(fā)的程序員,一起來(lái)認(rèn)真的開(kāi)發(fā)一段時(shí)間自動(dòng)部署功能,都是非常值得的。因?yàn)閺慕褚院?,你就可以擁有一個(gè)自己的部署系統(tǒng),這個(gè)系統(tǒng)不但可以積累你的運(yùn)營(yíng)部署經(jīng)驗(yàn),還能加入很多錯(cuò)誤、故障的自動(dòng)檢查,讓你不再需要導(dǎo)出找“永遠(yuǎn)不出錯(cuò)的”運(yùn)維人員。
自動(dòng)化部署系統(tǒng)中,最核心的部分就是配置管理。擁有一個(gè)對(duì)現(xiàn)有環(huán)境資源集中管理的數(shù)據(jù)倉(cāng)庫(kù)是非常重要的。如果每個(gè)你的腳本可以識(shí)別自己所在的環(huán)境,以主動(dòng)的方式去“申請(qǐng)”自己的配置文件和安裝任務(wù),是非常好的一個(gè)模式。因?yàn)閺囊粋€(gè)節(jié)點(diǎn)主動(dòng)去分發(fā)程序,比不上多個(gè)節(jié)點(diǎn)向中心集群請(qǐng)求部署任務(wù),來(lái)的更容易穩(wěn)定。因?yàn)樵诠?jié)點(diǎn)上的部署代理程序,能更準(zhǔn)確的知道自己環(huán)境的情況,也可以做本地的測(cè)試。
自動(dòng)化集成測(cè)試前面曾經(jīng)說(shuō)過(guò),敏捷開(kāi)發(fā)非常依賴(lài)于自動(dòng)化的單元測(cè)試。實(shí)際上持續(xù)集成,也非常依賴(lài)于自動(dòng)化的集成測(cè)試。集成測(cè)試可以把自動(dòng)化部署的結(jié)果進(jìn)行檢驗(yàn),避免手工進(jìn)行反復(fù)驗(yàn)證。如果只有自動(dòng)化部署,而沒(méi)有自動(dòng)化測(cè)試,那么集成工作,其實(shí)還是非常浪費(fèi)人力的。更重要的是,我們?cè)诿看巍鞍l(fā)版本”之后,總會(huì)擔(dān)心新的修改,導(dǎo)致一些舊的功能失效。這種問(wèn)題實(shí)際上是很常見(jiàn)的,如果無(wú)法自動(dòng)化的做這種回歸性的測(cè)試,那么我們每次發(fā)版還是要忍受漫長(zhǎng)的測(cè)試工作進(jìn)度。
自動(dòng)化集成測(cè)試也有很多開(kāi)源的工具可供選擇,特別是基于B/S模式開(kāi)發(fā)的WEB程序,但如果是手機(jī)APP的項(xiàng)目,或者客戶(hù)端C/S程序(比如網(wǎng)絡(luò)游戲),對(duì)于這類(lèi)服務(wù)器系統(tǒng)的集成測(cè)試,往往需要我們自己根據(jù)業(yè)務(wù)來(lái)編寫(xiě)測(cè)試程序。對(duì)于服務(wù)器系統(tǒng)來(lái)說(shuō),一般我們針對(duì)其通信協(xié)議編寫(xiě)測(cè)試程序即可,而對(duì)于客戶(hù)端系統(tǒng),如果是GUI系統(tǒng)的,我們還可以根據(jù)GUI的內(nèi)部調(diào)度命令(安卓就有這樣的套件)來(lái)測(cè)試,但如果是類(lèi)似游戲這類(lèi)業(yè)務(wù),就只能用圖形識(shí)別技術(shù)了。
在持續(xù)集成的流程中,集成測(cè)試往往是最后一步的檢驗(yàn)關(guān)口。如果集成測(cè)試失敗,應(yīng)該給所有關(guān)注集成的人員發(fā)送警報(bào)(實(shí)際上,如果成功也應(yīng)該報(bào)告)?,F(xiàn)在企業(yè)往往會(huì)用郵件、IM、微信、短信或者別的一些東西接收這種消息。
DevOps的意義和實(shí)踐在互聯(lián)網(wǎng)企業(yè)初始的階段,運(yùn)維工作往往是服務(wù)器端開(kāi)發(fā)人員兼任的。當(dāng)我在承擔(dān)這種既是開(kāi)發(fā)又是運(yùn)維的工作時(shí),往往非常羨慕那些“開(kāi)發(fā)、運(yùn)維分離”的公司。因?yàn)樽鳛殚_(kāi)發(fā)人員,沒(méi)有三班倒的值班備份人力,往往是7X24小時(shí)的待命狀態(tài),工作壓力非常大。然而,當(dāng)我自己參與到一些真正開(kāi)發(fā)、運(yùn)維分離的項(xiàng)目的時(shí)候,卻發(fā)現(xiàn),項(xiàng)目運(yùn)營(yíng)事故中,最少有70%的事故,是由運(yùn)維的原因造成的。
除了常見(jiàn)的硬件、網(wǎng)絡(luò)故障,操作系統(tǒng)配置出錯(cuò),日志清理出問(wèn)題,部署配置搞錯(cuò),進(jìn)程不小心殺掉等等都出現(xiàn)過(guò)??磥?lái)服務(wù)器端開(kāi)發(fā)和運(yùn)維還真是難解難分,而DevOps的思想,就是為了努力解決這種矛盾。我們不應(yīng)該再把開(kāi)發(fā)和運(yùn)維對(duì)立起來(lái),而應(yīng)該認(rèn)識(shí)到,運(yùn)維是開(kāi)發(fā)的一種延續(xù),運(yùn)維的需求也是服務(wù)器端系統(tǒng)的功能需求;運(yùn)維是開(kāi)發(fā)的目地,便利的、通用的運(yùn)維工具,本身是能提高開(kāi)發(fā)效率的一種專(zhuān)業(yè)產(chǎn)品。
運(yùn)維與開(kāi)發(fā)的一體性:運(yùn)維、運(yùn)營(yíng)、QA可以把DevOps看作開(kāi)發(fā)(軟件工程)、技術(shù)運(yùn)營(yíng)和質(zhì)量保障(QA)三者的交集
一個(gè)互聯(lián)網(wǎng)軟件的上線運(yùn)營(yíng),往往是由開(kāi)發(fā)人員編寫(xiě)出來(lái),然后經(jīng)過(guò)QA人員測(cè)試,最后放在運(yùn)營(yíng)環(huán)境里進(jìn)行運(yùn)營(yíng)。這個(gè)過(guò)程并非是單向的過(guò)程,基于前文說(shuō)的,互聯(lián)網(wǎng)服務(wù)都是在反復(fù)修改迭代中完善的,所以項(xiàng)目本身,一定是由多個(gè)版本,反復(fù)在開(kāi)發(fā)、QA、運(yùn)維之間循環(huán)交接。舉例來(lái)說(shuō),一個(gè)網(wǎng)絡(luò)游戲,在第一次開(kāi)發(fā)出來(lái)后,都會(huì)經(jīng)過(guò)比較仔細(xì)的QA測(cè)試,然后通過(guò)運(yùn)維人員進(jìn)行上線部署,最后由運(yùn)營(yíng)推廣人員進(jìn)行宣傳,同時(shí)也要配合這些宣傳開(kāi)啟游戲內(nèi)部的一些功能,客服人員也會(huì)在開(kāi)始運(yùn)營(yíng)后參與進(jìn)來(lái),除了提供客戶(hù)咨詢(xún)外,抓作弊玩家和封帳號(hào)也會(huì)持續(xù)進(jìn)行。而作為開(kāi)發(fā)人員的游戲策劃,立刻會(huì)關(guān)注游戲系統(tǒng)的各種統(tǒng)計(jì)數(shù)據(jù),以期在下一個(gè)版本中改善游戲設(shè)計(jì)。這個(gè)過(guò)程,可以看到在產(chǎn)品開(kāi)發(fā)出來(lái)之后,整個(gè)團(tuán)隊(duì)幾乎都還是需要以各種方式“使用”此服務(wù)器端系統(tǒng)的。所以我們?cè)陂_(kāi)發(fā)互聯(lián)網(wǎng)服務(wù)的時(shí)候,不能僅僅面向互聯(lián)網(wǎng)上的一般用戶(hù),同時(shí)也需要考慮整個(gè)開(kāi)發(fā)團(tuán)隊(duì)的使用需求。
現(xiàn)代的互聯(lián)網(wǎng)軟件系統(tǒng)往往都帶有服務(wù)器端部分。而這些服務(wù)器程序需要7X24運(yùn)行,因此產(chǎn)生了兩類(lèi)非常明顯的需求:
運(yùn)維需求:這類(lèi)需求往往表現(xiàn)為非功能性需求,它要求服務(wù)器程序能夠適應(yīng)大規(guī)模用戶(hù)訪問(wèn)和持續(xù)穩(wěn)定運(yùn)行。
運(yùn)營(yíng)需求:這里需求通常是功能性需求,因?yàn)楫a(chǎn)品上線后,產(chǎn)品和運(yùn)營(yíng)、客服、測(cè)試人員,還需要持續(xù)不斷的使用這個(gè)系統(tǒng),和互聯(lián)網(wǎng)的海量用戶(hù)進(jìn)行互動(dòng)。
運(yùn)營(yíng):客服、活動(dòng)在互聯(lián)網(wǎng)服務(wù)中,運(yùn)營(yíng)是一個(gè)非常重要的環(huán)節(jié)??蛻?hù)除了直接使用互聯(lián)網(wǎng)軟件的功能外,背后其實(shí)往往還有大量的從業(yè)人員在通過(guò)這個(gè)軟件提供服務(wù)。
其中最常見(jiàn)的就是客服服務(wù)??头钚枰氖遣樵?xún)功能————能夠查到系統(tǒng)中特定用戶(hù)的使用數(shù)據(jù),從而協(xié)助客戶(hù)解決問(wèn)題??头牧硗庖粋€(gè)主要工作,是封帳號(hào)和封IP。現(xiàn)在互聯(lián)網(wǎng)黑色產(chǎn)業(yè)鏈非常龐大,互聯(lián)網(wǎng)企業(yè)保護(hù)自己的手段其實(shí)不多,而客服是其中一個(gè)重要的環(huán)節(jié),避免黑色產(chǎn)業(yè)侵襲自己的利益,就需要互聯(lián)網(wǎng)服務(wù)系統(tǒng)有人工干預(yù)其數(shù)據(jù)的能力。
運(yùn)營(yíng)互聯(lián)網(wǎng)服務(wù)另外一個(gè)常見(jiàn)的行為就是“活動(dòng)”,也就是開(kāi)放一些限時(shí)的服務(wù)。就和超市一樣,互聯(lián)網(wǎng)服務(wù)也要定時(shí)或不定時(shí)的加入或關(guān)閉一些特別的服務(wù)。這些工作非常細(xì)致和瑣碎,需要服務(wù)器系統(tǒng)能夠提供人工參與或者機(jī)器定時(shí)啟動(dòng)的一些功能。在《魔獸世界》這個(gè)網(wǎng)游中,大部分的活動(dòng)都是自動(dòng)的和定時(shí)的,可以從游戲里的一個(gè)日歷功能查到。而在國(guó)產(chǎn)的互聯(lián)網(wǎng)產(chǎn)品中,的很多是臨時(shí)加入,需要人工維護(hù)的,如“雙十一購(gòu)物節(jié)”這種。這些對(duì)于服務(wù)器系統(tǒng)的版本更新,功能修改,都提出了更高的要求。
因此一般我們?cè)谠O(shè)計(jì)互聯(lián)網(wǎng)服務(wù)系統(tǒng)的時(shí)候,就應(yīng)該一開(kāi)始就把運(yùn)營(yíng)需求,也作為版本目標(biāo)納入開(kāi)發(fā)計(jì)劃中。一些比較好的團(tuán)隊(duì),會(huì)抽象和總結(jié)同類(lèi)互聯(lián)網(wǎng)項(xiàng)目(比如游戲、電商類(lèi)型)在客服、運(yùn)營(yíng)活動(dòng)上的共性,形成一套標(biāo)準(zhǔn)的服務(wù)規(guī)范以及實(shí)現(xiàn)這個(gè)規(guī)范的接口。由互聯(lián)網(wǎng)服務(wù)開(kāi)發(fā)團(tuán)隊(duì)去實(shí)現(xiàn)這些規(guī)范的接口,提供功能上的支持,而另外一個(gè)運(yùn)營(yíng)開(kāi)發(fā)小組,則負(fù)責(zé)根據(jù)這個(gè)接口,開(kāi)發(fā)供運(yùn)營(yíng)團(tuán)隊(duì)人員使用的界面、內(nèi)部管理系統(tǒng)等。比如游戲的運(yùn)營(yíng)規(guī)范會(huì)要求游戲提供查詢(xún)角色區(qū)服、帳號(hào)的名字、等級(jí)等數(shù)據(jù),提供接口在游戲中發(fā)布任務(wù);電商系統(tǒng)的運(yùn)營(yíng)規(guī)范會(huì)要求網(wǎng)店提供本店銷(xiāo)售排行查詢(xún)、優(yōu)惠券折扣接口等等。
運(yùn)維:部署(虛擬機(jī))、監(jiān)控、統(tǒng)計(jì)作為非功能性的需求來(lái)說(shuō),部署需求是第一位的。頻繁的部署是互聯(lián)網(wǎng)服務(wù)快速演變的基礎(chǔ)能力。另外,互聯(lián)網(wǎng)用戶(hù)的增加(和消退)也是非常迅速的,這導(dǎo)致了我們可能需要快速的進(jìn)行服務(wù)器擴(kuò)容,或者縮容。這種情況都需要涉及到部署。所以我們?cè)陂_(kāi)發(fā)服務(wù)器系統(tǒng)的時(shí)候,部署需求是第一個(gè)需要考慮。加上如果我們希望實(shí)行持續(xù)集成,那么就更加需要重視部署的能力。作為服務(wù)器端系統(tǒng),如果被設(shè)計(jì)成帶有非常復(fù)雜的進(jìn)程種類(lèi)和進(jìn)程通訊關(guān)系的話,要做好部署就會(huì)變得更加復(fù)雜。加上可能部署的環(huán)境還不統(tǒng)一,可能出現(xiàn)的問(wèn)題就更復(fù)雜了。所以現(xiàn)在有大量的技術(shù)嘗試改善這個(gè)方面。首先被大家廣泛接受的是虛擬機(jī)技術(shù),也就是所謂云服務(wù)器(IAAS),這種技術(shù)能讓你無(wú)需直接操作硬件,不用扛機(jī)器到機(jī)房來(lái)進(jìn)行部署,是一種巨大的進(jìn)步。
而后現(xiàn)在我們有了Docker這種基于Linux容器技術(shù)的工具,這可以把服務(wù)器操作系統(tǒng)層的差異環(huán)境,都統(tǒng)一成一個(gè)個(gè)image文件,部署的時(shí)候只要運(yùn)行image文件即可。但是這些依然無(wú)法簡(jiǎn)化錯(cuò)綜復(fù)雜的服務(wù)器進(jìn)程關(guān)系,所以現(xiàn)在有了各種“隊(duì)列服務(wù)”技術(shù),比如Kafka,RabbitMQ, ActiveMQ等等,這些隊(duì)列服務(wù)把進(jìn)程間通訊簡(jiǎn)化成專(zhuān)門(mén)的服務(wù),減少了部署的復(fù)雜性。而ZooKeeper的廣泛使用,讓我們?cè)诙噙M(jìn)程間協(xié)調(diào)和監(jiān)控有了更多的手段。在具體部署工具方面,Chef這一類(lèi)軟件做了各種有益的嘗試,這些都是能讓我們優(yōu)化部署需求功能的工具。
互聯(lián)網(wǎng)服務(wù)的24X7持續(xù)服務(wù)能力,實(shí)際上會(huì)收到各種挑戰(zhàn),除了版本發(fā)布可能導(dǎo)致的問(wèn)題外,在大量機(jī)器硬件里面,硬件故障率是一個(gè)固定的比例。網(wǎng)絡(luò)抖動(dòng),機(jī)房線路故障也常常會(huì)出現(xiàn)。更容易出現(xiàn)的是異常的用戶(hù)訪問(wèn)波動(dòng):一大波用戶(hù)洶涌而來(lái),但是也有可能是DDOS攻擊。不管怎樣,你都需要隨時(shí)掌握服務(wù)器系統(tǒng)的工作狀態(tài)。這時(shí)你就需要一個(gè)監(jiān)控系統(tǒng),但如果產(chǎn)品上線才發(fā)現(xiàn)要做,那往往已經(jīng)很遲了。因?yàn)橐粋€(gè)系統(tǒng)是否有問(wèn)題,并不是簡(jiǎn)單的從內(nèi)存、CPU、網(wǎng)卡流量就能看出端倪的,我們往往需要在服務(wù)開(kāi)發(fā)之初,就定義好各種需要監(jiān)控的指標(biāo),傳統(tǒng)常見(jiàn)的指標(biāo)有:每秒主循環(huán)的次數(shù)、每秒處理業(yè)務(wù)包的次數(shù)、服務(wù)器中緩存的會(huì)話數(shù)等等……一些做的好的系統(tǒng),還會(huì)有很多業(yè)務(wù)層面的監(jiān)控指標(biāo),比如某個(gè)特定服務(wù)的處理效率、處理成功率等等。
既然一個(gè)系統(tǒng)有大量的監(jiān)控指標(biāo),就涉及如何生成和管理這些數(shù)據(jù)的問(wèn)題。傳統(tǒng)的做法是在系統(tǒng)中“埋入”這些監(jiān)控程序,系統(tǒng)一邊運(yùn)行一邊統(tǒng)計(jì)這些指標(biāo),然后定時(shí)生成日志或者通過(guò)網(wǎng)絡(luò)上報(bào)給某個(gè)監(jiān)控系統(tǒng)。但是這種做法的缺點(diǎn)是:如果你需要更多的指標(biāo),或者修改指標(biāo)的統(tǒng)計(jì)方法,你就被迫要修改代碼,重啟服務(wù),這樣會(huì)影響正在運(yùn)行的服務(wù)?,F(xiàn)在另外一個(gè)做法是,由系統(tǒng)把運(yùn)行的原始信息記錄成日志,然后把日志集中上報(bào)到一個(gè)監(jiān)控系統(tǒng)中,這個(gè)監(jiān)控系統(tǒng)一般都帶有分布式的文件存儲(chǔ)系統(tǒng)和分布式計(jì)算統(tǒng)計(jì)能力。在搜集到大量實(shí)時(shí)日志的同時(shí),這個(gè)系統(tǒng)根據(jù)預(yù)設(shè)的指標(biāo)統(tǒng)計(jì)方法,不停的進(jìn)行日志統(tǒng)計(jì),一旦發(fā)現(xiàn)統(tǒng)計(jì)結(jié)果有問(wèn)題,就會(huì)報(bào)警。而這種統(tǒng)計(jì)由于是在大數(shù)據(jù)處理能力的平臺(tái)上生成的,所以往往發(fā)現(xiàn)問(wèn)題的時(shí)間差能縮小到分鐘級(jí)甚至秒級(jí)。這種做法由于搜集的是原始日志記錄,所以就可以靈活的在系統(tǒng)運(yùn)行時(shí)定制很多統(tǒng)計(jì)和報(bào)警的策略,但完全不會(huì)增加服務(wù)系統(tǒng)的壓力,也不需要修改服務(wù)系統(tǒng)的代碼。
最后說(shuō)說(shuō)統(tǒng)計(jì),任何一個(gè)互聯(lián)網(wǎng)系統(tǒng),都是在用戶(hù)的使用中不斷優(yōu)化的,這個(gè)優(yōu)化的依據(jù),最重要的客觀依據(jù),就是統(tǒng)計(jì)數(shù)據(jù)。而統(tǒng)計(jì)數(shù)據(jù),一般由兩部分構(gòu)成:
用戶(hù)的行為數(shù)據(jù)。比如登錄行為,就可以給系統(tǒng)留下用戶(hù)的IP、登錄時(shí)間、登出時(shí)間等數(shù)據(jù);購(gòu)買(mǎi)行為,就可以留下購(gòu)買(mǎi)商品,購(gòu)買(mǎi)價(jià)格,購(gòu)買(mǎi)時(shí)間這些數(shù)據(jù)。
根據(jù)用戶(hù)的行為的關(guān)聯(lián),統(tǒng)計(jì)出來(lái)的數(shù)據(jù)。比如根據(jù)登錄行為,我們可以統(tǒng)計(jì)出用戶(hù)的在線時(shí)長(zhǎng),用戶(hù)重復(fù)登錄的次數(shù),用戶(hù)重復(fù)登錄的間隔,還有什么次日存留、七天存留等等……;根據(jù)購(gòu)買(mǎi)行為,我們更是可以整理出用戶(hù)的購(gòu)買(mǎi)商品傾向,ARPU值,甚至同類(lèi)用戶(hù)的購(gòu)買(mǎi)共性,這些也是所謂大數(shù)據(jù)做商品統(tǒng)計(jì)的主要方向。
根據(jù)上面的分析,我們可以發(fā)現(xiàn),實(shí)際上統(tǒng)計(jì)系統(tǒng)也是應(yīng)該分兩個(gè)部分設(shè)計(jì),一個(gè)是盡量記錄用戶(hù)行為的基礎(chǔ)數(shù)據(jù),第二個(gè)是以復(fù)雜多變的統(tǒng)計(jì)條件,去挖掘這些用戶(hù)行為數(shù)據(jù)中包含的規(guī)律。對(duì)于第一部分,一個(gè)可以存放海量日志數(shù)據(jù)的分布式存儲(chǔ)系統(tǒng)非常重要;對(duì)于第二部分,分布式的統(tǒng)計(jì)運(yùn)算系統(tǒng)是必不可少的。對(duì)于這個(gè)體系,Google的Hadoop提供了業(yè)界的示范。但是如果你愿意,也可以使用這個(gè)思路自己來(lái)建設(shè)自己的統(tǒng)計(jì)系統(tǒng),也許你的數(shù)據(jù)量無(wú)需要用到Hadoop那么復(fù)雜。
總結(jié)互聯(lián)網(wǎng)開(kāi)發(fā)模式,是針對(duì)于互聯(lián)網(wǎng)本質(zhì)上是一個(gè)“服務(wù)”而發(fā)展起來(lái)的。因?yàn)槭恰胺?wù)”而不是產(chǎn)品,所以應(yīng)對(duì)快速變化的能力是最高的技術(shù)標(biāo)準(zhǔn)。我們傾向采用更適合表達(dá)需求的軟件開(kāi)發(fā)技術(shù)、自動(dòng)化程度更高的開(kāi)發(fā)工具,來(lái)提高我們的開(kāi)發(fā)效率,而不是靠單純的“激勵(lì)主觀能動(dòng)性”來(lái)做管理。
因此我們?cè)诨谧詣?dòng)化測(cè)試、自動(dòng)化部署等持續(xù)集成工具的平臺(tái)上,使用重視原型迭代的方法來(lái)開(kāi)發(fā)項(xiàng)目,在反復(fù)以原型確認(rèn)需求,以及適應(yīng)需求變化的過(guò)程中,逐步的完善整個(gè)開(kāi)發(fā)生產(chǎn)線。并且把開(kāi)發(fā)和運(yùn)營(yíng)視為一個(gè)整體,在服務(wù)的運(yùn)營(yíng)過(guò)程中,不斷的完善互聯(lián)網(wǎng)服務(wù)的運(yùn)營(yíng)工具,讓開(kāi)發(fā)和運(yùn)營(yíng)在同一個(gè)生命周期里生長(zhǎng)。
此文已由作者授權(quán)騰訊云+社區(qū)在各渠道發(fā)布
獲取更多新鮮技術(shù)干貨,可以關(guān)注我們騰訊云技術(shù)社區(qū)-云加社區(qū)官方號(hào)及知乎機(jī)構(gòu)號(hào)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/100909.html
摘要:阿里巴巴的共享服務(wù)理念以及企業(yè)級(jí)互聯(lián)網(wǎng)架構(gòu)建設(shè)的思路,給這些企業(yè)帶來(lái)了不少新的思路,這也是我最終決定寫(xiě)這本書(shū)的最主要原因。盡在雙阿里巴巴技術(shù)演進(jìn)與超越是迄今唯一由阿里巴巴集團(tuán)官方出品全面闡述雙八年以來(lái)在技術(shù)和商業(yè)上演進(jìn)和創(chuàng)新歷程的書(shū)籍。 showImg(https://segmentfault.com/img/remote/1460000015386860); 1、大型網(wǎng)站技術(shù)架構(gòu):核...
摘要:架構(gòu)設(shè)計(jì)實(shí)體化單元測(cè)試敏捷開(kāi)發(fā)講究要快速的修改代碼,我們往往會(huì)發(fā)現(xiàn),代碼修改的越頻繁,越多,這似乎是一個(gè)無(wú)法解決的矛盾。 本文由云+社區(qū)發(fā)表,作者:韓偉 互聯(lián)網(wǎng)開(kāi)發(fā)的核心問(wèn)題 當(dāng)我1999年進(jìn)入互聯(lián)網(wǎng)行業(yè)工作的時(shí)候,華為剛剛通過(guò)了著名的CMM認(rèn)證。當(dāng)時(shí)作為一個(gè)小程序員,非常向往業(yè)界經(jīng)典的軟件開(kāi)發(fā)模式。因?yàn)榭瓷先ィ绻髽I(yè)實(shí)行了CMM,我們程序員就不用再天天為了老板一個(gè)拍腦袋的主意而加班...
摘要:鑒于目前大多數(shù)服務(wù)器環(huán)境都是,提前接觸能夠相輔相成。正則也是必須要掌握的一個(gè)知識(shí)點(diǎn)。有多種創(chuàng)建多線程的方式,不過(guò)目前使用線程池的多一些。 原創(chuàng):小姐姐味道(微信公眾號(hào)ID:xjjdog),歡迎分享,轉(zhuǎn)載請(qǐng)保留出處。 你可能有所感悟。零散的資料讀了很多,但是很難有提升。到處是干貨,但是并沒(méi)什么用,簡(jiǎn)單來(lái)說(shuō)就是缺乏系統(tǒng)化。另外,噪音太多,雷同的框架一大把,我不至于全都要去學(xué)了吧。 這里,我...
2020年發(fā)生的眾多事件讓對(duì)2021年的大多數(shù)預(yù)測(cè)浮出水面。人工智能(AI)和物聯(lián)網(wǎng)(IoT)等熱門(mén)技術(shù)趨勢(shì)仍將在明年重塑我們生活的方式。然而,最重要的用處是幫助我們?cè)谶@個(gè)不斷變化的時(shí)代下適應(yīng)和生存。沒(méi)有什么趨勢(shì)比云計(jì)算更重要。云是數(shù)據(jù)驅(qū)動(dòng)、基于應(yīng)用程序的技術(shù)生態(tài)系統(tǒng)的支柱,在幫助我們管理這種變化方面起著至關(guān)重要的作用。云服務(wù)徹底改變了從聯(lián)系人追蹤到家庭遞送服務(wù)、遠(yuǎn)程醫(yī)療和遠(yuǎn)程辦公以及娛樂(lè)的一切。...
閱讀 3208·2021-09-30 09:48
閱讀 3485·2021-09-22 16:00
閱讀 1062·2019-08-30 13:08
閱讀 3098·2019-08-30 10:53
閱讀 2410·2019-08-29 18:33
閱讀 1583·2019-08-29 12:47
閱讀 896·2019-08-29 12:16
閱讀 1929·2019-08-26 12:02