老舊項目二次開髮指南

来源:https://www.cnblogs.com/maogy/archive/2022/04/15/16147663.html
-Advertisement-
Play Games

老舊項目二次開髮指南 背景: 最近新入職公司,負責技術。由於各種原因現在項目全權交由我們團隊負責,之前的研發團隊不再參與(及以後可能完全聯繫不上)。作為技術負責人,又剛入職公司壓力巨大。經過兩個多月的改造,算是接手得還算行。該項目存在的問題比較典型,特此記錄。歡迎各位大佬批評指教。技術能力有限,文中 ...


老舊項目二次開髮指南

背景:
最近新入職公司,負責技術。由於各種原因現在項目全權交由我們團隊負責,之前的研發團隊不再參與(及以後可能完全聯繫不上)。作為技術負責人,又剛入職公司壓力巨大。經過兩個多月的改造,算是接手得還算行。該項目存在的問題比較典型,特此記錄。歡迎各位大佬批評指教。技術能力有限,文中所說解決方案(思路)只代表筆者的愚見。

1 老項目存在的問題

  • 項目採用的主要技術:

    後端: spring-boot+dubbo+redis+mybatis+oracle+jeager+apollo+flyway

    前段: node+react

1.1 架構層面

1.1.1 微服務並不微

多個服務的代碼量遠超許多單體服務;

1.1.2 依賴代碼不受控制

技術框架二次封裝:由於spring框架提供的便利性,上個團隊應該是出於對技術規範的考慮,對整個項目所使用的技術框架進行了二次封裝,技術框架做了封裝;
依賴第三方團隊代碼:項目中存在對三方非開源代碼的依賴;

1.1.3 開源項目版本老舊

項目框架老舊,項目框架被二次封裝,導致依賴的項目主體技術版本老舊,不能及時更新。

1.1.4 沒有事務(包含分散式事務)

單體服務事務:使用不規範,部分CUD操作甚至沒有開啟事務;
分散式事務:雖然項目框架中有引入seata事務解決分散式事務,但可能是代碼先行框架後用,代碼中存在大量複雜SQL,導致seata不能使用。

1.1.5 缺少主要服務

沒有字典服務,字典服務、用戶信息服務、許可權服務為同一個服務(暫且叫做“主數據服務”)沒有分離;
需要說明下
    字典服務:指維護字典數據的服務,及簡單的key-value數據,例如:性別(1:男,2:女),民族(1:漢,2:滿,3,蒙古...)。
    用戶信息服務:指維護用戶信息的服務;
    許可權服務:指用戶許可權信息的維護,設計各個子服務操作許可權,菜單許可權的單獨維護。
    服務是否需要如此拆分,各個業務場景不同,需慎重考慮。只是筆者評估目前接手的項目適合如此拆分。

1.1.6 網關服務定位混亂

 後端沒有統一的網關服務,每個服務單獨校驗用戶登錄信息,前段node服務只做了介面轉發並沒有承擔應有的大前端工作。

1.2 資料庫層面

1.2.1 未分庫分表

未分庫:整個工程四百多張表全部創建在同一個用戶下;
未分表:用戶基本信息表,欄位上百,存在大量非常用欄位;

1.2.2 依賴資料庫

使用觸發器
使用自定義函數
使用存儲過程

1.3 緩存層面(主要說明redis緩存)

1.3.1 使用不同的序列化方式

項目中沒有使用統一的序列化方式

1.3.2 沒有充分使用數據類型(只使用String類型)

例如用戶基本信息,直接序列化成jSON字元串存儲,而不是使用hash,導致當需要使用用戶信息中的某個欄位時得全部取出用戶信息,無端增加IO。

1.4. 性能層面

1.4.1 存在迴圈使用調用資料庫的情況而沒有使用批量操作(List,batch)

數據CUD等操作時,沒有使用批量操作執行器,而是for迴圈獲取SQL拼接(並不是說SQL拼接等操作性能就一定查,這裡只說明部分數據量大的情況下更推薦使用批量執行器來操作);
同一個數據迴圈跨服務調用,舉例說明:
    例如,“A應用服務”的某一個數據A_data保存著“用戶ID”,現在需要在頁面展示A應用的A_data數據,此時肯定需要把用戶名字也展示出來。對於該業務就存在返回數據給前端時,需要調用主數據獲取“用戶ID”對應的“用戶信息"。
    就這樣的一個應用場景。如果是返回一個A_data列表數據給前端,則應該是先獲取所有的用戶ID列表,再通過用戶ID列表去獲取所有需要的用戶數據。可實際代碼中大量地方是使用的迴圈調用,這無疑是一個巨大的性能損耗。

