帶團隊後的日常思考(六)

咖啡機(K.F.J)發表於2021-11-30

一、日常問題

1)MySQL歸檔

  當前我們組管理著一套稽核系統,除了資料來源是服務端提供的,其餘後臺管理都是由我們組在維護。

  這個系統就是將APP中的各類社交資訊送到後臺,然後有專門的稽核人員來判斷資訊是否合規,當然在送到後臺之前已經讓機器稽核了一遍。

  在去年8月份上線後,日積月累,有張資料表變得比較龐大,截止到目前將近5800W條,資料容量31.21G,每條記錄大概是582B。

  由於資料量龐大,在檢索時也將模糊查詢撤掉,並且為了便於查詢,還加了很多索引,目前的索引容量都達到了12.2G,稽核人員也經常反饋系統使用起來很卡。

  在瞭解到他們的訴求後,我們也展開了優化方案。首先想到的分表,第一種橫向分表,也就是將資料以日或月為單位,目前一天的量在20W條左右,一個月的話在600W條左右。

  但是這麼分的話,在維護上就比較複雜,例如查詢時,假設正好遇到跨天或跨月的條件,那麼資料組織就比較繁瑣了。

  第二種分表是利用MySQL的語法:分割槽表,就是讓MySQL來做分表這個粗活,對我們這些使用者來說該怎麼查還是怎麼查。

  但是有網友說,隨著資料量的增加,分割槽表也會有效能問題,具體達到多少量會有顯著的效能問題,我沒有深入研究,但是量上去了,總歸還是會有點問題的。

  分表的方案就這麼廢棄了,然後想到將資料同步到 ElasticSearch 中,這樣的話,檢索就毫無壓力了,不過資料是需要頻繁的更新的,不知道會不會影響ES的效能。

  並且改造成本也是巨大的,要改動很多地方,而目前最緊缺的就是人力資源了,即使我們花大力氣改造好了,當前測試組也抽不出人手做質量保障。

  匆忙上線勢必會影響稽核人員的使用,雖然系統有這個那個的小毛病,但至少還能穩定的在執行中,也就作罷了。

  在仔細思考後,又想到了另一個改造成本最小的方案:MySQL歸檔。所謂歸檔就是將大表中的一組資料遷移到另一張表中。

  與稽核人員一對一溝通後,瞭解到,其實他們會用到的資料也就是半個月內的,半個月之前的資料很少會用到。

  也就是說表中存在很明顯地冷熱資料,並且冷資料被操作的概率非常低,幾乎不會訪問。

  那我只要每天將這部分冷資料遷移出去,就能保障稽核記錄表的容量,也就能避免效能問題。

2)壓力測試

  運營最近想發50W的推送,推廣一個匿名聊天的功能,那麼就得提前做一輪壓力測試,好知道這個功能承受多少的使用者量。

  壓測的任務交給了QA去完成,自己對此也蠻在意的,所以也瞭解了一下壓測的流程,找到了JMeter這個工具。

  搗鼓了半天,才發現我本機使用JMeter只能開啟4000個執行緒,這遠遠無法滿足壓測需求,又去尋找方案,才找到了JMeter的分散式測試。

  這個過程跌宕起伏,我特地做了一個記錄。QA既用此軟體,還使用了websocket-bench,用程式碼來模擬訪問。

  在用JMeter開啟1.2W個執行緒1分鐘內訪問頁面後,生成了一組報告,資訊非常多,我認得的就是錯誤率,發現並不多,還有很多響應時間、TPS等資料。

  詳細的分析我還不是很專業,後續我得去系統的學習一下效能測試的方方面面。

  以當前的結果看,情況不是很糟,但是那個閾值還沒找到,得讓QA幫忙找下了。

  其實我在檢視伺服器的一些引數的時候,就發現很多值都達到了百萬,例如檔案開啟數,QA通過WIKI也發現了之前的壓測記錄,這說明之前也做過此類測試。

