前言
AspNetCore技术栈在我们团队里的使用也有一段时间了,之前的部署方式一直是本地编译之后上传可执行文件到服务器,使用supervisor来管理进程这种很原始的方式。
参考之前的文章:
对于小项目来说尚可,够用,但是存在几个问题:
- 每次更新花费的时间太长了,无论是
Framework-Dependent
还是Self-Contained
,都要上传很大的文件~ - 更新的时候需要在supervisor里把进程停掉,不然无法覆盖
- 每次更新都是手动操作,一点也不geek
鉴于之前使用Django的项目里docker用得非常愉快,而且到处在宣传.netcore新技术对docker的官方支持有多好多好,于是我这也不能落后,必须上docker部署啊!
更关键的一点理由是,最近搞了个新的小项目,用到了Redis,但服务器上没装Redis,作为一个被docker惯坏的人,我也不可能去安装配置这些东西~
那就开始吧,直接从微软官方文档开始(MSDN真是好东西啊)
开始
事实上,我现在已经开始尝鲜使用 .net6.0
来新建项目了,默认的项目模板中就带有docker配置,完全是傻瓜式的,不用自己写什么配置文件,上传到服务器里就是docker build
一把梭(或者是docker-compose up
更好)
没有的也没事,把VS升级到最新的2022版本(其他版本应该也有,请自测),项目右键添加就能选择Docker支持了~
其实Rider也可以,并且我在此前也是一直使用Rider开发的,但截至本文编写时,Rider的2021.3版本还没推出,尚未支持 .net6.0 ,因此我没有使用Rider测试自动添加docker支持~
不想使用傻瓜式生成dockerfile也行,下面给出我部署的这个项目的dockerfile,可以参考一下。(项目名称为:DataMiddlePlatform
)
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["DataMiddlePlatform/DataMiddlePlatform.csproj", "DataMiddlePlatform/"]
RUN dotnet restore "DataMiddlePlatform/DataMiddlePlatform.csproj"
COPY . .
WORKDIR "/src/DataMiddlePlatform"
RUN dotnet build "DataMiddlePlatform.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "DataMiddlePlatform.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DataMiddlePlatform.dll"]
其实dockerfile基本可以不管的,因为 .net6.0
项目生成的时候,都会有个dockerfile,在本项目中我只修改了docker-compose.yml
文件,因为要增加一个Redis容器~
以下是我的docker-compose.yml
文件代码
version: '3.4'
services:
redis:
image: redis
expose:
- 6379
web:
image: ${DOCKER_REGISTRY-}web
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=https://+:443;http://+:80
build:
context: .
dockerfile: DataMiddlePlatform/Dockerfile
depends_on:
- redis
ports:
- "15002:80"
- "15003:443"
不多解释了,docker-compose的用法详见官方文档~
环境切换
之前我们在docker-compose.yml
里添加了Redis容器,并在web镜像里添加了依赖,所以在Web容器里访问Redis是用redis:6379
这样的地址,不像本地开发时一样使用localhost:6379
,如果在Django里就要在settings.py
里根据环境变量判断了(我的Django-Starter
框架集成了自动识别)
而AspNetCore的基础设施做得很完善,默认就有development
、staging
、production
这三个环境,每个环境有对应的appsettings.json
配置文件,所以只要在配置文件里区分不同的Redis地址就好了,如果是其他数据库的配置也同理,真是方便啊~!
到本项目中就是,在appsettings.Development.json
文件里,Redis的连接地址是"Connection": "127.0.0.1:6379"
,本地开发时使用本地安装的Redis服务。
然后appsettings.json
文件里,使用"Connection": "redis:6379"
,docker部署的时候,使用docker里的Redis服务~
完美
部署
既然写完了dockerfile
和docker-compose.yml
,那部署这块也没啥好说的,就把整个代码文件夹上传到服务器,之后一行命令搞定:docker-compose up
~
因为这AspNetCore本身性能就很可以了,小项目都不用nginx来提供静态文件服务,方便得很~!
要更新服务的话,目前就是上传代码之后执行docker-compose up --build
重新构建,因为只需要上传代码文件,这样下来每次更新的速度快多了,而且可以写脚本在git commit
后一键执行更新,也…算是自动了吧…hhh
小结
微服务是发展趋势,应用从旧的部署方式到容器化是很重要的一步,虽然我们团队的Java还处在一个jar包丢上去supervisor运行的阶段,(吐槽:后面甚至有项目都没有挂supervisor,直接shell里执行起来,什么时候挂了都不知道)
经过这段时间的实践下来,AspNetCore还是很可靠的扛住了不低的并发,也有比较完善的生态(虽然第三方库比不上Java和Python,但完完全全够好用了),开发效率高(但学习门槛也不低,至少比Django难),综合优缺点下来,加上我自己对这框架的掌握也还很粗浅,所以只能小范围推广了~
我对于AspNetCore目前还处在摸索阶段,好用是好用,就是在工作中用得还不够多,不够熟悉,加上之前折腾Django的经历让我尝到了动态语言开发的甜头,所以不会短时间把团队的技术栈全部迁移到NetCore上去,毕竟会C#的人还是不够多,新招进来的应届生来现学也有不低的门槛,项目进度也禁不起这种折腾…
我还是很喜欢微软的这套技术栈,它真的很好用,目前以及后续的小项目毫无疑问都会选择这套东西,但对于提高多少生产力,我目前是没多少底气的,接下来要调研一番构建自动化、部署自动化方面的技术,哎,小团队的基础设施不足真是痛苦…… 难怪现在Serverless开始流行起来了,低代码平台也起来了,程序员终究要自己砸自己的饭碗…
参考资料
- 托管和部署 ASP.NET Core | Microsoft Docs
- 在 Docker 容器中托管 ASP.NET Core | Microsoft Docs
- .NET 微服务。 适用于容器化 .NET 应用程序的体系结构 | Microsoft Docs