1.4.2 返回大集合對象

就介面請求的數據返回不夠精細,往往存在一個返回數據再多個地方使用,而消費端卻僅僅只需要使用少量欄位。

1.4.3 存在重覆解釋欄位情況

對字典數據的解釋沒有統一放到前段處理,而是由後端解釋翻譯;
後端介面沒有隔離,存在同樣的欄位A服務解釋了之後B服務接著重覆解釋,具體距離:
A服務依賴B服務,現在前端請求A服務獲取數據,A服務調用B服務,B服務返回數據(對欄位進行瞭解釋),A服務再返回給前端之前對欄位又進行瞭解釋。

1.5 代碼規範

1.5.1 沒有使用枚舉,全部使用常量;

1.5.2 命名不規範

1.5.3 沒有註釋

1.6 項目文檔

1.6.1 沒有任何文檔

2. 對應的解決方案

優先順序確定

可以看到整個項目存在問題較多,加上研發任務也再同時進行,基於自己多年研發的直覺,對上述問題進行簡單的優先順序排序,並逐一闡述理由。

經過前面對項目中存在問題的整體梳理,對項目現狀有了比較全面的瞭解。由於研發任務同時進行,無法投入太多人力對以上問題進行全面休整,因此基於自己多年研發累積經驗對以上問題進行了簡單的優先順序排序處理。

2.1 風險規避——必須儘快解決的問題

  • 未分庫分表

    原因

      由於項目是整體交接,之前的團隊退出,新來接手的團隊對之前的項目完全不瞭解,因此為了避免項目變得更亂,資料庫分離迫在眉睫。
      因為所有子服務的表全部放到同一個用戶下麵,如果不從技術層面實現數據的分離,由於join操作的便利性,必然會產生更多的跨服務關聯查詢。
    

    技術實現

      1.通過python腳本(正則匹配)找出各個子服務中在使用的表,按照CRUD操作進行歸類;
      2.對於已經存在的多個服務同時存在CUD同一個表的情況,仔細確定表的歸宿問題;對於無法確認歸宿問題的表先保存記錄,待後續業務熟悉之後再次確認(非常感謝之前的開發者,整個項目梳理下來這樣的表也只有十幾個);
      3.將所有表都按照服務歸類之後,通過使用資料庫提供的公共同義詞,對跨服務使用的表分配對應的CRUDE許可權(除非像上文2中提到無法確認歸宿的表之後,禁止分配CUD許可權)。
    
  • 依賴代碼不受控制

    原因

      相信這一點不用多說,不受控制的東西千萬不要使用。所用一段無法控制的代碼,不知道啥時候會爆雷;當沒有利益做橋梁,很難期望別人會給予恩惠。要不被人鎖住咽喉,唯有將不穩定的因素解決。
      當然對於這樣全面的技術棧替換,測試的支持必不可少。這也是我將優先順序排到此處的原因。由於項目剛接受,剛好產品、測試都需要對項目進行全面瞭解。這樣避免到以後真的被技術鎖喉時,還需要來進行一次全方位的測試(這工作不是一般的小)。
    

    技術實現

      就框架的二次封裝而言,相對比較容易解決;把項目中使用到的技術整理出來,逐一使用開源技術替換即可;還在是對開源技術的二次封裝,大家的使用技術比較統一,項目中並沒有太多依賴二次封裝框架的代碼存在。少量的存在也通過反編譯的方式生成了源碼。
    
      其中最麻煩的是上個研發團隊自己封裝的工具包,整個項目涉及十幾個。由於一些緣由無法獲得該部分源碼,沒有辦法對於這樣,也只有使用最原始的方式——反編譯(這無疑是整個項目最頭疼的一部分)。
    
  • 開源項目版本老舊

    原因

      一、項目安全是任何一種技術被採用必須被考慮的問題。一個三年前更新的技術版本,讓我無法放心使用;以後技術版本越老舊,以後升級成本就越高。這也是需要先行處理開源技術被二次封裝的原因。
      二、過時的版本,也意味著使用不到新的技術特性。
    

    技術實現

      由於已經處理好了項目框架被二次封裝的問題,對於開源技術的升級相對來說比較愉悅,各個技術官網、論壇都能找到幫助文檔。
    