3)版本迭代的疑惑

  每次APP的版本迭代從開發到提審都要持續一個月以上,我本來以為是因為需求太多導致的,但和產品溝通後,發現原因並沒這麼簡單。

  確切的說應該是多方面的,這裡就從產品的角度來說說其中的一個緣由。

  公司在一個版本提測後,就會抽時間開個初審會議,說明下一個版本的需求。

  而產品的初衷是希望給開發更多的時間來理解需求,評估需求的合理性、開發時間以及技術細節。

  理想很豐滿,現實很骨感。讓開發邊修BUG,邊思考需求,實際操作中並沒有同步。

  開發並不會提前閱讀產品需求,只會在確定要開始做的時候才看。這就會導致一個問題。

  那就是做到某一個需求,發現自己的理解與產品不同,然後開始討論補救方案,打補丁,因為如果做了很多功能,不能一下子全砍了。

  這樣一來一回就會浪費很多不必要的時間,降低開發效率,雙方還會鬧的有點不愉快。

  其實之前在我們組內推行了設計方案,可以很大程度的規避需求理解和技術細節的問題。

  但在我們組內還沒出現令人信服的資料和案例,所以現在推廣也不太現實。

  之前和服務端的同學溝通過,他說他很多時候並不是在做需求,而是將很多時間花在修線上BUG上了,祖傳程式碼坑很多。

  並且有些邏輯都無人維護了,一旦出問題,就要除錯半天,這應該也是影響開發進度的一個原因。

  我個人感覺每次將這些功能除錯完後,就該留下點文件記錄,無論是技術細節還是業務細節,都可以留存,下次再遇到就能遊刃有餘了。

4)關聯功能的遺漏

  對於那些有時間範圍的活動,不會有這個問題。

  而對於那些長期維護的功能,就會有這個隱患,因為這些功能互相之間相互關聯,而當前沒有很好的方式來表明他們之間的關係。

  雖然沒有牽一髮而動全身這麼誇張,但是動區域性還是很有可能的,最近就遇到幾個這樣的坑。

  服務端對支付改版,新增了一張訂單表,售後服務關聯的是老表,沒有人知道要適配新表,直到客服上報問題才發現。

  推薦管理增加中英繁語言欄位,在改完後,運營使用時發現有個標籤欄位無法顯示了,開發排查發現是提交旁邊有個定時任務的按鈕,其中的邏輯沒有更新,導致問題發生。大家都不知道原來還有這個玩意兒,包括QA也沒注意到。

  這類問題,該如何預防,目前只能被動的接收業務人員的反饋,主動出擊的問題是沒有目標和參考資料,難以劃定受影響的範圍。

  若是畫一張巨大的關係圖,我又擔心維護成本巨大,沒有那麼多資源來支撐。

  雖然這個不行那個不行,但是若是遇到了這個業務的問題,那麼就有必要針對此業務將邊邊角角的流程梳理乾淨。

  例如售後服務,就拉上產品、財務和客服一起開個會議,在和她們溝通後,就發現她們的日常操作和我們預期的並不同。

  於是讓她們記錄當前流程,在此基礎上做針對性的適配優化。

5)資料庫優化

  最近幾天,從週六開始,管理後臺在早上9點至10點會發生掛起,每次客服就會找到我。

  週末也無法細看,只能重發程式碼臨時解決,本來以為只是個偶發現象,沒想到並不是。

  過了幾天頻發,引起了我們的注意,運維也查到有段時間的伺服器CPU異常,突然飆升。

  經過曲折的探索後,定位到一些SQL語句查詢非常慢,阻塞了資料庫處理。

  執行 EXPLAIN 命令,發現命中的是一個時間索引,影響的行數要300多萬條。

  而那個時間限制是特定時期才需要的,現在只是個冗餘條件,完全可以移除,移除後,查詢效率飆升。

  MySQL為什麼會選錯索引,這裡面蠻有學問的,得學學索引的執行原理,一句兩句講不清。

  順便說一句,最近還對MongoDB中的一張表也加了個時間索引,表的資料量有3億多條。

  未加索引之前,查詢幾條記錄要十幾分鍾,加了索引後,可以在幾毫秒中得到結果。

二、工作優化

1)推廣單元測試

  其實在很早之前就已經在組內分享過單元測試的種種好處。

  並且在當前使用的程式碼結構中,已經整合了單元測試的框架,包括 mocha.js、chai.js 和 sinon.js,並且附加了多種場景下的測試用例。

  組內成員只要根據自己的實際情況,編寫測試用例即可,但使用率仍舊不是很理想,分析下來可能是以下幾個問題導致的。

  首先就是團隊成員會質疑單元測試的價值,需要給出證明單元測試確實有效可行的方法和證據。

  其次是團隊成員缺乏主動測試的意識,目前有大量的測試程式碼,不知道從哪裡開始測試,並且花費額外的精力來維護單元測試的程式碼。

  還有就是編寫單元測試大概會花費日常開發的 10% 以上的時間,而專案時間總是比較緊,無法留出充裕的測試時間。

  最近自己工作的重點是專案的質量保障,想了一下後,覺得有必要再次將單元測試提到議程,特地做了些準備,根據兩本單元測試的書籍編寫了一篇簡易的教程,希望能降低單元測試的門檻。

