問題
最近做的工作痢虹,似乎沒有太大難度武氓,以至于讓我在技術(shù)方面有些迷茫梯皿。而且,基于阿里的平臺县恕,很多技術(shù)方面的事情變得很容易东羹。有時甚至可以輕輕松松地搭建起一個分布式應(yīng)用,能支撐起RT在5ms以內(nèi)忠烛,QPS在10w以上的訪問属提。
另外一個問題是,有很多框架美尸,各種層出不窮的新東西冤议,學(xué)也學(xué)不盡。那么师坎,怎么才能算是掌握核心技術(shù)呢恕酸?
回顧
首先回顧一下最近半年內(nèi)的技術(shù)經(jīng)歷。
去年9月中旬胯陋,轉(zhuǎn)崗到另一個部門蕊温。從Python技術(shù)轉(zhuǎn)到Java方向袱箱,一切都是新奇的。
校招時本打算找Java方面的工作义矛,但一直以來沒有Java方面的項目經(jīng)驗犯眠,而對Java的了解也就只在Leetcode上刷題和基本的語法方面,于是直接被阿里刷掉了症革。后來找到了Python方向的工作筐咧,但也擔心Python以后的發(fā)展,甚至因為這個事情給一些比較有名的Python工程師發(fā)過郵件咨詢噪矛。其中一位這么給我說:
首先不要想著自己是一個Python工程師量蕊,應(yīng)該想著自己是一個后端工程師,然后才是Python工程師艇挨。
覺得他說的在理残炮,對以后用Python做主力語言也不是那么抗拒了。但9月份因為一些不可抗力因素要轉(zhuǎn)崗缩滨,原以為也是Python势就,不過轉(zhuǎn)崗面試時都問的是Java,然后我基礎(chǔ)還可以脉漏,于是就這么轉(zhuǎn)到新部門苞冯,技術(shù)也切到了Java方向。
1. 遷移
最開始接觸的是一個后臺系統(tǒng)侧巨,Mentor說是前不久離職的兩個同事留下來的項目舅锄,以后就交我維護。那是第一個真正接觸的Spring MVC項目司忱。之前我用的是Python的Django/Flask/Tornado框架皇忿,雖然也聽說過Spring MVC,但很是嫌棄Java框架一直以來笨重的xml配置(相比Django/Ruby On Rails/Grails那種慣例優(yōu)于配置的輕便易用)坦仍。但是鳍烁,既然上了Java的賊船,就不能不用Spring MVC繁扎,可等我在本地把那個系統(tǒng)用Tomcat運行起來幔荒,一個更重要的項目開始了。
之前離職的同事還負責另外一個項目锻离,就是數(shù)據(jù)入庫系統(tǒng)铺峭,而這些從任務(wù)分配上來講都該由我接手识樱。同時榴嗅,因為大項目的需要,我們這個系統(tǒng)要遷移到另外一個平臺上缆巧,于是我就開始了這段近四個月的遷移歷程虱朵。
如圖莉炉,算法組在HDFS文件系統(tǒng)中儲算法數(shù)據(jù)钓账,這些數(shù)據(jù)需要存入Hbase/Redis/Memcache中,提供給線上服務(wù)使用絮宁。大項目將算法遷移到了ODPS平臺(阿里的OLAP平臺梆暮,學(xué)堂在線上有專門對這個進行介紹),也將數(shù)據(jù)存儲到了ODPS上绍昂,但是我們的服務(wù)還是要從Hbase/Redis/Memcache里取數(shù)據(jù)啦粹,這需要我們把數(shù)據(jù)由ODPS上存到具體的數(shù)據(jù)庫中。
1.1 插件攻城獅
集團有自己的異構(gòu)數(shù)據(jù)傳輸工具Datax(該工具在Github上已經(jīng)開源)窘游,可以將數(shù)據(jù)在各種不同的數(shù)據(jù)庫之間進行傳輸唠椭。該工具采用插件的方式使用,例如我需要向Hbase寫數(shù)據(jù)忍饰,則必須向Datax提供Hbase的寫插件贪嫂。集團的Datax已經(jīng)默認提供了Hbase1.1和Hbase0.94的寫插件,但是但是艾蓝,我們的Hbase是0.98版本的力崇,經(jīng)過測試發(fā)現(xiàn)不兼容。另外赢织,Datax沒有Redis和Memcache插件亮靴。本來,這個事情由另一團隊負責支持我們敌厘,但由于各種原因台猴,最后他們提供了Redis的寫插件,我們則自己開發(fā)了Hbase0.98和Memcache的寫插件俱两。
插件的開發(fā)過程是不連續(xù)的,跟大項目的推進進度有關(guān)曹步,需得算法提供ODPS上已經(jīng)就緒了的數(shù)據(jù)宪彩,我才可以遷移。最開始給我的是入Hbase的數(shù)據(jù)讲婚,但是Datax上Hbase能用的插件版本跟我們的Hbase不匹配尿孔。如果不解決這個問題,我們根本遷移不了筹麸。最終我們決定自己開發(fā)Datax的Hbase0.98版本寫插件活合。
開發(fā)插件這個事情應(yīng)該是我主動要求來做的,因為當時數(shù)據(jù)已經(jīng)有了物赶,然而我卻入不了Hbase白指,心里比較著急。不記得當時是否跟組長說過這個事情我來做酵紫,反正我主動去看了下Hbase0.94的代碼告嘲,查看了Datax插件的開發(fā)文檔错维,又去網(wǎng)上查了下0.94和0.98的區(qū)別,擼起袖子就開干橄唬。其實0.98的主要是底層依賴的庫與0.94的代碼不一樣赋焕,其他層面只需要對0.94的代碼做些改動即可,而1.1版本的區(qū)別就大了仰楚,這也是我選擇0.94來參考的原因隆判。這時也是我第一次接觸Java的構(gòu)建工具Maven。
代碼改好之后僧界,讓部署的同學(xué)幫忙部署蜜氨。然而,測試的時候遇到了一個奇怪的錯誤:有個方法找不到捎泻。由于在Java上比較沒有經(jīng)驗飒炎,死活沒找出來是啥問題,就去尋找Mentor的幫助笆豁。他看了一下錯誤信息郎汪,然后弄了個jd-gui的小工具,將那Hbase和Hadoop的依賴包反編譯了下闯狱,在里面發(fā)現(xiàn)找不到的那個方法存在煞赢,但是沒有符合那個參數(shù)的。當時我也不明白這是啥問題---那個錯誤的異常我沒完全看懂哄孤,因為參數(shù)的部分是我從沒見過的信息照筑,當時Mentor又找了好久,可能他有其他方面的懷疑瘦陈,反正我沒看懂凝危。
夜晚回家的路上就想,如果這個方法這個包里面沒有晨逝,那么很有可能是依賴的包不對蛾默,正確的包應(yīng)該在哪呢?要被遷移的入庫任務(wù)也是用Java從HDFS上讀數(shù)據(jù)寫入Hbase捉貌,那么那些代碼里面肯定有支鸡。第二天我去了,然后就看了那個pom文件趁窃,把開發(fā)的插件的依賴的Hadoop版本給換掉了牧挣,再一部署測試,沒問題了!
特別感謝我的Mentor醒陆,他幫我很多瀑构,要不是他我也不曉得可能是依賴包出了問題。這個事情讓我覺得Java的依賴有時候會出現(xiàn)很大的問題统求,做好依賴管理可能就是開發(fā)Java程序時比較重要的一環(huán)检碗,也是讓人感覺超級蛋疼的一環(huán)据块。
Hbase0.98就這么開發(fā)出來了,感覺我組長還有整個大項目的負責人都比較開心折剃,后者還專門找我問了一下這個插件的情況另假。這也是我第一次真正用Java做個東西出來。
接下來我受到了鼓勵怕犁,覺得開發(fā)這個插件也不是很難嘛边篮,決定自己做Redis的寫插件開發(fā)。我先調(diào)研了原先那個入庫代碼里面對Redis的寫入情況以及對應(yīng)的API奏甫,然后花了一個周末的時間把東西開發(fā)出來戈轿,并且測試、部署都沒問題阵子。但是周一上班的時候思杯,我把這事情告訴組長,他說Redis插件和Memcache插件就另一個團隊來開發(fā)挠进,就不用我的了色乾。話說,當時確實有點沮喪...
后來就跟另一個團隊的開發(fā)同事溝通Redis寫插件的需求問題领突,由他來給我們提供Redis寫插件暖璧,但我負責在我們的環(huán)境中測試他的插件。他是一個很好哥們君旦,哈哈澎办,和他合作很愉快,雖然這個插件不用我的了金砍,可我也沒啥話可說局蚀。
但是在Memcache寫插件的測試過程中出了點問題。由于他提供的是在Datax的另一個插件的基礎(chǔ)上修改的插件捞魁,底層依賴的是spymemcached包至会,而我們這邊用的是xmemcached包……最開始我也不知道我們用的是這個,后來看了代碼才知道谱俭,但這時候他已經(jīng)結(jié)束了Memcache插件的開發(fā)。他的插件也可以使用宵蛀,但是效率低的出奇---我得開1000個線程才能滿足傳輸速率昆著。當時就想,很可能就是兩邊的依賴的庫不一樣導(dǎo)致的术陶。然后一個周末的下午和夜晚凑懂,我用了大概8個小時,開發(fā)出基于xmemcached包的Memcache寫插件梧宫,那天我還記得接谨,最后是學(xué)校自習(xí)室的保安把我趕走了摆碉,因為待的太晚……
第二天部署測試,效率杠杠的:傳輸速率提高了100多倍脓豪,花費時間減少了100多倍巷帝。后來我們就果斷采用我這個插件了。
當然扫夜,開發(fā)還是很開心的楞泼,尤其是做了比較有用的事情,這使我們這個遷移項目推進的速度加快了笤闯,且風(fēng)險降低了堕阔。
這里面還有其他故事。由于其他組的業(yè)務(wù)需要颗味,我還給他們開發(fā)了Redis讀插件超陆。另外,還有一個其他部門的高級工程師浦马,經(jīng)常找我咨詢Hbase的事情时呀,因為他負責他們部門的數(shù)據(jù)遷移,而Hbase標準插件不滿足他的需求捐韩,然后就找我來幫他開發(fā)退唠。當然,我們也有自己的需求荤胁,后來我給Hbase0.98寫插件增加了一些功能瞧预,例如支持動態(tài)列,支持列名可空仅政」赣停可能是幫他太多了,那哥們說要請我吃飯圆丹,哈哈滩愁,我是那么好意思的人嗎?果斷說他太客氣了辫封,不需要請吃飯的硝枉。而且那陣子經(jīng)常收到來自杭州的電話,因為有一個部門需要Hbase0.98的讀插件倦微,需要我支持……然后花了點時間給他們寫了個讀的∑尬叮現(xiàn)在還在做他們的支持,因為動不動就找我欣福。
這事情讓我感覺還是很好玩责球,一是開發(fā)比較開心,另外被需要會讓人感覺自己很重要,我也會有這種迷之虛幻感雏逾,哈哈嘉裤。不過最重要的是讓我感覺到,我終于在Java方面邁出了第一步栖博。
1.2 簡陋的入庫系統(tǒng)
在上面這個架構(gòu)圖上屑宠,三臺入庫機里面的入庫任務(wù)和調(diào)度,都是用shell寫的笛匙。話說我當時看到這個很簡陋的入庫系統(tǒng)時侨把,真想要把它拆了重寫才好,至少要弄個Web界面妹孙,配置什么的直接在界面上操作秋柄,而不需要每次都要登錄入庫機,修改xml配置文件---那么長的配置文件蠢正,蛋疼啊骇笔。不過我們的全部入庫任務(wù)都會遷移到集團的調(diào)度平臺,重寫也沒啥用處嚣崭。于是遷移過程中我一直在梳理這些入庫Shell的流程笨触,然后把業(yè)務(wù)邏輯遷移到集團的調(diào)度平臺(D2)上。
這個系統(tǒng)主要承擔以下幾方面的功能:
- 創(chuàng)建新的入庫任務(wù):主要是通過增加xml配置文件雹舀、Shell任務(wù)文件芦劣、Crontab執(zhí)行項實現(xiàn)
- 調(diào)度任務(wù):執(zhí)行時檢查HDSF上的數(shù)據(jù)是否存在,如果不存在則等待數(shù)據(jù)说榆,按照一定的等待時間重試虚吟;且如果機器上的資源不足,則等待再執(zhí)行
- 報警:入庫失敗則給相關(guān)負責人員發(fā)郵件
那么這些是怎么實現(xiàn)的呢签财?
首先crontab里面會設(shè)定某個入庫任務(wù)的執(zhí)行時間串慰,以及對應(yīng)的shell腳本。然后shell腳本里面會有檢查HDFS文件是否存在的邏輯唱蒸,有等待邏輯邦鲫,還有失敗發(fā)送郵件的邏輯,但最關(guān)鍵的是給出了入庫的Java的執(zhí)行命令及參數(shù)---這兒會依賴一個jar包神汹,該包里面實現(xiàn)具體的入庫邏輯庆捺。另外,還需要配置xml文件屁魏。Java代碼會讀取xml文件里面配置的executor疼燥,producer、processor和output蚁堤。executor包含producer、processor和output三個參數(shù),它表示一個完整的入庫處理流程披诗。producer表示產(chǎn)生數(shù)據(jù)撬即,這個數(shù)據(jù)可能是HDFS上的數(shù)據(jù),也可能是本地數(shù)據(jù)呈队。processor表示處理過程剥槐,可能把數(shù)據(jù)轉(zhuǎn)換成一定的格式,也可能不做處理宪摧。output則是將數(shù)據(jù)入到某個數(shù)據(jù)庫中粒竖,可能是Hbase的入庫代碼,也可能是Redis或者Memcache几于。
xml文件中需要為每個任務(wù)需要配置一個executor蕊苗,一個executor里面需要配置好producer、processor和output沿彭。比較好的是依賴的jar包里面已經(jīng)把相關(guān)的代碼寫了朽砰,很少需要更新jar包---除非有了新的需求,比如更改了數(shù)據(jù)格式喉刘,這就要增加processor的處理類瞧柔,在該類里面實現(xiàn)具體的數(shù)據(jù)格式處理。整個老入庫系統(tǒng)維護過程中睦裳,我只處理了一次這樣的需求造锅,升級了一次jar包,這說明這個jar包的代碼寫的還是比較有擴展性的廉邑。
這個系統(tǒng)的問題在于以下幾個方面:
- 每個任務(wù)都要增加shell文件哥蔚、xml中的executor配置,時間久了鬓催,shell文件會非常多肺素,xml長的非常長,crontab也會非常長
- 沒有機器的資源使用監(jiān)控宇驾,有一次有個算法同事改了代碼倍靡,不知道哪里寫錯了,開了三萬個線程并且不關(guān)閉课舍,其他任務(wù)沒資源執(zhí)行塌西,且因為沒有資源,也沒有給我們發(fā)報警郵件筝尾,還是API調(diào)用部分發(fā)現(xiàn)沒數(shù)據(jù)我們才發(fā)現(xiàn)這個問題……
- 手工操作太多捡需,有一次修改xml,文件格式弄錯了筹淫,最后弄的很多入庫任務(wù)都入庫失敗……
其實這只需要一個管理系統(tǒng)而已站辉。如果這個系統(tǒng)沒有遷移,我會做如下開發(fā):
- 任務(wù)腳本改用Python,不用shell饰剥,shell可讀性弱殊霞,且Python還有很多庫可以使用
- 任務(wù)腳本根據(jù)配置自動生成
- 配置改用MySQL管理,開發(fā)Web界面
- 增加機器資源監(jiān)控
- 支持增加機器及指定機器執(zhí)行汰蓉,之前系統(tǒng)的3臺機器是隨著任務(wù)的增多一臺臺增加的
- 再往后面就是往分布式調(diào)度方面開發(fā)了
哈哈绷蹲,都是我的假想,并沒有做這樣的一個東西顾孽。但是遷移到D2平臺已經(jīng)基本滿足的這樣的需求祝钢,但D2也有一點不好,每次整體上的一點小變化若厚,都要修改成百上千個任務(wù)節(jié)點拦英,沒有批量改的操作接口,真是累啊盹沈。在維護這些任務(wù)的過程中龄章,我改過好幾次每次上百個文件的任務(wù)節(jié)點配置。這讓我體會到乞封,工作上的有很多事情都是重復(fù)性的做裙,沒有開發(fā)創(chuàng)造那么有意思。
1.3 MR的虛幻感
這個遷移項目還有后面一步關(guān)鍵肃晚,就是數(shù)據(jù)轉(zhuǎn)換锚贱。
這是原始的入庫流程。當算法的數(shù)據(jù)遷移到ODPS上了之后关串,我們即使有了Datax和對應(yīng)的寫插件拧廊,也還存在一個巨大的問題,就是數(shù)據(jù)處理過程晋修。API從Hbase/Memcache/Redis取得的數(shù)據(jù)都是有一定的格式吧碾,而算法給的數(shù)據(jù)卻是原始的數(shù)據(jù)。同時墓卦,ODPS支持通過SQL對其之中的數(shù)據(jù)進行查詢倦春,也支持通過MapReduce對其進行處理。于是我們遷移之后的流程就成了這樣:
于是我遷移過程就變成了:
- 在入庫的Java程序中尋找每一個shell任務(wù)對應(yīng)的executor和它的具體配置落剪,然后查看processor配置的類里面的具體處理方法
- 根據(jù)1中的處理方法睁本,改寫成MapReduce,在ODPS上處理
嗯忠怖,總共179個入庫任務(wù)呢堰,雖然遷移過程中砍掉了一些,最終也有上百個凡泣。另外枉疼,ODPS的MapReduce感覺是給Hadoop的MapReduce增加了一層包裝皮假,所以寫法略有不同。
當然往衷,這個過程中并不是MapReduce有多難寫钞翔,而是梳理Shell的處理流程,查找數(shù)據(jù)Parser的方法席舍,才是特別耗費心力的。感覺就是苦力勞動吧哮笆。其中一個shell文件寫的特別復(fù)雜来颤,我只好打印出來從紙上看,總計有6頁代碼稠肘。
Hadoop的MapReduce在研究生時代就寫過福铅,并且用實驗室的機器搭建過Hadoop集群。另外项阴,研究生畢業(yè)設(shè)計是用Spark來做推薦系統(tǒng)的數(shù)據(jù)處理滑黔,里面寫Map/Reduce真是簡單的都不知道怎么說好了,沒有對比就沒有傷害环揽。
由于是使用MapReduce略荡,這讓我有一種“MapReduce也就是這樣子啊,也沒剛出來的時候那么高大上”的感覺歉胶。我想可能是寫那種簡單的處理寫疲憊了……
其實Hadoop的HDFS/MapReduce的細節(jié)汛兜,包括設(shè)計,都是非常值得研究的通今,可惜現(xiàn)在沒時間去做這個了粥谬。也不止這個,因為我們的數(shù)據(jù)存儲主要是使用Hbase辫塌,這三樣正好對應(yīng)Google的那三篇論文漏策,這可就不只是值得去好好研究的了,而是一定要去研究的臼氨。且待我有時間掺喻。
1.4 總結(jié)
花了四個月的時間,磕磕碰碰一也,從無到有巢寡,總算是獨自把這個遷移任務(wù)完成。感謝我的Mentor和我的組長椰苟,是他們在我遇到問題的時候給我提供信息抑月,幫我理清思路,建議并指導(dǎo)我怎么去處理舆蝴。這一個過程中感覺真的收獲了不少谦絮,讓我有了一定的Java開發(fā)經(jīng)驗题诵。但這個過程中同樣暴露了我在Java技術(shù)方面的短板,即項目經(jīng)驗太少层皱,需要掌握的東西很多性锭,有時候處理的思路也有偏移,而且對于底層有點霧里看花的感覺---可能是寫的不夠多吧叫胖。這四個月中草冈,大致做了這么些事情:
- 開發(fā)Datax插件、自己測試瓮增,并給需要的同學(xué)提供相關(guān)服務(wù)怎棱,包括Datax的使用方法
- 梳理舊的入庫系統(tǒng)邏輯,改造成MapReduce
- D2平臺上創(chuàng)建任務(wù)绷跑,包括入庫拳恋、MR處理等
- 推動算法組同學(xué)提供ODPS上的相關(guān)數(shù)據(jù)(因為這個事情阻塞不少時間)
2. 后臺維護
2.1 管理系統(tǒng)遷移
年后過來,接受了三個后臺管理系統(tǒng)往集團平臺上遷移的任務(wù)砸捏,Mentor協(xié)助我谬运。這三個系統(tǒng)都是之前同事來維護的,順理成章垦藏,這些也該由我來遷移梆暖。其中Mentor幫我遷移了一個,自個兒完成了剩下的兩個膝藕。這三個系統(tǒng)都是由Spring MVC寫的式廷,于是這次我才有功夫接觸一點Spring MVC方面的知識。遷移的關(guān)鍵點在于:
- 將原有的系統(tǒng)前端和后端合并成一個應(yīng)用
- 后臺數(shù)據(jù)庫的切換芭挽,web.xml中修改MySQL的配置
- 舊MySQL數(shù)據(jù)同步到集團的MySQL平臺中(idb4)
- 接入SSO替換原有的CAS系統(tǒng)滑废,修改原有的權(quán)限邏輯
- 集成平臺(Aone)部署測試
這個過程中,遇到了一些問題袜爪,但是都被解決了蠕趁,也對Spring MVC的整個項目的構(gòu)造以及容器、注解辛馆、AOP和配置有所了解了俺陋。如果現(xiàn)在讓我寫一個CURD的Spring MVC項目,我想應(yīng)該沒多大難度昙篙。但總感覺不踏實腊状,因為我沒有把這個東西掌握到我十分熟悉的那種地步。
2.2 審核系統(tǒng)
遷移過程中審核系統(tǒng)變得無法使用苔可,主要是算法那邊沒有提供審核信息缴挖。于是我們幾個相關(guān)環(huán)節(jié)的負責人把審核流程通了一遍。
如上圖所示焚辅,整個流程就是數(shù)據(jù)通過ODPS入到MySQL映屋,審核人員通過Web界面審核數(shù)據(jù)苟鸯,把修改存入到MySQL中,然后定時將全量的MySQL審核數(shù)據(jù)同步到ODPS上棚点,最后生成的審核數(shù)據(jù)早处,會被算法用于過濾。這樣瘫析,同事提供了數(shù)據(jù)砌梆,我配置好了相關(guān)的Datax任務(wù),整個系統(tǒng)就運行起來了颁股。這里面流程雖然簡單么库,但是各方面都要通知到,尤其是使用最后的數(shù)據(jù)的同學(xué)甘有。
2.3 用戶變身
用戶變身是為了給算法測試提供的一個功能,實際上就是在小結(jié)UID替換器的實現(xiàn)里面介紹的功能葡缰。
本身功能是對特定用戶的ID進行替換亏掀,如果請求中帶有我們定義的ID,則替換成我們定義的該ID的替換ID泛释,推薦算法根據(jù)替換后的ID計算出推薦結(jié)果滤愕。這實際上就起到了用戶變身的效果。
功能要求:
- 要有管理界面怜校,能對我們要替換的ID和最終替換成的ID進行管理间影,一個這樣的映射對定為一個規(guī)則
- 要能停止和啟用某個規(guī)則
- 要能使修改后的規(guī)則立即在線上起作用,也就是要添加這樣的一個按鈕:使規(guī)則生效
如上圖所示茄茁,在管理后臺修改了規(guī)則之后魂贬,可以點擊使規(guī)則生效按鈕。這個按鈕會調(diào)用線上API的每臺機器的同一個接口裙顽,也就是圖中的刷新接口付燥。刷新接口又會調(diào)用管理系統(tǒng)的數(shù)據(jù)接口(HTTP),加載所有啟用了的規(guī)則信息到線上API中的一個全局HashMap中愈犹。線上的請求打過來的時候键科,會根據(jù)請求中的ID在HashMap中做匹配,如果匹配上了漩怎,則替換掉勋颖,如果沒有,則略過勋锤。
這是我用到的第一個規(guī)范的使用MySQL數(shù)據(jù)影響高訪問量API的設(shè)計饭玲。如果不這樣做,而是每次請求進行MySQL查詢怪得,再替換咱枉,則MySQL肯定會掛卑硫。 之所以能這么設(shè)計,是因為少量的過濾數(shù)據(jù)是可以加載到內(nèi)存中蚕断,而且使用HTTP協(xié)議加載數(shù)據(jù)欢伏,實現(xiàn)了兩個系統(tǒng)之間的松耦合。
這個功能是獨自參考系統(tǒng)原有的黑名單功能做出來的亿乳,前前后后硝拧,包括寫管理系統(tǒng)、修改線上API葛假、測試部署等花了近5天障陶。當然,代碼本身寫的不多聊训,但在項目的哪個地方寫抱究,該寫哪些東西才是花時間比較多的。
3. 實時跟蹤系統(tǒng)
實時跟蹤系統(tǒng)是大系統(tǒng)架構(gòu)換新的一個關(guān)鍵服務(wù)带斑,已經(jīng)由另一個團隊的同事們寫好鼓寺,交由我們使用,且當前由我負責勋磕。這個系統(tǒng)里面用了集團的很多產(chǎn)品妈候,好在開源界有很多替換方案,此處就用開源方案給出設(shè)計圖:
系統(tǒng)本身功能是對用戶的點擊挂滓、瀏覽記錄進行跟蹤苦银,跟蹤數(shù)據(jù)要實時提供給算法使用。點擊等日志會通過Kafka的發(fā)布和訂閱服務(wù)赶站,傳遞給我們的實時跟蹤系統(tǒng)幔虏。實時跟蹤系統(tǒng)中取得日志中的數(shù)據(jù),解析某些關(guān)鍵數(shù)據(jù)亲怠,存儲到Redis集群中---Redis中的數(shù)據(jù)量十分大所计,預(yù)估是5T左右。同時团秽,實時跟蹤系統(tǒng)通過Dubbo分布式服務(wù)框架提供RPC服務(wù)接口主胧,返回Redis集群中存儲的數(shù)據(jù)。
通過RPC服務(wù)使用Redis數(shù)據(jù)的消費者是算法組的同學(xué)习勤,他們使用用戶的實時數(shù)據(jù)進行推薦踪栋。這個系統(tǒng)對性能要求比較高,要求RPC調(diào)用數(shù)據(jù)響應(yīng)時間在5ms以內(nèi)图毕,并且支持7w每秒的QPS夷都。
這個服務(wù)運行的還不錯,但很快就接到了新的需求:日志結(jié)構(gòu)更改和提供HTTP的數(shù)據(jù)訪問接口予颤。
日志結(jié)構(gòu)更改就是通過Kafka訂閱的日志結(jié)構(gòu)跟之前的不一樣囤官,需要重新寫解析方法---當然我是看了源代碼之后才知道要改解析方法冬阳。提供HTTP接口的原因是RPC服務(wù)在算法平臺上可能無法使用。
大概花了兩天半的時間完成了這個任務(wù)党饮。當然肝陪,最開始還是有點慌張的,因為對這個東西一無所知刑顺,僅僅知道它叫“實時跟蹤系統(tǒng)”氯窍,用了RPC服務(wù)框架(因為是Java菜鳥,RPC服務(wù)本身原理我沒深入研究過蹲堂,僅僅知道這個是做什么的)狼讨。但我答應(yīng)了組長三天之內(nèi)把這個東西修改好,部署并測試柒竞,還要跑成功政供。所謂的跑成功就是在我們的APP上有點擊瀏覽記錄,我能通過RPC服務(wù)和HTTP服務(wù)看到我的點擊足跡朽基。
其實看了代碼之后就有了思路鲫骗。但是對于集團的一些產(chǎn)品不熟悉(設(shè)計圖中給的全部是開源的產(chǎn)品,集團內(nèi)部用的不是這些踩晶,另外還有些開關(guān)和限流服務(wù),都是第一次接觸)枕磁,以及測試完全是在生產(chǎn)環(huán)境下的渡蜻,抓包找自己的設(shè)備的ID花了很長時間。好在比較快速地完成了這個任務(wù)计济,當時給組長說已經(jīng)沒問題了時茸苇,他說:好,非常好沦寂。
這個服務(wù)的代碼不是我寫的学密,但是寫的不錯,接下來我會把它的代碼再仔細看一遍传藏。但我感覺到腻暮,這個用8臺機器運行的應(yīng)用,并有5臺機器的緩存(類Redis)集群毯侦,在集團提供了好用的平臺的情況下哭靖,增加功能和維護變得容易,但也屏蔽了我對具體架構(gòu)的了解和學(xué)習(xí)侈离。就像這種感覺:如果一件事變得容易试幽,那么肯定是有其他東西幫助你做好了很多事情。這也會造成對這個平臺更加依賴卦碾。
思考
經(jīng)歷回顧帶來了什么
- 讓我知道自己為什么會有一種虛的感覺
- 代碼寫的不多铺坞。沒有一次完整的開發(fā)整個項目的經(jīng)驗起宽,基本零敲碎打,而自己也沒有總結(jié)一些代碼的良好的框架設(shè)計济榨。但是坯沪,在大型的項目中,基本上每個人都負責一部分模塊的開發(fā)腿短,要一個人完全把所有功能做好屏箍,也不太現(xiàn)實。
- 同時橘忱,好的平臺赴魁,讓人可以專注于業(yè)務(wù)開發(fā),但也屏蔽了對更深層技術(shù)的感知钝诚。這是好事還是壞事呢颖御?如果有一天,需要從零開始搭建一個基礎(chǔ)平臺凝颇,只會業(yè)務(wù)代碼潘拱,能Hold住嗎?
- 讓我知道過去的半年內(nèi)到底做了哪些東西
以上的工作歷程,本質(zhì)上是干活和學(xué)習(xí)結(jié)合在一起的。這樣的學(xué)習(xí)是有幫助的涨薪,比如后臺系統(tǒng)中的一個處理我把它用在實時跟蹤系統(tǒng)的改造中了抽诉。同時,這個總結(jié)也讓我梳理了一下在Java技術(shù)方向半年以來做了哪些事情。當然,這些事情有些有價值,有些不一定有價值川无,但對我來說也是比較重要的成長經(jīng)歷,對自己的技術(shù)經(jīng)歷要清晰虑乖。
- 讓我開始去思考接下來要處理哪些事情
什么是項目經(jīng)驗
- 開發(fā)經(jīng)驗
- 維護和擴展經(jīng)驗
什么是核心技術(shù)
接下來該怎么做