1. 程式人生 > >帶團隊後的日常

帶團隊後的日常

一、日常工作

1)開會

  由於公司規模並不大,因此一有事情就會拉個會議,例如需要大會、技術評審、彙報週會、突發會議等。一週中大概有20%~30%的時間會花在大大小小的會議上。

  公司會議難免會出現接鍋的情況,雖然自己不想做鍋靖,但是有些邊界定義比較模糊的鍋(既可以給後端,也可以給前端),在時間允許的時候,都會自己接下,因為服務端資源很有限,日常雜活太多,大家打工人都不容易。

  雖然比較費時,但會讓自己有更多的參與感。公司辦公都是用mac pro最新款,攜帶也比較方便,開會的時候帶個筆記本,也可以在會議中處理一些工作的事情。

  在團隊成員來齊後,每週五的10點,自己還會組織一個團隊短會,一般控制在30分鐘內。不是工作彙報,而是:

  1. 回顧一下本週遇到的難點或費時的事情,若還未解決,可在會議上當場討論思路。避免下次碰到又要花費太多精力。
  2. 發表一下自己這周遇到的困惑,無論是技術還是公司,都可以隨意發表。互相瞭解一下團隊成員的想法。
  3. 我也會傳達一些公司資訊,例如本週或下週的重點任務、公司的新政策等,及時與團隊成員同步。
  4. 若有時間還會做個簡短的 Code Review,或者做技術分享,無論是當前前沿技術,或者是經典案例,都行。

2)任務分配

  目前公司兩條產品線,加上我是3個人,他們各自負責一條線。若一些需求沒時間做的時候,我也會幫忙寫。

  並且與組內成員要保持任務資訊的同步,大家都得清楚現在做什麼,未來還有哪些活需要處理。

  新同學剛來沒多久,還在適應期,給他的任務都不是緊急的。當抽不出人手時,也會讓他搞,不過我和另一個同學也會協助他。

  當有緊急需求時,我會將優先順序不高的任務延後,並安排給合適的人處理。

  自己除了開會之外,也要寫程式碼,一些難弄麻煩費時的功能都留給了自己,例如那些跨團隊的、或是測試環境不容易部署的功能。

  每天也會關注一下組員的進度,遇到問題可以幫忙出解決方案或應對策略,以免卡在一個地方,既影響心情,也影響開發進度。

3)錯誤除錯

  我們Web小組不僅維護著一個龐大的後臺管理系統(前後臺都做),還參與過許多後端服務(例如定時任務、金額結算)、H5活動頁面、微信公眾號、小程式等。

  因此,很多時候線上出問題,都會與我們組有關。經常是某個人找到我,向我反饋問題,嚴重的話我就得停下手中工作,立刻去拍錯。

  我花了很多時間去做各種錯誤除錯,並且經常會出現跨團隊的場景,而我排錯的過程一般是幾步:

  1. 頁面樣式出錯,那毫無疑問是我們組的問題,除非那人看錯了,將客戶端的頁面報到了我們這邊。
  2. 若是呼叫的介面問題(所有的前端介面都會通過Node服務做一層中轉),那麼會將介面路徑拿到VS Code中做一次專案搜尋,檢視程式碼邏輯。
  3. 若內部核心邏輯是呼叫服務端內部介面,那麼就需要將問題反饋給他們,再做聯調和定位是誰的問題。
  4. 若介面中的邏輯沒有呼叫內部介面,都是直接操作資料庫的,那麼就要查詢資料庫寫入的邏輯。若沒有,那麼就去找誰在維護這張表。

  之前就遇到過一個問題,說是後臺的一張重要的統計報表沒資料了。查了半天,發現是一個定時任務在做寫入,而在這個定時任務中又會涉及MongoDB的寫入、客戶端的上報、第三方平臺和服務端的讀取。在一一排除後,最終發現是服務端在寫入其中一個數據源時,日期寫的不對(由於時區的問題)。斷斷續續花了4天的時間,期間與運維、客戶端、伺服器、測試還有第三方平臺的技術人員先後做過溝通,這種排錯很費成本。

  後面又遇到一個問題,也是與後臺有關,說是一張統計表看不到了。這次也是先查寫入的程式碼,發現沒有,馬上與服務端聯絡,他們那邊也沒有。於是就找到測試組,因為他們組目前是公司內最瞭解整個管理系統的人,果然找對了人,他就說是AI演算法組在維護的。找到他們之後,才查出是他們的一個定時任務掛了,怪不得沒有資料。之後在週會上,我就提出讓他們統計出自己維護的資料庫表,並且是那些與我們組相關的資料庫中的表。

