今天我们分析了博客站点的2次故障(故障一、故障二),发现一个巧合的地方,.NET 5.0 正式版的 docker 镜像是在11月10日提前发布上线的。
而在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
文章来源: 博客园
- 还没有人评论,欢迎说说您的想法!