《.NET 5.0 背鍋案》第1集:驗證 .NET 5.0 正式版 docker 映象問題

部落格園團隊發表於2020-11-13

今天我們分析了部落格站點的2次故障(故障一故障二),發現一個巧合的地方,.NET 5.0 正式版的 docker 映象是在11月10日提前釋出上線的。

《.NET 5.0 背鍋案》第1集:驗證 .NET 5.0 正式版 docker 映象問題

而在11月10日下午4點左右,由於 CI 伺服器磁碟空間用完,我們進行了磁碟清理,刪除了 CI 伺服器上的所有映象,清理之前 CI 伺服器上 .NET 5.0 映象版本對應的是 .NET 5.0 RC 2,所以11月10日晚上釋出部落格站點時,CI 伺服器重新下載了映象,這時正好下載了 .NET 5.0 正式版的 docker 映象,所以釋出時部落格系統的映象是基於 .NET 5.0 正式版(釋出時會在CI伺服器上生成應用的生產環境映象)。

現在可以進入這2個釋出版本的映象進行驗證

$ docker run -t blog-web:2.3.101 dotnet --info
  Host (useful for support):
  Version: 5.0.0
  Commit:  cf258a14b7

$ docker run -t blog-web:2.3.102 dotnet --info
  Host (useful for support):
  Version: 5.0.0
  Commit:  cf258a14b7

 Commit: cf258a14b7 對應的正是 .NET 5.0 正式版。

對比一下11月10日之前生成的映象

$ docker run -t blog-web:2.3.100 dotnet --info
  Host (useful for support):
  Version: 5.0.0-rc.2.20475.5
  Commit:  c5a3f49c88

不僅 Commit 不一樣,而且 Version 中包含 rc.2。

所以這2次故障時用的都是基於 .NET 5.0 正式版的映象,而且11月10日至11月12日期間,我們只進行了2次釋出,2次都出現了故障。

如果片面地從這個巧合來看,似乎故障與 .NET 5.0 正式版映象有關,這時你可能立馬提出疑問,同樣是基於 .NET 5.0 正式版的映象,為什麼今天早上釋出沒有出現故障?

根據我們的分析判斷,故障的觸發與釋出時的併發請求量有關,2次故障時的釋出時間分別是在 20:30 與 19:30 左右,這2個釋出時間點的併發量差不多,而今天早上釋出時併發量要小很多,而且我們其他併發量不大的應用升級到 .NET 5.0 沒有出現過這個問題,所以今天早上釋出正常很可能是因為沒有到達觸發故障的併發量。

另外,今天早上釋出時我們已經將部落格專案依賴的下面這些 nuget 包升級到 .NET 5.0 正式版對應的版本,昨天晚上在處理故障時也進行過這個升級釋出嘗試,但沒有解決問題,與故障關聯的可能性很小,但從中可以得到的資訊是故障時專案程式碼是基於 .NET 5.0 RC 2,生產環境部署的 runtime 是基於 .NET 5.0 正式版。

Microsoft.Extensions.Primitives
System.Interactive.Async
Microsoft.Extensions.Http
Microsoft.Extensions.Logging.Abstractions
System.ServiceModel.Primitives
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
System.Text.Encoding.CodePages

雖然正式版 runtime 映象造成這個故障的可能性很小,但考慮到問題的詭異性,我們不想放過一個蛛絲馬跡,所以準備今天晚上再次釋出試試,計劃的釋出時間是21:30,但是由於今天是週五,晚上的併發請求量比前2次故障期間小一些,即使沒有出現問題,也不能說明100%沒問題,但至少可以知道在週五晚上的併發量下不會觸發問題。

附部落格專案所使用的 Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list
RUN apt-get update && apt-get install -y curl

FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY src/*.sln src/*.props src/NuGet.config ./
COPY src/*/*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p ${file%.*}/ && mv $file ${file%.*}/; done
RUN dotnet restore "BlogServerCore.sln"
COPY src/. .
RUN dotnet build "BlogServerCore.sln" -c Release --no-restore

FROM build AS publish
WORKDIR /src/BlogServer.WebApi
RUN dotnet publish "BlogServer.WebApi.csproj" -c Release -o /app/publish --no-build

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
RUN echo "dotnet BlogServer.WebApi.dll" > run.sh
HEALTHCHECK --interval=5s --timeout=20s \
    CMD curl -fs -o /dev/null localhost/alive || exit 1

相關文章