從.net framework 到 .net core:車家號項目的升級過程及經驗

来源:https://www.cnblogs.com/88223100/archive/2023/02/21/Autohome-netframework_to_netcore.html
-Advertisement-
Play Games

車家號作為一個PGC平臺,聚合了全網大多數汽車行業的專家及意見領袖,每天為用戶提供大量的汽車類優質內容。用戶日瀏覽量在幾千萬級,後端的介面也承載億級的日訪問量。 車家號WEB、API、後臺管理等系統採用 .net4.5進行開發。一直以來為用戶及調用方提供了穩定的服務。由於其只能運行於W... ...


 

一、背景

      車家號作為一個PGC平臺,聚合了全網大多數汽車行業的專家及意見領袖,每天為用戶提供大量的汽車類優質內容。用戶日瀏覽量在幾千萬級,後端的介面也承載億級的日訪問量。

      車家號WEB、API、後臺管理等系統採用 .net4.5進行開發。一直以來為用戶及調用方提供了穩定的服務。由於其只能運行於Windows平臺上,其擴展及遷移的能力受到了極大限制。需要將車家號業務轉移到Linux平臺,可以進行更為靈活的運維,並且具有容器化能力。

       方案之一,用java重寫,這個對於一個已經維護多年的有大量的業務邏輯在裡面的系統來說,工作量是相當大的。只重寫介面相對簡單,但如果將PC 及後臺管理進行重寫工作量極大。或前後分離NodeJS 方式,這樣也會給前端開發及測試帶來巨大大的壓力。還有更重要的一點,需求不斷的提出來,還要不斷有新特性加入進來,如果維護兩套異構語言的系統,會給業務及系統的穩定性帶來很大的風險。

      另一個方案,項目從.net framework 升級為dotnet core,基本上語法方面不需要變化,業務代碼不需要變化,新需求的加入,單向同步代碼即可。同時,.net core 是跨平臺的,另外,可以使用docker進行彈性擴容縮容。.net core 在性能方面從官方數據及後來的一些測試看的確有了明顯的提升。

       所以,基於這些主要原因,我們選擇了方案二,.net core ,並且容器化。

 

二、人員投入

時間

天數

人員

人日

2月21日-2月27日

5

1人

5人日

4月1日 -5月13日

27

0.5人

13.5人日

5月14日-5月24日

9

1.5 人

13.5人日

5月27日-6月6日

9

2.5人

22.5人日

合計:

   

54.5人日

 升級前期,因存在嘗試、學習等因素,人員投入較少。後面調整重心,加強人力投入到升級工作中,快速推進升級上線。

 公司範圍內,我們是第一個將較大項目進行.net core 升級的團隊。沒有太多dotnet core的積累,無成功案例可借鑒,同時大量工作也用在了構建基礎設施。未來類似規模項目進行升級,時間及人力投入方面會大大減少。

 

三、升級效果

1.性能提升

圖片

從5.25日開始逐步灰度,tp99也從100ms逐步降到45ms左右,到發稿為止穩定保持於45ms以下。

2.無感知升級

介面,WEB,後臺管理等從外觀及行為上沒有的變化,做到用戶及調用方無感知。

3.彈性

由於core 可運行於Linux上,可以藉助於之家雲平臺,在容器中彈性擴容。

 

四、主要過程

在業務需求不斷變更的同時,在第一次全量完成代碼同步後,嚴格從原有業務主幹(.net framework + TFS)單向同步到新版本業務主幹(.net core+ git),保證業務行為的一致性,並不斷同步發佈新版本進行灰度,兩個版本的行為保持一致性,升級過程無縫切換。如下圖所示:

 

圖片

1.準備階段

由於.net core相容性及某些功能的缺失,需要使用重新編譯或編寫新組件進行相容,這些作為基礎組件,需要進行更多的單元測試及測試項目中的測試,保證其它正確性,穩定性及相容性。

  • .net core 已經無法使用.net framework的組件,所有原有組件都需要重新編譯適配。(見組件列表)

  • Asp.net core 中 有些功能已經不再支持,需要重新適配。見附相容組件 