2)Code Review再議

  我們團隊在遇到重要活動時會做Code Review,雖然頻率不高,每次執行的時間也就半小時左右,但效果顯著。

  我們Code Review時的氣氛非常和諧,大家並不是為了找茬而來的,都是為了找出其中的程式碼或設計缺陷而來的。

  我們不會拘泥於註釋、空格個數等細節,主要還是專注於業務理解和邏輯思路。

  大家坐在一張桌子上,將自己的程式碼展示出來,訴說自己的思路和想法,有時候就會發現協作的兩人在介面使用或某個引數含義上發生了偏差。

  一旦發現就能當場或會後及時修正,以免在測試,甚至線上出事故時才發現,既節省了時間,也避免了公司損失。

  對於某段程式碼寫的過於繁瑣或抽象不夠時,大家也會提出自己的改進意見,從而就能做到互相進步。

  在會議中,有時候也會發現頁面的效能問題,例如有個活動在初始化時呼叫了一個內部邏輯過於複雜的介面,其實完全可以將其拆成兩個介面。

  這樣就能快速渲染頁面整個結構,避免白屏時間過長。

  其實還有很多好處,大家只要帶著目的去嘗試一下,就會發現新大陸的。

3)前端崗位的三點思考

  如果你覺得我的理解有偏差,歡迎評論區留言。

  • 前端離使用者最近

  使用者在瀏覽網站時,最先看到的就是頁面,從這個層面來說,前端的確離使用者最近。

  但使用者瀏覽網站是有目的地,可能是閱讀文字資訊,也可能是購物,還可能是提交表單等等。

  這些資料就全部轉移給了後端,讓後端來處理,而此時,後端才是離使用者最近的。

  前端從某種意義上來說,只是做了一層橋接,為使用者和後端提供了一座溝通的橋樑。

  由於使用者看到的都是介面,那麼一旦有問題,首先聯絡的也將是前端。

  此時前端將會排查問題,當查到後端問題,前端再轉移問題到他們名下,日常工作中,前端經常要做這些瑣碎的事情。

  • 前端涉足很廣的領域

  前端的觸手已經伸到了客戶端(Flutter、React Native等)、服務端(Node.js)和桌面端(Electron),可以說無所不能。

  但也僅僅是伸到而已,大部分情況下,是難以有機會實踐的。

  一個原因是術業有專攻,客戶端和服務端到底在他們各自領域會來的專業點。

  第二個原因是公司資源,大部分公司不會讓一個人做這麼多事情,都是會分工的,做太多反而不精,容易誤事。

  前端這麼多年發展下來,其實主要的工作仍然是表現和互動,工作形式以頁面製作為主。小程式也是頁面,只是執行環境不同。

  現代的製作方法也越來越講究,越來越科學,例如流行的React、Vue基於元件的開發思路,還有各種工程化利器,在提效的同時,也提升了程式設計體驗。

  我還記得當年被IE6支配的黑暗年代,做什麼創新都得為IE6多準備一套相容方案,工作量都耗在了IE6的適配上。

  • 前端能幫助大家做的更好

  之前說到前端涉及了非常廣的領域,如果想著替代那些崗位,其實意義不大,職責分工還是蠻科學的。

  我感覺可以融合現有的這些技術,創造出能幫助解決業務痛點或提升工作效率的工具。

  例如測些不太懂redis命令,那麼就做套視覺化的快取介面供他們操作,節省測試時間。

  還例如運營活動比較常規,那將共性抽象出來,做成一套可配置化的系統,只要輸入些引數,就能實現他們所需的功能,壓縮開發週期。

  網上還看到有些團隊的前端做了一套報表系統,供產品和運營檢視,解放了服務端的生產力。

  前端被賦予了很多能力,發揮想象,可以做的事情還有很多,不用侷限於那一畝三分地。

相關文章