.NET跨平台实践:Linux .Net Core自宿主应用程序瘦身记

一,.NET Core 自宿主应用程序个头有点大

发布.NET Core应用程序有两个方式,一种是“便携式”,一种是“自宿主式”。便携式发布时,目标程序不带.net core运行环境,所以“个头”很小,可能只有几十K几百K字节,但是它需要用户的目标系统上安装.NET CORE 框架;自宿主式发布出来的程序,自带运行时和框架类库,自成一体,不需要客户机安装.NET CORE环境,部署简单方便。

看看一个简单的“Hello World!” 控制台程序有多大:

修改 csproj文件,添加目标系统:

用 dotnet publish -r:linux-x64 针对linux平台发布,得到目标文件(夹),现在看看大小:

这个Hello World 控制台程序的目标文件,总大小达到了62.2 MB! 

二,为什么.net core自宿主程序这么大

原因有二,一是为了能在目标系统上 “独立” 运行,自宿主程序必须自带运行时,这无可厚非,二是不管是用 dotnet publish命令行发布还是用VS发布,它们都会不分青红皂白地把.net core类库整个发布到目标程序中,这正是使目标程序变大变肥的主要原因。

下面是发布后的部分文件列表,可以看出,很多的dll与这个hello world 程序毫无关系!

 

三,给 Linux .Net Core 自宿主应用程序瘦身

为什么要给“自宿主”程序瘦身?原因是,既然发布“自宿主”程序而不是便携式程序,一般都是程序作者或厂商希望产品能有更好的独立性,更看重程序本身的完整和纯净,不喜欢附带一些乱七八糟的东西。另外,程度体积小一些,能更方便地在卡片机(如树莓派)、小型专用设备这类存贮空间不太富裕的设备上部署,在Docker中部署,也能大大减小映像的大小,在同样的空间中运行更多的服务。

从前边的分析可以看出,自宿主应用程序之所有“肥大”,是因为有太多的无关的类库或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的体积。

原文地址:http://www.cnblogs.com/yunei/p/7436368.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323935.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汇编语言(三)之判断数值是否大于42H并统计个数

在内存中一串数值,判断数值是否大于42H并统计个数 程序运行: 代码: datas segmentidata equ 100hnums db idata dup(41h,42h,43h,42h,41h,43h,30h)count dw $-numsup dw 0down dw 0upNumber …

idea打war的问题

大家好,我是雄雄,欢迎关注微信公众号:👉雄雄的小课堂👈。 👨‍🏫前言 今天,记录个到现在为止还没搞清的问题,这个问题浪费了我几个小时的时间,基本上昨天晚上…

汇编语言(四)之比较字符串

输入两个字符串,比较字符串是否相同 程序运行: 代码: datas segmentstring1MaxLength db 0ffh,0 string1 db 100h dup(?)string1Number dw 0 string2MaxLength db 0ffh,0 string2 db 100h dup(?) string2Number…

.NET平台微服务项目汇集

最近博客园出现了一篇文章《微服务时代之2017年五军之战:Net PHP谁先死》,掀起了一波撕逼,作者只是从一个使用者的角度来指点江山,这个姿势是不对的。.NET Core就是专门针对模块化的微服务架构而设计,在微服务架构这方…

idea打war包时,JDK版本的问题解决方式

“大家好,我是雄雄,欢迎关注微信公众号:????雄雄的小课堂????。”????‍????前言今天,记录个到现在为止还没搞清的问题,这个问题浪费了我几个小时的时间,基本上昨天晚上啥也没干&#xff0…

汇编语言(五)之数组中正数和负数分离

将数组中的正数和负数分离到两个数组 程序运行: 代码: datas segmenta dw -1,2,3,4,-2,-3,5,6,7,8,9,-10,13,15,-5,-24,-36,34,53,-90count dw ($-a)/2p dw 20 dup(?)n dw 20 dup(?)pNumber dw 0…

dotnet使用Selenium执行自动化任务

如果要做百度文库,百度贴吧,百度知道签到,你,会怎么做?前不久我还会觉得这好像太麻烦了,now,soeasy。 自动化测试工具:Selenium Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行…