2.編譯通過階段可運行階段

  • 自底向上,逐個項目進行升級。

  • 卸載所有項目。

  • 從基礎的底層的類庫進行升級,通常其依賴著準備階段中提到的各種組件。

  • 底層公共項目,通常都可以順利編譯通過。

  • 對於實在無法編譯通過的項目,根據其作作決定是否先註釋掉,並用異常拋出的方式先行替代(throw new NotImplementedException()),防止未來的誤調用或忘記實現。

  • 根據原有項目間依賴並系,逐步上向。

  • 先將介面項目編譯通過,由於其不依賴UI等,比較容易通過,替換相容,運行。

  • WEB 項目

  • Asp.net Core 與 asp.net 項目結構不同需要進行調整。

  • 批量替換命名空間

  • 編譯,如果有不能通過的,看是否能快速解決或重要性,決定是否跳過。

經過上面的操作,項目基本可以運行,完成升級過程的第一步。

3.細化解決問題並同步代碼

Core 版代碼使用git 進行管理,從 TFS某個時間點進行快照,並Push到git庫。作為基礎,進行升級改造,對組件及代碼級別的不相容進行調整。後面新業務也是在這個版本的基礎上進行增量同步。

後面的需求還在繼續在TFS上提交,採用由TFS到Git單向同步的方式,TFS上的新需求由負責的開發人員同步至git 上。這種情況將持續到全量上線。

這個階段經歷了大致兩個星期。

4.測試

  • 開發自測:開發人員 自動用例生成工具,生成測試用例,使用JMeter 測試,大規模的覆蓋,快速發現並修複問題。另外,使用自動化介面對比工具,完成全量介面對數據對比,完全節省了人工對於介面的重覆測試,快速發現並定位問題。

  • 測試人員測試:對於一些重要場景,如作者發現文章及與財務相關的功能,需要人工方式進行二次驗證。

5.灰度上線

雖然經過了多次測試,但一些場景可能會無法覆蓋,需要採用灰度方式。將新版加入負載,經過從萬分之一,百分之一,十分之一,二分之一,最終全量。

在灰度過程中,對錯誤日誌、訪問日誌、性能日誌等多維度進行監測,保證系統負載在可控範圍內,並且發現有異常及時修複或回調流量。

6.全量切換

系統上是先從PC開始的,等PC上線穩定以後,再上線介面,服務,對外介面等其它系統。

PC:在構成方面雖然比較複雜,但它前面有CDN 及SCS,萬一齣現問題,來得及進行補救。

介面:流量大,但結構相對簡單,如果出現問題,影響面比較大,所以,在PC成功切換後,有了經驗及信心,再進行切換。

後臺管理:運營使用,有問題可能快速反饋,並能快速修複。

服務:核心業務已經上線,服務,也要跟著上線了。

Open介面:由於流量及用戶都不多,並且大多數是Post介面,需要更充分的測試,選擇最後上線。

6月6日 最終完成所有系統的全量的上線。

 

五、經驗

1.備用方案,隨時可回滾

在最初制訂方案的時候,考慮到極有可能出現意外,導致新系統有不可預知的問題。需要具有隨時切換回舊系統的能力,當然,這個也是灰度的基礎。

保證可以切回,要保證:

    (1)最重要的,代碼要保持同步。

    (2)同步發佈,新舊兩個環境都要保持最新,同步。

    (3)在完成穩定遷移,舊的環境一直保持高可用。

在本次遷移過程中,由於Core所在集群故障,緊急切回舊系統,這樣避免了一次非常嚴重的事故。 

2.擴容要謹慎

升級過程中某天,系統的流量突然異常。系統開始變慢,但還能勉強頂住。

隨後做出了擴容決定,從8個實例,直接擴容為30個。接下來,就是連鎖反應,WEB,API,相繼告急,性能極度下降。資料庫不斷報警。

對於我們從傳統的單體應用進行遷移至Docker, 不要急於擴容,一定要看到你的系統是否有單點,這個單點是否可以避免。

3.自測工具

本次升級,測試人員投入大概兩個半天,進行測試。剩下的都由開發人員進行自測。使用工具進行大規模的覆蓋。

測試工具,對比工具等都根據實際業務進行自主開發。在未來也可以重覆用於其它或日常工作中。

