使用 ASP.NET Core 的微服务

作者 : 慕源网 本文共7828个字,预计阅读时间需要20分钟 发布时间: 2022-03-7 共498人阅读

微服务

微服务一词描绘了一种软件开发风格,这种风格已经从当代趋势发展为旨在提高大规模开发和管理软件解决方案的速度和效率的实践。微服务更多是关于应用一定数量的原则和架构模式作为架构。每个微服务独立存在,但另一方面,也都相互依赖。一个项目中的所有微服务都按照自己的节奏部署在生产环境中,在云端、独立、并存。

在本文中,我们将学习微服务的概念、架构以及如何在 .NET 和 C# 中创建微服务。您还将学习使用 docker 容器在 .NET 中构建、部署和测试微服务的步骤。

微服务架构

Microsoft Docs 中的下图显示了微服务体系结构样式。

除了微服务本身之外,微服务架构中还有各种组件。

Management。维护服务的节点。

Identity Provider(身份提供者)。在分布式网络中管理身份信息并提供身份验证服务。

Service Discovery(服务发现)。跟踪服务和服务地址和端点。

API Gateway(API 网关)。作为客户端的入口点。来自客户端的单点联系,反过来返回来自底层微服务的响应,有时是来自多个底层微服务的聚合响应。

CDN。为分布式网络中的页面和 Web 内容等静态资源提供服务的内容交付网络

Static Content(静态内容)页面和网页内容等静态资源

微服务独立部署,每个服务都有自己的数据库,因此底层微服务如下图所示。

单体与微服务架构

单体应用程序更像是一个完整的包,将所有相关的所需组件和服务封装在一个包中。

以下是完全封装或基于服务的单体架构的图解表示。

微服务是一种创建小型服务的方法,每个服务都在自己的空间中运行,并且可以通过消息传递进行通信。这些是直接调用自己的数据库的独立服务。

以下是微服务架构的图解表示。

在单体架构中,即使遵循面向服务架构的方法,所有功能的数据库都保持不变,而在微服务中,每个服务都将拥有自己的数据库。

Docker 容器和 Docker 安装

像 Docker 等容器对操作系统资源进行切片,例如网络堆栈、进程命名空间、文件系统层次结构和存储堆栈。Docker 更像是虚拟化操作系统。在此处了解有关码头工人的更多信息。打开URL 并单击从 Docker 中心下载。下载后,登录 Docker 并按照说明安装 Docker for Windows。

使用 ASP.NET Core 的微服务

本节将通过图片逐步演示如何使用 ASP.NET Core 创建产品微服务。该服务将使用 ASP.NET Core 2.1 和 Visual Studio 2017 构建。Asp.NET Core 与 VS 2017 集成。该服务将拥有自己的 DBcontext 和数据库以及独立的存储库,以便可以独立部署该服务。

创建 ASP.NET Core 应用程序解决方案

  1. 打开 Visual Studio 并添加一个新项目。

选择应用程序作为 ASP.NET Core Web 应用程序并给它一个有意义的名称。

接下来,选择 API 作为项目的类型,并确保选择“启用 Docker 支持”选项,操作系统类型为 Linux。

解决方案如下所示。

添加模型

  1. 将一个名为“Model”的新文件夹添加到项目中。

  1. 在 Models 文件夹中,添加一个名为 Product 的类。

  1. 向产品类添加一些属性,例如 Id、Name、Description、Price。产品也应该是某种类型的,为此,定义了一个类别模型,并将一个 CategoryId 属性添加到产品模型中。

  1. 同样,添加类别模型。

启用 EF Core

尽管 .NET Core API 项目具有对 EF Core 的内置支持,并且所有相关依赖项都在项目创建和编译时下载,可以在项目的 SDK 部分下找到,如下所示。

Microsoft.EntityFrameworkCore.SqlServer (2.1.1) 应该是下载的 SDK 中的包。如果它不存在,它可以通过 Nuget 包显式添加到项目中。

添加 EF Core DbContext

需要一个数据库上下文,以便模型可以与数据库交互。

  1. 将名为 DBContexts 的新文件夹添加到项目中。

  1. 添加一个名为 ProductContext 的新类,其中包括 Products 和 Categories 的 DbSet 属性。OnModelCreating 是一种可以将主数据播种到数据库的方法。因此,添加 OnModelCreating 方法并在创建数据库时将最初将添加到数据库中的一些示例类别添加到类别表中。

ProductContext 代码

using Microsoft.EntityFrameworkCore;
using ProductMicroservice.Models;

namespace ProductMicroservice.DBContexts
{
  public class ProductContext : DbContext
  {
    public ProductContext(DbContextOptions<ProductContext> options) : base(options)
    {
    }
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
      modelBuilder.Entity<Category>().HasData(
          new Category
          {
            Id = 1,
            Name = "Electronics",
            Description = "Electronic Items",
          },
          new Category
          {
            Id = 2,
            Name = "Clothes",
            Description = "Dresses",
          },
          new Category
          {
            Id = 3,
            Name = "Grocery",
            Description = "Grocery Items",
          }
      );
    }

  }
}