若依前后端部署之后验证码不显示

大家好,我是雄雄,欢迎关注微信公众号:👉雄雄的小课堂👈。 最近的几天都在搞publiccms的内容,从0到1实现,在花费了大量精力下,终于将一个门户站完完全全的实现了,且还可以…

汇编语言(六)之输出字符的前导后字符

输入一个字符,输出该字符的前导后字符 程序运行: 代码: datas segmenta db ?inputPrompt db input a lowercase character:$outputPrompt db 0dh,0ah,output …

若依部署上线之后验证码不显示的解决方法之一

“大家好,我是雄雄,欢迎关注微信公众号:????雄雄的小课堂????。”最近的几天都在搞publiccms的内容,从0到1实现,在花费了大量精力下,终于将一个门户站完完全全的实现了,且还可以自定义扩…

在 ASP.NET Core 中执行租户服务

本博文翻译自:http://gunnarpeipman.com/2017/08/tenant-providers/ 在我之前关于 Entity Framework core 2.0 全局查询过滤器的文章中,我提出了一个想法,当构建模型时,如何自动地将查询过滤器应用到所有的领域实体中&#xff0c…

【最全最详细】使用publiccms实现动态可维护的首页轮播

大家好,我是雄雄,欢迎关注微信公众号:👉雄雄的小课堂👈。 💁‍♂️前言 前几天,分享了一篇关于publiccms的教程,在这里:【最全最详细】publiccms使用教程,不…

汇编语言(七)之字符串转大写

输入一串字符,将字符串的小写字母转成大写字母 程序运行: 代码: datas segmentoriginalCaseMaxLength db 0ffh,0originalCase db 100h dup(?)uppercase db 100h dup(?)inputPrompt …

基于.NET CORE微服务框架 -谈谈surging API网关

1、前言 对于最近surging更新的API 网关大家也有所关注,也收到了不少反馈提出是否能介绍下Api网关,那么我们将在此篇文章中谈谈surging Api 网关 开源地址:https://github.com/dotnetcore/surging 2. API网关 简介 API 网关是服务提供者…

【最全最详细】使用publiccms实现动态可维护的导航菜单栏

“大家好,我是雄雄,欢迎关注微信公众号:????**雄雄的小课堂????。”????‍????前言昨天,给大家整理的是通过publiccms实现动态可维护的轮播图,有需要的小伙伴可以点击这里:publiccms实现动…

【上海】关于云计算,你想学习哪些知识,快让我来满足你

超高人气、干货十足的 免费云计算课堂 Microsoft Cloud Day云思塾 2017下半年再出发! 即将开启上海之旅,微软诚邀您参加! Microsoft Cloud Day是个啥? 这是为时一天的结合用户培训与经验分享的云计算免费研讨会,通…

【最全最详细】publiccms实现将公共部分提取成单独模块引入

大家好,我是雄雄,欢迎关注微信公众号:👉雄雄的小课堂👈。 🧘‍♂️往期系列 这两天一直在整理Publiccms系列的教程,有需要的小伙伴们可以点击以下链接查看: ☝publiccms使用教程&a…

汇编语言(九)之十六进制数值转二进制

输入四位十六进制的数值,将十六进制数值转二进制输出 程序运行: 代码: datas segmentmaxLength db 5hexLength db 0hex db 5 dup(?)bin db 100h dup(?)inputPr…

.NET Core 2.0 单元测试中初识 IOptionsMonitoramp;lt;Tamp;gt;

在针对下面设置 CookieAuthenticationOptions 的扩展方法写单元测试时遇到了问题。 public static IServiceCollection AddCnblogsAuthentication(this IServiceCollection services, IConfigurationSection redisConfiguration, Action<CookieAuthenticationOptions> …

汇编语言(十)之最小偶数

在数组中查找最小的偶数&#xff0c;并输出 程序运行&#xff1a; 代码&#xff1a; datas segmentminEven dw 0DATA dw 10 dup(101,1,21,81,5,261,3,421,4,541)DATACount dw ($-DATA)/type DATAoutputPrompt db min eve…