Skip to the content.

MS.Microservice

微服务架构设计

.NET 微服务 - 体系结构电子书-原文英文版

.NET 微服务 - 体系结构电子书

Martin Fowler 对微服务特征的概括:微服务

微服务与 DDD 基本概念

应用程序包括

应用程序必须要高可用,要支持垂直的向外拓展,因为有些子系统还会要求更高的伸缩性。

并且应用程序必须是可以部署到多种架构环境的(多个公共云或本地云),并且理论上还是要跨平台的,要很容易的从 Windows 和 Linux 之间切换。

微服务拆分的好处:

微服务的缺点:

微服务分层

微服务验证

编码一定免不了的就是异常,以我现在的经验业务验证一般都是写在应用层。还有一些就是请求接口参数的基本验证逻辑,向这种一般都是直接从业务层返回给 UI 的。还有一种验证就是领域验证,比如聚合根添加实体的时候会对领域实体属性进行符合领域需求的验证判断。我们一般的做法是直接抛出一个属于领域层特定的错误类型如DomainException,然后在应用层或是全局异常处理程序中对消息展现给 UI。这样就做到了领域层与应用层的逻辑解耦。

public void check() {
   if (date == null) throw new IllegalArgumentException("date is missing");
   LocalDate parsedDate;
   try {
     parsedDate = LocalDate.parse(date);
   }
   catch (DateTimeParseException e) {
     throw new IllegalArgumentException("Invalid format for date", e);
   }
   if (parsedDate.isBefore(LocalDate.now())) throw new IllegalArgumentException("date cannot be before today");
   if (numberOfSeats == null) throw new IllegalArgumentException("number of seats cannot be null");
   if (numberOfSeats < 1) throw new IllegalArgumentException("number of seats must be positive");
 }

这个做法是没错的,但是我们要知道,这种做法是有代价了,尽管结构,代码都优雅了,但是请记住这是以抛出异常的方式为代价实现的。我们知道发生异常会给应用程序带来非常大的性能开销,会由用户态切换成内核态将错误信息栈拿到返回给上层应用。那么我们其实是可以通知模式验证代替这种跑错的方式的。

具体详见用通知代替抛出异常

微服务模块组成

分布式链路追踪

分布式链路追踪要遵循 OpenTelemetry API 规范。

分布式系统模式

分布式锁

关于 Docker 部署

利用 Visual Studio 2019 工具添加 docker 支持,会根据项目结构自动添加两个文件结构

关于自动生成的 Dockerfile 文件,如果项目没有用到私有 nuget 库的话,一般是没有问题的。如果用了私有库,那么我们还得在 Dockerfile 文件添加 nuget.config 文件,来告诉 dokcer 在 restore 时要读取的 nuget 服务地址。举个例子:

#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/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
#下面一行添加私有nuget库
COPY ["nuget.config","src/MS.Microservice.Web/"]
#上面一行添加私有nuget库
COPY ["src/MS.Microservice.Web/MS.Microservice.Web.csproj", "src/MS.Microservice.Web/"]
COPY ["src/MS.Microservice.IntegrateEvent/MS.Microservice.IntegrateEvent.csproj", "src/MS.Microservice.IntegrateEvent/"]
COPY ["src/MS.Microservice.Database/MS.Microservice.Database.csproj", "src/MS.Microservice.Database/"]
COPY ["src/MS.Microservice.Repostitory/MS.Microservice.Repostitory.csproj", "src/MS.Microservice.Repostitory/"]
COPY ["src/MS.Microservice.Domain/MS.Microservice.Domain.csproj", "src/MS.Microservice.Domain/"]
COPY ["src/MS.Microservice.Core/MS.Microservice.Core.csproj", "src/MS.Microservice.Core/"]
RUN dotnet restore "src/MS.Microservice.Web/MS.Microservice.Web.csproj"
COPY . .
WORKDIR "/src/src/MS.Microservice.Web"
RUN dotnet build "MS.Microservice.Web.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MS.Microservice.Web.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MS.Microservice.Web.dll"]
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="private.server" value="http://192.168.1.101:8001/nuget" />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
</configuration>

2020-12-24 修改

由于本项目增加了文件 Directory.Build.props 以及 global.json 文件,所以生成项目是要依赖解决方案的。在上面的的 dockerfile 内容只是复制了各项目的内容,没有 *.sln 做上下文环境支撑,所以无法正常运行。

需要将对应的项目目录结构全部拷贝至 docker 环境中,如最新的 dockerfile 内容如下:(⚠️要放在 sln 同目录下)

#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:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ["Directory.Build.props","src/"]
COPY ["global.json","src/"]
COPY ["MS.Microservice.sln","src/"]
COPY ["nuget.config","src/"]
COPY ["src/MS.Microservice.Web/MS.Microservice.Web.csproj", "src/MS.Microservice.Web/"]
COPY ["src/MS.Microservice.IntegrateEvent/MS.Microservice.IntegrateEvent.csproj", "src/MS.Microservice.IntegrateEvent/"]
COPY ["src/MS.Microservice.Database/MS.Microservice.Database.csproj", "src/MS.Microservice.Database/"]
COPY ["src/MS.Microservice.Repostitory/MS.Microservice.Repostitory.csproj", "src/MS.Microservice.Repostitory/"]
COPY ["src/MS.Microservice.Domain/MS.Microservice.Domain.csproj", "src/MS.Microservice.Domain/"]
COPY ["src/MS.Microservice.Core/MS.Microservice.Core.csproj", "src/MS.Microservice.Core/"]
RUN dotnet restore "src/MS.Microservice.Web/MS.Microservice.Web.csproj"
COPY . .

WORKDIR "/src/src/MS.Microservice.Web"
RUN dotnet build "MS.Microservice.Web.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MS.Microservice.Web.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MS.Microservice.Web.dll"]