【西天取经】(升级.net5)用了一整天才把项目从.netcoreapp3.1升级到.net5
【西天取经】(升级.net5)用了一整天才把项目从.netcoreapp3.1升级到.net5
2020年11月11日零点,一年一度的剁手节开始了,我相信很多人都在熬夜等待新的一天到来之后马上清空购物车,有的剁手,有的截肢,有的睡醒起来在自残。
除了这群人,昨晚还有一批.net粉丝们,他们除了剁手还需要关注地球背面另一个大新闻—微软的.net5今天正式发布了,同时也意味着.net framework,.net core都将成为过去了,.net的另一个时代来临了。
微软选择双十一这天发布.net5很多人也开始发挥想象力了,各种意味深长的文章全都冒出来了,今天早上各大.net公众号也是频频出现《.net5的崛起,淘宝双11系统会不会采用.net core?别不敢想?》的文章,看完之后我的心里也是激动万分感慨颇多,心里想着微软近二十年时间里是怎么把.net做成过街老鼠人人喊打的结果呢,为啥.net不招国人待见呢,甚至.net技术被认为根本做不了大项目呢?其实每一位.neter心里都很清楚,但是每个人的力量有限始终没有办法对整体产生影响。
作为一名.net老兵,昨晚虽然没有熬夜去看发布会,但是一觉起来赶紧上网找.net5的资源链接,趁着早晨还没有出门上班之前先把家里的电脑环境升级到.net5后,心里想着之前有篇文章写过五分钟就能升级完,开开心心的出门了……结果我用了一整天的时间才升级成功。下面开始分享我的项目整个升级过程。
首先需要把本地开发环境准备成.net5。 一共两步:
1、开发机安装.net5 SDK(SDK简单理解就是软件开发包,开发机必须安装),根据每个人的操作系统和CPU位数自己选择合适文件的下载。我是windows10 64位系统,所以我选x64。
.net5的下载页面:https://dotnet.microsoft.com/download/dotnet/5.0
下载之后就可以安装了
安装成功以后,用命令行的方式查看是否已经安装成功,确认一下自己.net版本是否已经是5了,这点比java好,不用配置环境变量,很贴心。实话实说,之前安装.net core 3.1的时候忘记有没有配过环境变量了。
dotnet --version
2、VS 2019升级到16.8以上的版本 ,打开VS 2019自动会有升级提示,很贴心;
如果你的IDE没有右下角的铃铛提示,请自己从帮助菜单里选择检查升级菜单项
安装成功之后,记得看一下关于Microsoft Visual Studio菜单项是不是已经升级到16.8的版本了。
两步做完以后,恭喜你成功进入.net5的开发环境里。这时候,我已经从上午9点上班,到了上午10点钟,用了一个小时做完本地开发环境的升级,因为升级需要公司的网络资源,所以比较慢。
下面我就要说让我折腾一天时间的升级过程了,真的是太不顺利了。
之前看过博客园的升级.net5翻车日记,也看过很多博客主写的升级文章,有说五分钟就能升级成功的,我也是抱着这种心态开始今天的升级操作,因为我也是和之前博主说的一样从.net core 3.1升级到.net 5。
结果升级的悲剧不断的发生,一直到下班之前才搞定所有升级。
原本以为,点一下更新就能一下升到最新的版本,没想到痛苦的工作才刚刚开始。
72个包需要更新,折磨我一天。
首先我是把每一个项目文件里的TargetFramework从netcoreapp3.1改成net5.0这个很容易,批量替换就可以了,
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>net5.0</TargetFramework>
1个解决方案里面 74个项目很快就替换完成了,接下来开始替换微软自己的包文件,从3.1.0替换到5.0.0,不顺利的过程就是从这里开始发生的:
Version="3.1.0" 批量替换 Version="5.0.0"
结果发现还是有Microsoft开头的包没有升级到最新的5.0.0,查看之后发现是之前引用包文件写的版本不是Version="3.1.0",当时也忘记为啥不是了,结果杯具的过程就此发生了(自己一个人哭就好了),我直接说结果了。下面这个包根本没有5.0.0这个版本的,是微软忘记出新版了,还是忘记发布更新了,啥原因自己也不清楚。
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="3.1.10" />
升级不成功,把这一个版本退回去不就可以了吗?退回去这个之后发现还有别的包有问题,注意下面是第三方的包更新爆出问题了,我这个时候还没有开始更新第三方的包,它就开始报错了,也是奇怪了。
<PackageReference Include="DotNetZip" Version="1.13.8" />
DotNetZip这个包怎么也升不上去,错误写的啥也不记得了,反正缺System.Security.Permissions这个包,我的项目也没有用到这个包里面的类。算了不管那么多先加上不就可以了,于是乎就这样加上了一个根本没用过的包引用。
<PackageReference Include="System.Security.Permissions" Version="5.0.0" />
到这里还算幸运编译不出错了,时间也到中午12点了,项目可以运行成功了,也能看到程序跑起来的界面了,心里一阵喜悦,可以开心的去吃饭了,这时候打开朋友圈发现我的好友上午就已经在本地开发环境里升级成功了。而我的项目还没有把用到的第三方的包升级到最新版本呢,吃完饭先睡了一会,下去继续开始弄。看到别人成功了自己也有信心了,虽然我的项目第三方包用的有点多,项目分的也有点多,但是都是数量上的多,心里想着没啥问题的,结果下午升级第三方的包麻烦真的来了。 升级第三方的包各种升不上去、不兼容的问题全出来了,基本上就是升级某个包需要必须在哪个版本范围内才可以升级,来回来去的折腾,要么先升级这个,要么不行就是先升级那个,繁琐的很。
举一个例子:MySqlConnector这个包从1.0.1升级到1.1.0
<PackageReference Include="MySqlConnector" Version="1.0.1" />
它和健康检查的包有冲突,我用的是下面这个版本的,来回来去折腾是先升级这个还是先升级那个
<PackageReference Include="AspNetCore.HealthChecks.UI.MySql.Storage" Version="3.1.1" />
最终让我把AspNetCore.HealthChecks.UI.MySql.Storage这个包引用给删了,不用了总可以吧,反正现在项目也没用上,之前用了存储健康检查结果到数据库里,后来感觉没啥用就不存数据库了。
此时已经到了下午3三点钟,项目引用的第三方的包也升级完了,就剩这3个了,没法升级了,因为它的开源协议之后改变了,升级以后要收费了。其他的都已经升级完成了,本地开发环境Debug,Release都可以编译成功,运行成功。
接着改.gitlab-ci.yml文件,把docker编译那里改成.net5就可以提交代码,自动发布进k8s了,事后证明这时候我想法太天真了,真正的麻烦终于来了。
.net5的docker镜像源地址:
https://hub.docker.com/_/microsoft-dotnet-aspnet/
https://hub.docker.com/_/microsoft-dotnet-sdk/
结果gitlab-ci执行不成功说找不到各种包(没有截图),当时太烦了,那会已经来来回回折腾好几次没心思在去截图了。
当时在执行gitlab-ci的时候,心里想着完事大吉看看朋友圈,发现我上午升级成功的好友已经开始喝某某咖啡了(不能被人怀疑有打广告的嫌疑,我就写某某咖啡了)。
幸亏我刷朋友圈的时候发现我的好友他用的docker源和我在网上找的不一样,多了这个-buster-slim后缀。于是我也改成和他一样的
****/aspnet:5.0 (我用的) => ****/aspnet:5.0-buster-slim (他用的)
****/sdk:5.0 (我用的) => ****/sdk:5.0-buster-slim (他用的)
赶紧换上继续提交代码自动编译发布到k8s里面。结果大失所望,还是找不到nuget包,Down下不来,于是我就又去掉这个包源的后缀了,提交上去自动化发布还是不行还是失败。
同事们这时候开始说三说四,.net5刚出来第一天就更新项目,很多用的包都还没有出来新版本呢,说我太着急了,退回去吧。我心里想着本地环境都能运行成功,我机器里的nuget包从哪里down下来的,为啥服务器上的nuget包down不下来呢?既然不是docker源的问题,那就是nuget源的问题。果然,事后证明我当时的想法是对的。继续找原因:
我们编译代码的时候gitlab-ci里的yml文件写了使用某一个nuget.config文件。
我们的项目一直用的是本地搭建的私有仓,怎么会出问题呢?先改了再说,死马当活马医,改成微软官方的源地址:https://api.nuget.org/v3/index.json,试试看。
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="internal" value="http://192.168.0.112/repository/nuget-proxy-v3/index.json" #之前一直在用的本地包源地址 protocolVersion="3" /> </packageSources> </configuration>
提交服务器后,自动化还是不行,咋回事啊。我想着还是让我同事帮忙看看吧,自己已经无计可施了。我想着去他们的机器上拉一下最新的代码试试看可不可以编译成功,这时候我才发现,早晨来了我在钉钉群里发的消息让大家下载.net5 sdk,升级vs2019到16.8,结果根本没有人在意,也没有人去做。
当时我脑袋里就想起来,之前在各种群里总是能看到有人抱怨公司的祖传代码如何如何垃圾,现在SDK我都发给你们了,竟然团队里没有一个人下载升级的,这就是真实的工作环境,一边抱怨别人写的东西,另一边自己却不作为。同事不给力,没办法只能说好话,让某个同事先下载安装然后升级,在他的机器上实验一下可不可以编译成功。我心里想怎么可能只有我一个人的机器可以下载nuget包呢?难道老天爷看见我勤奋努力,让我穿越到国外下载完成以后又送回来了吗?这时候公司的网络也非常不给力,下载速度巨慢,早晨人少下载的还快一点,现在公司同事都来了,大家都在用网络,下载的速度那真叫一个慢啊。一边想原因,一边自己本地打docker,发现项目通过vs 2019添加Docker支持后,Dockerfile文件里面用的docker源就是带有-buster-slim这个后缀的,难怪我的好友用的是这个名称的docker源,但是我依然把项目里新创建的Dockerfile这个源后缀给删了,还是用docker官方给的包源名称,因为我当时已经感觉到90%以上不是docker包源的问题,而是nuget的包源问题。
本地docker也做好了,还是能成功,真TMD奇怪了。真的如我所想,我的电脑已经出国了吗?服务器的网络会有问题吗?同事的电脑依然在慢慢的升级vs 2019。已经下午5五点多了,我这是要加班作死的节奏啊,今天弄不成,就得退回去,毕竟还有很多功能都需要测试,不能因为我升级耽误大家宝贵的时间。罪恶感涌上心头,心里骂了一百遍之前是谁说的从.net core 3.1升级.net 5没啥问题,5分钟就能搞定的,dll不用换,啥也不用改的。为啥我用了最新版本的包却一个也down不下来。
我开始让负责搭建自动化的同事,帮我把私有仓里服务器上的缓存文件全删了,心里琢磨着是不是这些最新的包文件都没法升级到最新的版本呢?服务器上的包文件有冲突了变傻了吗?这时发现他用了minio这个web界面(后面有机会再说),又是没见过的东西,心里骂娘,东西太多,学不完啊,保重身体要紧。删了服务器的缓存文件后还是down不下来包。灵感往往就在一瞬间的功夫出现了,难道是私有仓的包源那里出问题了吗?毕竟我改的是gitlab-ci里nuget.config这个文件而且也不管用。我再看看自己的vs 2019都用了哪些nuget包源,发现我用了博客园的包源地址。眼前一亮,博客园已经升级到.net5-rc2了,我本地用的是它的包源,而服务器上用的还是微软官方的包源,莫非今天升级的人太多了,微软的nuget服务器也挂了吗?
nuget官方包源:https://www.nuget.org/api/v2/
博客园的包源:https://nuget.cnblogs.com/v3/index.json
本地私有仓里,原来nuget的包源地址:
换成博客园的包源地址:
再来一遍gitlab-ci,终于成功了。此时我同事的电脑还在升级vs 2019呢,真的是无语……
编译的截图:(这里用到了nuget包缓存,由minio存储起来的,我上面的图片里dotnet restore命令会自动把nuget包下载放到minio里面,以后在发布就可以直接从本地私有仓里取了,这样的好处是只有第一次发布的时候需要down,之后就从本地私有仓里拿包了,速度快,节省带宽)
打包Docker的截图:
部署进K8S的截图:
项目运行环境的截图:其中一个项目里有498个dll文件,除了有3个包升级之后需要单收费没有升级之外,其他的495个dll文件全部升级到最新版本了。
项目运行起来的彩蛋信息:
总结一下,我们项目这次升级遇到的坑:
1、确实从.net core 3.1升级到.net 5很容易,冤枉某些博主了。
2、<PackageReference Include="Microsoft.****"开头的包都能升级到5.0.0,只有一个不行,Include="Microsoft.Extensions.DiagnosticAdapter" Version="3.1.10" ,继续用3.1.10这个版本,它就已经是最新版本的了。
3、升级第三方的包基本靠耐性,来回来去折腾先升谁后升谁,用的越多,来回来去捣腾的次数也越多。而且会有改代码的情况出现,我就遇到了。还有我把第三方引用的DotNetZip包删了,因为它会让我引用System.Security.Permissions这个包。搞不清楚干啥的,先去掉,之前用到DotNetZip包里面的代码我也注释了,前期需求有用到压缩文件,后来改需求不用了,所以这里暂时用不上,注释掉省的麻烦,因为当时下不来包的时候我已经很烦躁了,能少用一个是一个。
4、因为我们的项目是正式项目不是demo,整个项目用了很多.net之外的知识,出了问题不太好判断,还好最终找到原因解决了,这里我要给博客园的nuget包源点赞,不然我最后真得是down不下来包只能返工了。想想祖传代码是怎么来的?多可怕啊!看完这篇文章希望各位想升级项目的不要怕。
5、关于自动化编译打包部署这里的知识确实非常考验知识面,如果.neter还是认为windows天下无敌,java就是垃圾,那就大错特错了。虽然java的程序员未必会这些技能,但是他们公司有人就在用这些东西。而.net程序员还在用windows那么永远都没有机会接触到这些东西。还有用.net开发的程序不如java的,你们的想法也是不对的,选择什么开发语言本身没有错误,如果没有好的技术人员,运维,DBA,自动化管理,不管是java还是.net开发出来的程序都是做不起来的。想想没有DBA的公司,全靠程序员来做,怎么可能会成功呢?哪个大公司没有DBA,阿里没有吗?如果只靠java微服务框架就能做起来淘宝,就能够把淘宝的双十一剁手节撑起来那也不现实。妖魔化微服务框架也是不对的。
自动化,运维,DBA这些技能包希望更多的.neter能够快速掌握里面的知识,即便是自己一个人做不来,也应该知道招聘什么样的人来帮助公司做事了。毕竟一个人的能力有限,既写需求代码,又去搞自动化或者运维DBA也不现实,请专门的人做专业的事情,就像程序员负责把项目代码写好同样的重要。每个岗位分工不同,但是重要性都是一样的,如果一家公司的技术岗位缺三少四,那这家公司肯定做不大,往往用java的公司都不差钱所以技术岗位又多又全。阿里的数据库是自己做的,滴滴的数据库中间件也是自己开发的,没听说它们的项目全是用java写的。所以,最后建议大家把.net项目写好的同时,能多学点知识,或者尽快招聘到合适的人来一起把自己公司的项目做起来。没有一个大项目是用一种技术完成的,也不是说.net就做不了大项目。大项目和开发语言没关系这是常识问题,和团队有关系,和岗位分工有关系,和管理有关系,和业务有关系,和钱有关系。.net也好java也好,做技术的不应推卸自己的责任,但是不应该背的锅也不能让技术来背。技术人才可贵,但也不是什么都能做的人才叫技术人才。专和广本身就是矛盾的。
今天就要结束了,我和很多人一样都有同样的满足感,有人在双十一买到了又喜欢又便宜的商品;我也把.net5这只大螃蟹吃到肚子里面了,除了满足感之外我还有成就感:第一次在技术首发日之内把公司项目升级到最新版。
补充:
- 2020年11月11日晚六点下班前更新到测试环境进行测试;
- 2020年11月16日晚加班下班前更新到正式环境投入使用;
- 目前一天时间过去了,运行稳定,没有出现翻车问题;
- 不在更新本篇文章内容表示一直没有出现问题,请知晓。