在 appsettings.json 文件中添加连接字符串。

打开 Startup.cs 文件以添加 EF Core 的 SQL 服务器数据库提供程序。添加代码 services.AddDbContext<ProductContext>(o => o.UseSqlServer(Configuration.GetConnectionString(“ProductDB”))); 在 ConfigureServices 方法下。请注意,在 GetConnectionString 方法中,传递了添加到 appsettings 文件中的连接字符串的键名。

添加Repository

存储库作为微服务的一个微组件,它封装了数据访问层,并有助于数据的持久性和可测试性。

  1. 在项目中添加一个名为 Repository 的新文件夹,并在该文件夹中添加一个接口名称 IProductRepository。在对 Product 微服务执行 CRUD 操作的接口中添加方法。

  1. 在实现 IProductRepository 的同一 Repository 文件夹中添加一个名为 ProductRepository 的新具体类。所有这些方法都需要:

  1. 通过访问上下文方法添加方法的实现。ProductRepository.cs
using Microsoft.EntityFrameworkCore;
using ProductMicroservice.DBContexts;
using ProductMicroservice.Models;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ProductMicroservice.Repository
{
  public class ProductRepository: IProductRepository
  {
    private readonly ProductContext _dbContext;

    public ProductRepository(ProductContext dbContext)
    {
      _dbContext = dbContext;
    }
    public void DeleteProduct(int productId)
    {
      var product = _dbContext.Products.Find(productId);
      _dbContext.Products.Remove(product);
      Save();
    }

    public Product GetProductByID(int productId)
    {
      return _dbContext.Products.Find(productId);
    }

    public IEnumerable<Product> GetProducts()
    {
      return _dbContext.Products.ToList();
    }

    public void InsertProduct(Product product)
    {
      _dbContext.Add(product);
      Save();    }

    public void Save()
    {
      _dbContext.SaveChanges();
    }

    public void UpdateProduct(Product product)
    {
      _dbContext.Entry(product).State = EntityState.Modified;
      Save();
    }
  }
}
  1. 打开项目中的Startup类,将代码添加为services.AddTransient<IProductRepository, ProductRepository>(); 在 ConfigureServices 方法中,以便在需要时在运行时解析存储库的依赖关系。

添加控制器

微服务应该有一个端点,需要控制器将 HTTP 方法作为服务方法的端点公开给客户端。

  1. 右键单击 Controllers 文件夹并添加一个新的 Controller,如下所示。

  1. 选择选项“API Controller with read/write actions”来添加控制器。

  1. 将控制器的名称命名为 ProductController。

  1. 将在 Controllers 文件夹中添加一个 ProductController 类,其中包含默认的读/写操作,稍后将替换为产品读/写操作,并创建 HTTP 方法作为服务的端点。

  1. ValuesController 可以删除,因为它不需要。

通过调用存储库方法将实现添加到方法,如下所示。为了理解这个概念,这里显示了基本的实现。这些方法可以是属性路由的,并且可以根据需要用更多的注释来装饰。

ProductRepository.cs

using Microsoft.AspNetCore.Mvc;
using ProductMicroservice.Models;
using ProductMicroservice.Repository;
using System;
using System.Collections.Generic;
using System.Transactions;

namespace ProductMicroservice.Controllers
{
  [Route("api/[controller]")]
  [ApiController]
  public class ProductController : ControllerBase
  {

    private readonly IProductRepository _productRepository;

    public ProductController(IProductRepository productRepository)
    {
      _productRepository = productRepository;
    }

    [HttpGet]
    public IActionResult Get()
    {
      var products = _productRepository.GetProducts();
      return new OkObjectResult(products);
    }

    [HttpGet("{id}", Name = "Get")]
    public IActionResult Get(int id)
    {
      var product = _productRepository.GetProductByID(id);
      return new OkObjectResult(product);
    }

    [HttpPost]
    public IActionResult Post([FromBody] Product product)
    {
      using (var scope = new TransactionScope())
      {
        _productRepository.InsertProduct(product);
        scope.Complete();
        return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
      }
    }

    [HttpPut]
    public IActionResult Put([FromBody] Product product)
    {
      if (product != null)
      {
        using (var scope = new TransactionScope())
        {
          _productRepository.UpdateProduct(product);
          scope.Complete();
          return new OkResult();
        }
      }
      return new NoContentResult();
    }

    [HttpDelete("{id}")]
    public IActionResult Delete(int id)
    {
      _productRepository.DeleteProduct(id);
      return new OkResult();
    }
  }
}

Entity Framework Core Migrations

迁移允许我们提供代码来将数据库从一个版本更改为另一个版本。

  1. 打开包管理器控制台。

要启用迁移,请键入命令 Add-Migration 并为其指定一个有意义的名称,例如 InitialCreate,然后按 Enter。

执行命令后,如果我们现在查看我们的解决方案,我们会看到有一个新的 Migrations 文件夹。它包含两个文件。一,我们当前上下文模型的快照。随意检查文件。这些文件非常不言自明。

为了确保将迁移应用于数据库,还有另一个命令。它称为 update-database 如果执行,迁移将应用于当前数据库。

