一,.NET Core 自宿主应用程序个头有点大linux
发布.NET Core应用程序有两个方式,一种是“便携式”,一种是“自宿主式”。便携式发布时,目标程序不带.net core运行环境,因此“个头”很小,可能只有几十K几百K字节,可是它须要用户的目标系统上安装.NET CORE 框架;自宿主式发布出来的程序,自带运行时和框架类库,自成一体,不须要客户机安装.NET CORE环境,部署简单方便。docker
看看一个简单的“Hello World!” 控制台程序有多大:json
修改 csproj文件,添加目标系统:windows
用 dotnet publish -r:linux-x64 针对linux平台发布,获得目标文件(夹),如今看看大小:框架
这个Hello World 控制台程序的目标文件,总大小达到了62.2 MB!运维
二,为何.net core自宿主程序这么大函数
缘由有二,一是为了能在目标系统上 “独立” 运行,自宿主程序必须自带运行时,这无可厚非,二是不论是用 dotnet publish命令行发布仍是用VS发布,它们都会不分青红皂白地把.net core类库整个发布到目标程序中,这正是使目标程序变大变肥的主要缘由。测试
下面是发布后的部分文件列表,能够看出,不少的dll与这个hello world 程序毫无关系!.net
三,给 Linux .Net Core 自宿主应用程序瘦身命令行
为何要给“自宿主”程序瘦身?缘由是,既然发布“自宿主”程序而不是便携式程序,通常都是程序做者或厂商但愿产品能有更好的独立性,更看重程序自己的完整和纯净,不喜欢附带一些乱七八糟的东西。另外,程度体积小一些,能更方便地在卡片机(如树莓派)、小型专用设备这类存贮空间不太富裕的设备上部署,在Dockeer中部署,也能大大减少映像的大小,在一样的空间中运行更多的服务。
从前边的分析能够看出,自宿主应用程序之全部“肥大”,是由于有太多的无关的类库或Native so库形成的,只要清理掉它们,瘦身的目标就达到了。
1,将发布的程序所有上传到Linux系统的某个文件夹,而后运行 chmod +x coretest,给coretest赋与可执行权限。(我写的这个hello word程序名叫“coretest”)。
2,用 ./coretest 把程序运行起来:
不要按键,让程序不要退出。
3,查出这个进程的PID:
再加一个终端,用 ps -ef | grep coretest 查出这个进程的PID号
4,列出进程关联文件:
用 sudo lsof -p PID号,列出指定进程调用/引用的文件,从列表中找出属于这个core程序依赖的类库和core Navite函数库:
特色:路径都指向这个core程序所在的文件夹。
下图是列表的一部分:
从列表中,能够看出,本 coretest 程序,相关的文件有以下三类14个文件:
1)coretes加载程序和程序集:
coretest
coretest.dll
2)依赖的.net 框架程序集:
System.Runtime.dll
System.Console.dll
System.Threading.dll
System.Runtime.Extensions.dll
System.Collections.dll
3)运行时函数库:
libclrjit.so
libcoreclr.so
libhostpolicy.so
libhostfxr.so
System.Native.so
System.Globalization.Native.so
System.Private.CoreLib.dll
5,修改依赖文件 coretest.deps.json,对依赖行配置文件瘦身:
打开 coretest.deps.json文件,你会发现全部的依赖库都在其中,重要的是49行开始的“runtime.linux-x64.Microsoft.NETCore.App/2.0.0”的runtimes和native两个节点,共有173个依赖项,与咱们测试出来的14个依赖,整整多了近160个依赖项,这些多余的,均可以删除!
删除后,deps.json一会儿清爽了:
6,测试依赖配置文件是否正确:
再次用 ./coretest 运行本程序,检查依赖项是否正确。当按任意键退出程序时,出现了下边的错误。
原来,在Console.ReadKey返回时,会调用另外一个dll,而以前用lsof时读取依赖时,程序没有执行到这一步,因此没有看到有这个依赖,这个依赖被误删了。因此,得从新加到deps.json文件中。
再次测试,程序已经彻底正常。
7,根据瘦身后的依赖关系,删除无关文件:
要点,须要保留依赖列表文件coretest.deps.json和运行时配置文件coretest.runtimeconfig.json。
8,再次测试程序运行状况:
运行 ./coretest,发现出了一个问题:
原来还差一个native 函数库,怎么办?简单,从windows发布目录中,上传到Linux的这个程序文件夹中。
再次运行,一路顺风,瘦身工做正式完成!
如今看看这个程序,共计还有多少文件:
哈哈,如今只有19个文件!好比以前的近180个文件,这个”身“瘦得厉害吧,简直是一身清爽呀!
瘦身后,这个程序全部文件从62.2M变成了24.3m,打包压缩后,只有8.62M。
附记:
有的朋友可能会说,仍是有点大呀,一个hello world就有19个文件24m大小,若是我司开发一个功能完整的商业应用会不会大得吓人?其实,我能够告诉你:
一,这19个文件已经具有了.net core的关键功能,你开发更大的商业应用,不外乎再多引用了几个dll而已,能再大多少?!
二,这个程序是自带了运行环境的,它自成一体,独立运行,不须要麻烦你和你的客户或运维人员在linux上安装安装一大堆东西,配置一大堆东西!
三,正由于这个程序能够独立运行,那么,若是放在Docker中,对docker镜像的体积影响能够忽略,大家镜像文件不会由于须要安装什么工做环境而增大数百M的体积。