4)完善文件

  先前的 WIKI 已有部分文件,但內容非常分散,不成體系,我花了點時間重新梳理,並整理到合適的位置。

  書寫之前沒有的文件,尤其是現在比較重要的業務或功能,完善業務流程,甚至將相關的 SQL 查詢語句都整理了出來,方便除錯。

  邀請其他組的成員幫忙書寫相關的文件,例如讓客戶端組完善 JSBridge 文件,而測試組是目前掌握最多業務細節的人,讓他們幫忙寫些發生突發情況或意外故障的處理過程。

二、工作優化

  日常的工作除了做業務需求(俗稱寫BUG)之外,其實就是發現問題,再解決問題,有時間的話,找出合理的優化手段,避免重複踩坑。

1)MongoDB視覺化介面

  若要查詢MySQL,可以藉助DMS視覺化介面。但要查詢MongoDB,那麼只能先連上跳板機,然後再通過跳板機進入MongoDB伺服器,這一來一回經常要耗上點時間。

  因此,後面就著手自己寫了一個簡易的視覺化介面,只提供查詢功能。Node程式碼中的ORM系統採用的是Mongoose庫,那麼就從其find()方法著手。

  介面中需要傳入一個Model名稱,多行文字中只要傳入 where 條件即可,語法參考的是 db.collection.find(),下圖灰色使用了 <pre> 標籤,為了能在頁面中顯示空行和換行。

  

  在後臺管理系統中,原先有個查詢redis的介面,但只查了一個庫,資料型別也只列了4種,後面將庫修改為可配,並且新增了一個數據型別。

  從而就能避免通過跳板機來讀取redis中的快取,可直接在頁面中查詢。

  指令碼檔案的執行,原先除了上傳程式碼之外,還得進入伺服器中,手動輸入命令執行。

  這麼操作略微繁瑣,自己做了點加工,做成半自動,程式碼還是要發,不過在後臺管理系統中有個按鈕,點選後就能執行指定的指令碼,下面是執行介面,呼叫了 fork() 方法。

router.get('/scripts/exec', async (ctx) => {
    const path = require('path');
    const { fork } = require('child_process');
    const exactPath = path.resolve(__dirname, 'scripts/index.js');
    fork(exactPath);
    ctx.body = { code: 0 };
});

 

2)微信公眾號配置封裝

  呼叫微信公眾號的JS-SDK之前,都是需要先引入配置檔案的。先前的做法是先在前端腳請求一個介面,響應得到timestamp、noncestr和signature等引數。

  然後呼叫wx.config()進行配置,最後在wx.ready()呼叫微信的onMenuShareTimeline()、onMenuShareAppMessage()等方法。

    const wx = require("weixin-js-sdk");
    const wxUrl = encodeURIComponent(location.href.split("#")[0]);
    getWeixin(wxUrl).then((e) => {
      wx.config({
        // debug: true,
        appId: "wx....",           // 必填,公眾號的唯一標識
        timestamp: e.timestamp,       // 必填,生成簽名的時間戳
        nonceStr: e.noncestr,        // 必填,生成簽名的隨機串
        signature: e.signature,       // 必填,簽名
        jsApiList: [
          "onMenuShareTimeline",
          "onMenuShareAppMessage",
        ], 
      });
    });
    wx.ready(function () {
      wx.onMenuShareTimeline({
        title: "",
        desc: "",
        link: "",
        imgUrl: "",
        success: function () {},
      });
      wx.onMenuShareAppMessage({
        title: "",
        desc: "",
        link: "",
        imgUrl: "",
        success: function () {},
      });
    });

  一旦需要用到微信JS-SDK就要呼叫這麼一坨,但其實這些可以都放到服務端去執行。

  後面我將上述配置封裝到後端的一個router方法中,路由成一個JS檔案(例如bridge.js),前端只要呼叫它,然後傳遞一些引數做一些簡單的變數宣告即可,完全不需要配置appid、signature等引數。