介面對比及批量對比測試:

圖片

 

自動生成用例及在JMeter中測試:

圖片

 

4.日誌工具

.net core 在 Linux下是沒有相應的訪問日誌,另一個途徑也可以從Nginx獲取訪問日誌,但它與我們現有日誌分析及監控系統不相容。

基於.net core 中間件,對訪問進行攔截並記錄日誌。使用Udp 方式發送至日誌收集系統。

這樣對系統的訪問數量及處理性能通過報表有直觀的瞭解。

圖片

5.監控工具

.net core 由於是一個新的生態,沒有類似於windows下的性能記數器,或Java的Jmx這種工具對性能進行監控。所以,我們需要自己來做一套監控解決方案。

(1)  做SDK,收集系統運行性能指標。

(2)  提交至Logstash

(3)  Logstash 寫入 ES

(4) 通過Grafana進行圖形化展示。

圖片

 

6.緩存註解

從Java中學習到Spring boot 的Cache註解,按其思路實現註解並應用於.net core , 一個註解,省去大片代碼。

 

代碼中使用註解示例效果:

圖片 

使用註解前後效果TP 99對比:

 

圖片

 

 

7.緩存的一致性

由於我們的系統極度依賴於緩存層,並且服務會更新緩存,新舊的系統如果可以使用同一套緩存,使用同一個Key,那可以減少很多必要的麻煩。

我們重新編譯了ServiceStack.Redis 。保證了緩存的行為的一致性,這為我們節省了至少三分之一的工作量,使得新舊各系統中都是一致的緩存,一致數據。

8.   Json 框架

在當前系統中用到了多個框架,Json.net , FastJson , MS Json , 在代碼調試過程中,新舊系統使用返回數據不一致,也發生各種序列化異常,經過分析,原來一舊代碼與新代碼使用不同的Json序列化方式。

在系統遷移過程中,由於多處使用了這三個框架,只重構掉了一種MS Json,現在還有 Json.net , FastJson 兩種在運行著。

後面系統穩定後,應該僅保留一種序列化框架。

9.Docker性能

當時轉core一個原因就是想使用 docker 進行動態擴容、縮容的特性。本次升級過程中,由於所在機房資源不足,docker集群不穩定,遷移機房暫時不具備條件等原因。只能將部分業務,如後臺,服務,Open介面等運行在docker上,其它隨時壓力較大的如WEB ,介面等運行在VM上,在遷移機房後,再將大流量產品進行遷移。

10.  先運行再解決Bug

過程中不要把問題放在一個點上,先保證系統可以整體運行,再去解決某個點的技術問題,為團隊樹立信心,讓每個人都可以看得到它是可運行的。

 

六、最後

在本次升級過程中,讓我們感受到升級.net core很小的學習曲線,快速入手,性能的提升也是一種驚喜。還有,大多數常用的開源組件對core提供了支持,改極少或不用改代碼即可使用。

同時,升級過程中,積累了經驗,產出了通用性功能及組件,對於其它系統的升級具有指導和借鑒意義。

還有,這個成功的案例,也給有升級想法的團隊,樹立信心,使他們可以更快邁出這一步。

升級過程發現了一些問題,促使我們對於架構進一步的思考,在後面通過對架構的優化使系統具有更好的擴展能力。

 

七、附錄

1.組件

  • dotcoreActionMessageSdk  發送HttpMessageQuene 組件

  • dotNews.ServiceStack.Redis  Redis連接組件

  • dotcoreAutohome.DataHelper  Sqlserver連接組件

  • dotCoreCasClient   SSO 組件

  • dotcorejobclient   分散式Job組件

  • dotcoreNews.Comm 通用類型組件

  • dotcoreNews.Common.Extends.Log ELK 日誌組件

  • dotcoreNews.Common.Extends.Upload 圖片上傳組件

  • dotcoreNews.Common.UploadObject 文件上傳組件

  • dotcoreWebdiyer.MvcPagerCore  ajax分頁組件

