《.NET 5.0 背锅案》第1集:验证 .NET 5.0 正式版 docker 镜像问题

今天咱们分析了博客站点的2次故障(故障一故障二),发现一个巧合的地方,.NET 5.0 正式版的 docker 镜像是在11月10日提早发布上线的。html

而在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服务器上生成应用的生产环境镜像)。web

如今能够进入这2个发布版本的镜像进行验证docker

$ 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。app

因此这2次故障时用的都是基于 .NET 5.0 正式版的镜像,并且11月10日至11月12日期间,咱们只进行了2次发布,2次都出现了故障。curl

若是片面地从这个巧合来看,彷佛故障与 .NET 5.0 正式版镜像有关,这时你可能立马提出疑问,一样是基于 .NET 5.0 正式版的镜像,为何今天早上发布没有出现故障?tcp

根据咱们的分析判断,故障的触发与发布时的并发请求量有关,2次故障时的发布时间分别是在 20:30 与 19:30 左右,这2个发布时间点的并发量差很少,而今天早上发布时并发量要小不少,并且咱们其余并发量不大的应用升级到 .NET 5.0 没有出现过这个问题,因此今天早上发布正常极可能是由于没有到达触发故障的并发量。memcached

另外,今天早上发布时咱们已经将博客项目依赖的下面这些 nuget 包升级到 .NET 5.0 正式版对应的版本,昨天晚上在处理故障时也进行过这个升级发布尝试,但没有解决问题,与故障关联的可能性很小,但从中能够获得的信息是故障时项目代码是基于 .NET 5.0 RC 2,生产环境部署的 runtime 是基于 .NET 5.0 正式版。ui

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%没问题,但至少能够知道在周五晚上的并发量下不会触发问题。

【更新】此次发布没有出现故障,下图是 memcached 服务器 tcp 链接数监控图

附博客项目所使用的 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