检查 SQL Server Management Studio 以验证数据库是否已创建。

查看类别表的数据时,会显示三个类别的默认主数据。

运行产品微服务

该服务可以通过 IIS Express 即 Visual Studio 默认运行,也可以通过 Docker 容器运行。

通过 IIS Express

在 Visual Studio 中选择 IIS Express,如下所示,然后按 F5 或单击该 IIS Express 按钮本身。

启动浏览器页面后,应用程序将启动。由于它没有任何内容可显示,因此它将是空白的,但可以通过任何 API 测试客户端测试该服务。这里 Postman 用于测试服务端点。保持打开状态并运行应用程序。

如果 Postman 不在机器上,请安装它并启动它。

Post

测试 POST 方法;即创建一个新资源,在 postman 中选择方法为 POST 并提供端点,即https://localhost:44312/api/product并在 Body 部分中,添加类似于具有 Product 模型属性的 JSON,如下所示和点击发送。

响应也与产品的 Id 一起返回。

控制器的“Post”方法负责在数据库中创建资源并发送响应。

该行 return CreatedAtAction(nameof(Get), new { id=product.Id }, product); 返回已创建资源的位置,可以在“标头”选项卡下响应的“位置”属性中进行检查。

对产品表执行选择查询,并为新创建的产品显示添加的行。

以类似的方式再创造一个产品。

GET

现在使用相同的地址执行 GET 请求,两条记录显示为 JSON 结果响应。

DELETE

通过选择 DELETE 作为动词并附加 id 作为 1(如果需要删除 id 为 1 的产品)来执行删除请求,然后按发送。

在数据库中,一条 ID 为 1 的记录被删除。

PUT

PUT 动词负责更新资源。选择 PUT 动词,提供 API 地址,并在正文部分中,以 JSON 格式提供需要更新的产品的详细信息。例如,使用 ID 2 更新产品并将其名称、描述和价格从三星更新为特定于 iPhone。按发送。

检查数据库以查看更新的产品。

通过 Docker 容器

可以通过在 docker 命令提示符下运行的 docker 命令以及使用 Visual Studio 来运行服务。由于我们添加了 docker 支持,使用 Visual Studio 在 docker 容器中运行服务很容易。

  1. 在解决方案中添加container orchestrator support ,如下所示。

  1. 这将要求编排器。选择 Docker Compose 并按 OK。

一旦添加到解决方案中,解决方案将如下所示,具有 docker-compose 和 dockerignore 和 docker-compose.yml 及其覆盖文件。

保存解决方案后,它会在容器下构建项目并创建 docker 映像。保存解决方案后,可以在输出窗口中看到所有命令的执行。

  1. 在管理员模式下打开命令提示符并导航到项目文件所在的同一文件夹。

  1. 运行命令 docker images 以查看所有创建的图像。我们看到 ProductMicroserviceimage 是最新的。

  1. 现在使用 Docker 作为选项运行应用程序,如下所示。

  1. 现在,运行命令 docker ps 查看正在运行的容器。它显示容器正在 32773:80 端口上运行。

  1. 由于容器处于运行状态,所以最好测试一下现在在容器下运行的服务。要测试服务,请将地址中的“values”替换为“product”,如下所示。理想情况下,它应该获取产品详细信息。但它给出了例外,如下所示。

  1. 在 IIS Express 下运行相同的东西可以正常工作,即在端口 44312 上。用product 替换“values”以获取产品详细信息,

  1. 由于在 IIS Express 应用程序中运行良好,而不是在 docker 容器中,错误清楚地表明 SQL 服务器有问题,它不理解我们的 docker 容器,或者它没有在 docker 容器下运行。在这种情况下,docker 容器在主机内作为单独的机器运行。因此,要连接到主机中的 SQL 数据库,需要启用到 SQL 的远程连接。我们可以解决这个问题。
  2. 打开 SQL Server 配置管理器。现在选择 MSSQLSERVER 的协议并在 TCP/IP 部分下获取 IPAll 端口号。

  1. JSON 文件中提到的连接字符串指向 docker 容器不理解的本地数据源。它需要具有端口和 SQL 身份验证的正确 IP 地址。因此,请提供相关详细信息,即数据源作为 IP 地址、端口号和 SQL 身份验证详细信息,如下所示。

  1. 现在再次使用 Docker 作为选项运行应用程序,就像之前所做的那样。

这次收到响应。

  1. 在 Postman 中进行相同的测试。

  1. 使用 IIS Express URL 再次测试。

这证明微服务运行在两个端点上,两个操作系统上独立部署在本地。

结论

微服务是围绕特定业务能力构建的服务,可以独立部署,称为限界上下文。这篇关于微服务的文章重点介绍了微服务是什么以及它们相对于单体服务架构的优势。本文详细介绍了使用 ASP.NET Core 开发微服务并通过 IIS 和 Docker 容器运行它。同样,该服务可以有多个镜像,并且可以在同一时间点在多个容器上运行。

 


慕源网 » 使用 ASP.NET Core 的微服务

常见问题FAQ

程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!

发表评论

开通VIP 享更多特权,建议使用QQ登录