2.2 架構優化——保證業務進度的前提下,儘快處理

  • 缺少主要服務

    原因

      主數據服務過重,性能將成為短期可預見的瓶頸。尤其是包含了字典服務的功能,而且該項目原有的架構還存在大量重覆解釋同一欄位的問題,必然加重服務負擔。
    

    技術實現

      筆者結合項目的實際情況,對服務的拆分目前沒有徹底進行,而是循序漸進(在迭代中重構)。目前只是將相對獨立的字典服務先抽取出來。以後需要使用字典數據的時候之後調用字典服務。要請所有研發人員在迭代開發的過程中逐步替換掉原有走主數據的方式,改為直接調用欄位服務。許可權服務和用戶信息服務,由於涉及到的業務相對複雜,考慮到項目穩定性的問題暫時未做處理(待後期業務熟悉)。
    
  • 沒有事務(包含分散式事務)

    原因

      沒有事務帶來的可怕性,不言而喻。
    

    技術實現

      由於目前對整個項目業務並不熟悉,因此筆者目前還未深入處理這塊;只是先行升級開源框架,使用spring-boot 提供的優雅停服務功能來減少由於直接關閉服務帶來的數據錯亂問題;
      筆者目前對這一塊的想法本來是想通過橫向切麵統一給所有給GET介面都加上事務,但由於考慮到整個項目目前可以正常使用,且重新發版時間還不是特別緊因此未做處理,在此提出僅供大家參考。
      另外對於分散式事務,由於項目中存在大量複雜SQL,原有seata框架沒有辦法繼續使用(這也是為啥之前引入了此框架沒有使用的原因)。筆者烤爐到跨服務的事務畢竟是少數再結合目前項目進度緊張的實際情況,暫時未做處理。目前的想法是等服務先行全面測試之後,再通過調用鏈路服務梳理出所有的跨服務寫數據業務,逐一排查處理。
    
  • 網關服務定位混亂

    原因

      網關服務混亂,每個自服務都有對用戶登錄信息的校驗,這無疑是沒有意義的,反倒使代碼不夠整潔。
      許可權認證如有任何的調整都將牽涉到所有的服務。
      而且如果現階段不准確的定位各個服務職能,由於每個人的喜好(代碼習慣)不同,必然後導致這個服務越來越混亂。
      由於“不信任原則”,沒有服務都會過重的對客戶端進行校驗。
    

    技術實現

      前端雖有node服務,但由於並沒有實際運用起來,在結合目前的人員問題。因此決定後端引入網關服務,將各個服務的許可權認證業務分離,統一由網關服務承擔。
    
      說明:
          筆者將該服務重新拆分,放棄大前端模式的主要原因是:
          1.原有本應由原有node服務所聚合分離不同客戶端介面的功能,並沒有在node中,而是在後端介面中看到各種webController,AppController代碼;
          2.受限於前端目前人手及人員技術。
          3.筆者自身對前端架構不夠熟悉,前端負責人也贊同此設計。
    
  • 使用不同的序列化方式

    原因
    不同的序列化方式使得對緩存問題的排查,數據不夠直觀;
    相同的服務由於序列化方式的不同導致同時存在多分;

    技術實現
    1.技術選型確定合理的序列化方式;
    2.新開module,完成對redis客戶端的統一包裝RedisService;
    3.應用spring-boot提供的自動裝配技術,統一裝配RedisService bean;
    4.使用RedisService替換原有服務中所有使用redis客戶端的地方。

2.3 性能優化——保證業務進度的前提下,儘快處理

2.4 風格理念——暫不處理

