【西天取經】(升級.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日晚加班下班前更新到正式環境投入使用;
- 目前一天時間過去了,運行穩定,沒有出現翻車問題;
- 不在更新本篇文章內容表示一直沒有出現問題,請知曉。