3)後臺管理系統介面優化

  後臺管理系統都會包含左邊的選單欄,剛接手的時候,每次頁面重新整理,選單欄預設就會閉合,不會展開當前URL路徑所處的選單。

  在除錯的時候,改一下指令碼就會自動重新整理視窗,一重新整理選單就會閉合,導致我要換旁邊的選單時,又要一步步的點選。

  於是就著手開始優化,在檢視程式碼時發現,選單資料被抽象成了多叉樹結構,而選中某個頁面的選單,其實就是用深度優先演算法來匹配指定路徑,下面用程式碼簡單的實現了這個功能。

  //深度優先 搜尋當前選單
  let defaultSelectedKeys = [],   //預設選中的選單
    defaultOpenKeys = [],         //預設需要展開的選單路徑
    isFind = false;
  const dfs = (node, keys) => {
    keys.push(node.id);
    if(node.routers == props.path) {
      isFind = true;
      defaultSelectedKeys.push(node.id);  
      defaultOpenKeys = keys;
      return;
    }
    node.children && node.children.forEach(value => {
      if(isFind)
        return;
      dfs(value, [...keys]);
    });
  };
  dfs(menuTree[0], []);

  其實演算法離我們平時的業務並不遠,只要用心發現就能挖掘出各類演算法。

4)釋出系統問題

  公司買了第三方平臺的一套釋出系統服務,每次釋出時,都會比較耗時,卡在某一步,少則7、8分鐘,多則10幾、20多分鐘。

  向運維也反饋過很多次,但每次都沒有找到針對性的解決辦法。

  最後無奈,只得和運維商量,在測試環境,自己寫個檔案傳輸工具,直接把build後的程式碼傳到指定目錄,跳過釋出系統。

  畢竟測試環境要經常發程式碼,老這麼延遲,實在是會讓人困擾。運維的意思是他們提供指令碼,我們在跳板機上執行指令碼,實現檔案傳輸。

  雖然沒有一鍵傳輸方便,但聊勝於無,總比干等好,同意了這個方案,後續跟進。

  期間還碰到了另一個棘手的問題,那就是測試和正式環境的Node版本過低,比當前穩定版本低了6個版本。

  這就導致很多庫不能直接安裝,得另想辦法或者用該庫比較老的版本。

  現在也不能立馬更新,一更新就出錯,測試也沒有額外的資源幫忙一起除錯。時間與資源的矛盾暫時還不能妥善解決。

5)效能分析日誌

  公司購買了阿里雲的日誌服務,之前幾個純前端的專案雖然開通了日誌服務,但並沒有妥善使用起來。

  這次正好想到可以開通阿里雲的WebTracking的採集功能,將效能引數推送到阿里雲日誌伺服器中,引數蒐集的庫採用了之前自己封裝的pineapple.js。

<head>
  <title>效能引數demo</title>
  <meta charset="utf-8">
  <script>
    window.pineapple || (pineapple = {});
    pineapple.param = {
      "token": "a0b923820dcc509a"
    };
  </script>
  <script src="pineapple.js"></script>
</head>

  在引數蒐集好後,就能借助阿里雲強大的查詢分析功能,分析頁面效能了,目前還沒想好分析維度。