2.相容手段

  • dotcoreHttpContextCurrentCore組件  asp.net core 已經沒有HttpContext.Current, 本項目實現 System.Web.HttpContext.Current 功能,最大程度相容舊代碼,減少重寫量

  •  core 不再支持 WCF ,未來版本是否支持社區還在爭論中,我們採用重寫路由的方式進行相容。

  •  Html.Action 不再支持,重寫這個方法,為了區別更別為Html.RenderAction,參數功能不變。

  • EF Repository 模式代碼,基於 sqlSugarCore 改寫。保持調用外觀不變。

  • Microsoft.Practices.ServiceLocation 不再支持,使用 Castle.Core

  • using System.Web.Mvc,不再支持, 使用  usingMicrosoft.AspNetCore.Mvc;

  • Areas 的支持不再,使用 router

  • Ashx 一般處理程式不支持,改用 router相容

  • [assembly: PreApplicationStartMethod] 不支持,改用 StartUp.cs中調用

  • HTTP handlers and modules 改為 middleware

3. 工具支持

  • 自製應用程式指標監控

  • 自製批量用例自動生成

  • 自製指量介面比較工具

  • Jmeter

 

作者| 張保維

本文來自博客園,作者:古道輕風,轉載請註明原文鏈接:https://www.cnblogs.com/88223100/p/Autohome-netframework_to_netcore.html


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

-Advertisement-
Play Games
更多相關文章
  • 阿裡雲物聯網平臺專用工具基本涵蓋了阿裡雲物聯網平臺提供你主要管理功能,可以方便創建產品、設備、物模型,查看設備實時屬性,事件,發送服務和查看服務日誌等等 ...
  • 近期,業務調整,需要內網讀取數據後存入到外網,同時,其他伺服器也需要讀取數據,於是我又盯上了RabbitMQ。在展開業務代碼前,先看下RabbitMQ整體架構,可以看到Exchange和隊列是多對多關係。 下麵,我們詳細說說RabbitMQ的隊列模式:簡單隊列、工作隊列、發佈訂閱模式、路由模式、主題 ...
  • Net 內置記憶體緩存 asp.net 中是有緩存的實現:HttpContext.Cache,緩存的數據是放到 Web 伺服器的進程 記憶體里。 在控制台、WinForm、子線程、SignalR 等不支持 HttpContext 的地方還可以使用 MemoryCache.Default(System.R ...
  • FTP作為日常工作學習中,非常重要的一個文件傳輸存儲空間,想必大家都非常的熟悉了,那麼如何快速的實現文件的上傳下載功能呢,本文以一個簡單的小例子,簡述如何通過FluentFTP實現文件的上傳和下載功能。僅供學習分享使用,如有不足之處,還請指正。 ...
  • 大家好,我是沙漠盡頭的狼。 本文先拋出以下問題,請在文中尋找答案,可在評論區回答: 什麼是API攔截? 一個方法被很多地方調用,怎麼在不修改這個方法源碼情況下,記錄這個方法調用的前後時間? 同2,不修改源碼的情況下,怎麼對方法的參數進行校正(篡改)? 同3,不修改源碼的情況下,怎麼對方法的返回值進行 ...
  • 一:背景 1. 講故事 一直在追這個系列的朋友應該能感受到,我給這個行業中無數的陌生人分析過各種dump,終於在上周有位老同學找到我,還是個大妹子,必須有求必應 😁😁😁。 妹子公司的系統最近在某次升級之後,在高峰期會遇到 CPU 爆高的現象,有些單位你懂的,很強勢,所以就苦逼了程式媛,不管怎麼 ...
  • 1. Ioc 與 DI Ioc 和DI 這兩個詞大家都應該比較熟悉,這兩者已經在各種開發語言各種框架中普遍使用,成為框架中的一種基本設施了。 Ioc 是控制反轉, Inversion of Control 的縮寫,DI 是依賴註入,Inject Dependency 的縮寫。 所謂控制反轉,反轉的是 ...
  • 概述 面臨一個複雜對象的創建工作,通常由各個部分的子對象用一定的演算法構成。子部件(對象)比較多,對象不能當作一個完整的對象或者產品使用(郵件:發件人,收件人、抄送人、主題、郵件內容)子部件需要按照一定的順序賦值才有一定的意義,在某個子部件沒有賦值之前,另一個子部件就無法賦值。 類圖 註:該類圖來源網 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...