去年.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大规模版本升级》的主要内容。视频可以通过思否的进行回顾:https://ke.segmentfault.com/course/1650000041122988/section/1500000041123033