去年.NET Conf China 技術大會上,我給大家分享了主題《輕鬆玩轉.NET大規模版本升級》,今天把具體分享的內容整理成一篇部落格,供大家研究參考學習。
一、先說一下技術挑戰和業務背景
我們公司:特來電新能源股份有限公司:中國最大最強新能源汽車充電網運營商,主要從事新能源汽車充電網的建設、運營以及網際網路增值服務。
基於.NET技術棧,團隊通過七年的迭代演進,搭建了一個分散式、微服務、高可用的網際網路技術平臺,全面支撐了特來電充電業務的大規模應用。
目前,我們面臨的技術挑戰有:
- 大型分散式、微服務、雲原生應用,新能源行業最大的網際網路應用
- 服務於全國的電動汽車車主,系統的穩定性要求非常高:SLA 99.99% ,系統全年可允許當機時間只有52.56分鐘
- 現有技術平臺需要快速支撐整個充電網的快速、上量發展!
通過打造一個網際網路技術平臺,全面支撐賦能公司的業務發展:
二、.NET技術棧及版本升級選擇
1. 先看一下我們網際網路技術平臺的技術架構全景圖
2. 整個網際網路技術平臺背後的.NET技術棧和開源技術
3. 目前系統的應用規模
4. .NET版本選擇及升級策略
- .NET Framework4.5.1 這個版本是線上最主要的版本,2015年開始一直沿用到現在
- 2020年正式全面遷移.NET Core3.1(LTS版本)
- 業務程式碼無法全部停下來,遷移升級.NET Core 3.1
- 遷移策略:逐步試點,逐個上線,非核心業務-新業務-核心業務
- 線上要長期、同時支援.NET Core 3.1和.NET Framework4.5.1
- 2022年計劃整體升級遷移到.NET 6
為什麼目前選擇了.NET Core 3.1 ?
- .NET Core 3.1:LTS版本,微軟支援到2022年
- .NET 5:非LTS版本,.NET 5是.NET統一後的第一個大版本,部分功能不完善,目前看是一個過渡版本。
- 2022年:整體升級遷移到.NET 6(LTS)
.NET 升級策略的設計
- 開發時:技術平臺的程式碼統一使用.NET Standard,同時支援.NET Framework4.5.1和.NET Core 3.1 業務程式碼的引用
- 執行時:.NET Framework4.5.1和.NET Core程式碼並存,技術平臺提供對應兩個版本的.NET CLR執行時,支援相互呼叫
三、.NET線上大規模升級實踐分享
1. 整體升級步驟
2. 先梳理NuGet包,確定各板塊應用.NET Core升級順序
3. 底層技術平臺先升級.NET Core
3.1 一套程式碼同時支援.NET Framework和.NET Standard
同時相容.NET Framework和.NET Standard
同時相容2個版本,不需要程式碼同步
示例一個多Target Framework的專案工程設計
示例一下程式碼支援多版本.NET
3.2 NuGet包同時支援.NET Framework和.NET Standard
價值:
同時相容.NET Framework和.NET Standard
相容現有程式碼引用,減少對引用方的影響
3.3 同時相容App.config和Web.Config檔案
引用Nuget:System.Configuration.ConfigurationManager
相容Web.Config檔案中對配置的訪問。
3.4 單元測試相容App.config和Web.Config檔案
單元測試情況下,在單元測試工程中增加了app.config檔案,但是實際無法讀取其中的配置,原因是:
MSTest is running as testhost.dll, which means that ConfigurationManager is reading settings from testhost.dll.config when executing under .NET core. It will look for testhost.dll.config where the testhost.dll is located as the accepted answer states. What is not mentioned is that it will also look for testhost.dll.config in the location where you have your test dlls
如何解決,大家可以參考這個連線:https://stackoverflow.com/questions/47752271/app-config-not-beeing-loaded-in-net-core-mstests-project/47753580
3.5 MyBatis.NET 升級.NET Core
MyBatis.NET作為資料訪問元件,社群早已不在維護,升級.NET Core我們做了哪些改造?
替換System.Web.HttpContextiBatis.net針對asp.net應用提供了HybridWebThreadSessionStore,通過HttpContext儲存每個http請求執行緒訪問資料庫的上下文。由於ASP.Net Core不再提供直接獲取HttpContext的方法,取而代之的是提供IHttpContextAccessor介面,並通過註冊HttpContextAccessor來獲取,因此在sqlmap初始化時,將獲取HttpContext的委託方法傳到HybridWebThreadSessionStore,使得每次ibatis.net需要獲取HttpContext時,都會從HttpContextAccessor中拿到。
替換System.Runtime.Remoting.Messaging.CallContextiBatis.net針對非web的應用也提供了CallContextSessionStore,通過CallContext來維護每個執行緒訪問資料庫的上下文。但.net core不再提供CallContext類,因此需要將CallContext替換為AsyncLocal型別的字典集合。Emit動態生成程式集相關改動。
對於一些使用Emit動態生成程式集的操作,例如DefineDynamicAssembly,由於原AppDomain中已經不再支援,需要進行一些相應的類的調整。
4、業務服務升級.NET Core
5、.NET Framework和.NET Core並行、相容執行,線上逐步升級
技術平臺層面:通過HTTP和TCP協議適配,實現微服務在.NET Framework和.NET Core下並行、相容執行
大規模升級步驟:非核心業務-新業務-核心業務,逐個系統升級、上線
四、未來技術規劃
全面升級.NET 6, 構建下一代雲原生架構的網際網路技術平臺
以上是2021年.NET Conf China 技術大會上,我給大家分享了主題《輕鬆玩轉.NET大規模版本升級》的主要內容。
周國慶
2022/2/26