以下幾點由於只是風格理念的問題,因此暫不處理。作為對新服務的規範。新增服務嚴格按照新的規範實施。老服務在之後的重構計劃中再行調整。
  • 依賴資料庫

    原因

      單一職責,資料庫只存儲數據,業務邏輯交由代碼。
    

    技術實現

      禁止使用資料庫存儲之外的其他功能。
    
  • 微服務並不微

    原因

      使用微服務架構,就使用微服務理念
    

    技術實現

      需求評審,合理定位,嚴格按照微服務的理念設計服務(掌握粒度,避免過度拆分)。
    
  • 返回大集合對象

    原因
    返回大對象會暴露一些不必要的欄位,泄漏隱私;增加IO消耗。

    技術實現
    VO獨立,介面返回欄位按需返回,避免大的VO設計。

  • 存在重覆解釋欄位情況
    原因
    無端的性能消耗

    技術實現

      介面分離,同時提供解釋欄位和不解釋欄位的介面(處於對現有介面的相容,因此提供解釋欄位的介面),這樣消費者可以按需獲取。
    
      說明:按照的架構風格,所有的介面不對字典數據做解釋處理。全部交由前段展示時翻譯。這樣的好處有:
      1.對於字典數據的處理,只需要在用戶登錄系統時從後臺請求一次返回保存到本地即可,一次請求多次使用。
      2.將解釋欄位的工作交由各個客戶端處理,減少伺服器壓力。
    
  • 代碼規範

    1.老服務的命名問題不做處理,幹掉強迫症;

    2.在迭代開發中增加代碼註釋;

    3.新開發研發按照編碼規範實施,使用sonar檢測代碼質量,不合格代碼一律不予以合併。

  • 項目文檔

    給產品和測試提需求,要求逐步完善項目需求相關文檔。
    技術相關文檔在迭代開發中同步完善。

筆者的話

以上調整,只是筆者對當前項目存在問題處理方式;由於技術能力有限,此中難免有不合理之處,誠邀各位大佬批評指教。

以下連接為筆者平時對技術的整理歸檔也歡迎各位大佬評論交流!
zero mgy ProcessOn


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原文地址:關於Android安裝apk出現解析包異常問題情況總結 | Stars-One的雜貨小窩 說之前,可以推薦下各位使用這個開源庫AndroidUtilCode,下麵提及到的工具類,都是在此庫中 以下說的解析包異常,是指進到安裝頁面就立馬出現了錯誤提示 而不是在可以正常進入安裝界面,然後點擊了 ...
  • OpenHarmony官方社群在4月14日晚上20:00,特別邀請了3位應用開發領域的技術大咖——張榮超、李寧、連志安,以《OpenHarmony 3.1 Release版本南北向關鍵能力解讀》為主題,與大家直播聊一聊OpenHarmony 3.1版本的那些事兒。 ...
  • ##背景 封樓期間難得空閑,也靜不下心學習,空閑之餘萌生了重做引導單頁的想法。因為之前都是扒站(某大公司游戲官網)+小改,一來雖然很炫酷,但本人水平有限,仍有很大一部分JS無從下手,甚至是看不懂|-_-|;二來對方畢竟沒有開源,無論道德還是法律都說不過去,所以……先從簡單處寫起,後續慢慢迭代吧! # ...
  • 由於vant組件自帶沒有隻選擇年的方法 所以需要我們自己寫這個方法,網上大多數的方法都是通過改node_modules下的組件文件,這個方法不是很友好,下麵的方法是我在網上找到一篇可以使用的方法,下附原文地址,原文包括了(年選、月選、周選、日選)方法,這裡只用到了年選,因為原文寫的年選方法有一點小問 ...
  • 今天結束的挺早,因為今天的內容還可以不是很難,今天全程是學了一些關於mysql資料庫和sql查詢語句的內容包括在node終端裡面怎麼來連接資料庫。經過今天的一個學習,我感覺離那個地步越來越近了,就是那個自己完成一個網站,有伺服器、有響應,就跟現在這些上線的網站一樣一樣的,越來越近了。 1. 這些內容 ...
  • 企業微信 自定義開發H5頁面應用 網頁授權登錄獲取用戶信息 許可權同步 ...
  • 哈嘍大家好我是臉皮賊厚的小威 愚人節剛過先給大家拜個早年吧 最近在HarmonyOS官網下載了IDE,並抱著學(wan)習(wan)的心態試著跑出了Hello World,並安裝到手機上 這是一個簡單到不能再簡單的過程,但是我做的依然磕磕絆絆,遇到很多的問題 在這裡發帖留念記錄一下 第一步安裝IDE ...
  • 為什麼要使用Sapper Sapper是一個用於構建各種規模的Web應用程式的框架,具有出色的開發體驗和靈活的基於文件系統的路由。 與單頁應用程式不同,Sapper不會在SEO,漸進式增強或初始載入體驗方面妥協 - 但與傳統的伺服器渲染應用程式不同,導航對於這種類似應用程式的感覺是即時的。 通過本教 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...