網站首頁 編程語言 正文
現階段的問題
現在是云原生和容器化時代,.NET Core對于云原生來說有非常好的兼容和親和性,dotnet社區以及微軟為.NET Core提供了非常方便的鏡像容器化方案。所以現在大多數的dotnet程序都是部署在各種容器化環境中,比如我們常見的Docker。
微軟官方為.NET提供的許多Docker鏡像,讓我們可以很方便的創建容器化的.NET應用。如下所示就是部分官方提供的不同操作系統的鏡像。
其它更詳細的內容大家可以點擊后面的網址查看:https://hub.docker.com/_/microsoft-dotnet-runtime/
使用VS新建一個項目,微軟官方給出的多段構建Dockerfile如下所示:
# 使用aspnet runtime鏡像作為基礎鏡像 FROM mcr.microsoft.com/dotnet/aspnet:6.0-focal AS base WORKDIR /app EXPOSE 80 # 使用sdk鏡像進行編譯 FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build WORKDIR /src COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"] RUN dotnet restore "WebApplication1/WebApplication1.csproj" COPY . . WORKDIR "/src/WebApplication1" RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build # 使用build鏡像發布 FROM build AS publish RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish # 拷貝編譯結果到base鏡像,完成鏡像打包 FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "WebApplication1.dll"]
現在看起來一切都很美好,但是假設我們遇到某一些線上CPU 100%、內存占用率很高或者程序突然停止響應等問題我們需要使用dotnet-trace
、dotnet-dump
等工具時就會發現使用不了。
而且在沒有安裝.NET SDK的情況下,我們也無法安裝dotnet tool。
解決方案
1.直接使用命令安裝dotnet sdk,然后再安裝dotnet tool,微軟在官網給出的非常方便的安裝方案,但是這不是我們想要的,畢竟每次還得下載多麻煩。
2.構建最終鏡像使用sdk
鏡像,這樣的話我們就可以直接安裝好這些工具,這也不是我們想要的,因為sdk
鏡像太大了,不利于我們分發和下載(自建機房的鈔能力除外)。
3.就是我們今天提到的方案,我們可以利用Docker多段構建,使用sdk
鏡像安裝好dotnet tool以后,直接COPY到我們runtime的鏡像,然后在runtime的鏡像中使用。
# 使用aspnet runtime鏡像作為基礎鏡像 FROM mcr.microsoft.com/dotnet/aspnet:6.0-focal AS base WORKDIR /app EXPOSE 80 # 使用sdk鏡像進行編譯 FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build WORKDIR /src COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"] RUN dotnet restore "WebApplication1/WebApplication1.csproj" COPY . . WORKDIR "/src/WebApplication1" RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build # !!! 在build鏡像安裝dotnet tools RUN dotnet tool install -g dotnet-dump \ && dotnet tool install -g dotnet-trace # 使用build鏡像發布 FROM build AS publish RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish # 拷貝編譯結果到base鏡像,完成鏡像打包 FROM base AS final WORKDIR /app # !!! 從build鏡像中把dotnet工具COPY出來 并設置為PATH COPY --from=build /root/.dotnet/tools /root/.dotnet/tools ENV PATH="$PATH:/root/.dotnet/tools" COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "WebApplication1.dll"]
其中關鍵就是這兩步,在build中使用dotnet tool來安裝好所需要的工具,然后復制到runtime鏡像中。
... # !!! 在build鏡像安裝dotnet tools RUN dotnet tool install -g dotnet-dump \ && dotnet tool install -g dotnet-trace ... # !!! 從build鏡像中把dotnet工具COPY出來 并設置為PATH COPY --from=build /root/.dotnet/tools /root/.dotnet/tools ENV PATH="$PATH:/root/.dotnet/tools"
當然我們可以打包一個包含好工具的runtime,供后面使用,就不用每次都安裝tool了。我個人比較喜歡使用Ubuntu作為基礎鏡像,大家也可以用Alpine之類的基礎鏡像來進一步縮小體積。
# 使用sdk鏡像進行編譯 FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build # !!! 在build鏡像安裝dotnet tools RUN dotnet tool install -g dotnet-dump \ && dotnet tool install -g dotnet-trace # 使用aspnet runtime鏡像作為基礎鏡像 FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS base WORKDIR /app # !!! 從build鏡像中把dotnet工具COPY出來 并設置為PATH COPY --from=build /root/.dotnet/tools /root/.dotnet/tools ENV PATH="$PATH:/root/.dotnet/tools"
最終鏡像也很小,當然我們可以使用單文件發布和Native AOT讓鏡像它變得更小,那就是后話了,不在本文中介紹。
常用的工具
因為公司是自建機房,所以對于存儲和網絡帶寬都比較寬裕,我們一般會在生產環境運行的鏡像中安裝下面這些工具。
RUN dotnet tool install -g dotnet-dump \ && dotnet tool install -g dotnet-trace \ && dotnet tool install -g dotnet-counters \ && dotnet tool install -g dotnet-sos \ && dotnet tool install -g dotnet-gcdump \ && dotnet tool install -g dotnet-monitor \ && dotnet tool install -g dotnet-symbol \ && dotnet tool install -g JetBrains.dotTrace.GlobalTools
在遇到線上問題的時候,排查起來非常方便,對于一些內存泄漏和CPU滿的問題,配合dotTrace很容易就能定位到問題所在。
總結
本文編寫的初衷是因為在群里有很多小伙伴遇到生產環境性能問題的時候,.NET的runtime鏡像中沒有帶一些工具,安裝和使用起來很麻煩,所以分享一些我們公司內部一些技巧,希望能幫到大家。
原文鏈接:https://www.cnblogs.com/InCerry/p/how-to-build-dotnet-image-with-trace-tool.html
相關推薦
- 2022-04-12 網絡編程——Http請求方式Get與Post
- 2022-03-16 C#語言主要語言區域_C#教程
- 2022-05-11 Redis之RedisTemplate配置方式(序列和反序列化)_Redis
- 2022-07-03 C#枚舉類型與位域枚舉Enum_C#教程
- 2022-04-03 Android?App應用退到后臺顯示通知的實現方法_Android
- 2023-07-16 spring boot 異步async
- 2022-05-20 Shell編寫格式和執行方式
- 2023-12-07 mitt 的使用
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支