API Gateway 主题可以很容易地承载几篇类似这样的博文。在本节中,我们专门针对在 ASP.NET Core 中开发的应用程序使用Apache APISIX API Gateway**(假设你有一个管理产品的 API)并提供如何使用docker compose部署多个镜像的简单示例。

现在在进入演示会议之前。我们先来讨论一下什么是**API网关?**🤔

API网关作为单一入口点

在当今的微服务架构中,我们通常为特定产品创建多个微服务,客户端应用程序通常需要使用多个微服务的功能。对于这些服务中的每一个,我们将有不同的端点从外部世界访问这些服务,暴露多个 URL 是没有意义的,我们应该有一个所有服务的入口点,并且基于不同的路径,我们应该是如下图所示进行路由。

Apache APISIX API Gateway 作为单一入口点

在构建.NET微服务 API 和 Web 应用程序时,API 网关还有许多其他方面。在许多场景中,_身份验证、安全性、可观察性、缓存、转换_都是集中处理的。如果没有API 网关,您通常可能会为每个服务实现这些关注点,因为为每个服务维护它们将是一项非常具有挑战性的任务并且非常耗时。同时,您可以受益于API 网关降低复杂性,为您的 API 提供高性能,并帮助您扩展微服务。

先决条件

👉 要根据本文中显示的需要执行和自定义示例项目,以下是您需要在系统中安装的最低要求:

  • ➡️.NET 6 SDK

  • ➡️Visual Studio 2022安装了 Web 开发和/或 .NET 跨平台开发工作负载。这包括默认的 .NET 6 开发工具。或Visual Studio 代码。

  • ➡️Docker 桌面- 您还需要在本地安装Docker 桌面才能完成本教程。它适用于Windows或macOS。或者安装用于 Linux](https://docs.docker.com/engine/context/aci-integration/#install-the-docker-aci-integration-cli-on-linux)的[Docker ACI 集成 CLI。

这里是我们所做工作的简短总结:

  • ✅ 从 GitHub 克隆演示项目apisix-dotnet-docker。

  • ✅ 了解项目结构和docker-compose.yaml文件。

  • ✅ 通过 Docker CLI 构建多容器 APISIX。

  • ✅ 为ASP.NETAPI 配置 APISIX API 网关路由。

  • ✅ 启用流量管理插件。

克隆演示项目

在本次演示中,我们将使用我提前准备好的演示项目apisix-dotnet-docker。你可以在 Github 上看到完整的源代码。

使用git克隆存储库:

git clone 'https://github.com/Boburmirzo/apisix-dotnet-docker'

转到 apisix-dotnet-docker 的根目录

cd apisix-dotnet-docker

您可以在您喜欢的代码编辑器中打开该项目。我使用VS 代码。您将看到以下项目目录结构:

apisix-dotnet-docker 项目文件夹

了解项目结构

在项目文件夹中,您可以查看以下主要组件列表:

  • APISIX 的配置文件 - 通过将项目中的外部配置文件挂载到 docker 容器上来配置所有服务:/apisix_conf/conf.yaml定义了 apisix 的配置。同样,etcd、prometheus 和 grafana 的配置分别位于/etcd_conf/etcd.conf.yml、/prometheus_conf/prometheus.yml和[0/grafana[0/grafana\2wzconf . ☝️注意grafana_confprometheus_confdashboard_conf都是可选的,只有当你想在你的项目中使用它们时。

  • APISIX 的日志 - 在apisix_log文件夹中,APISIX 管理和控制 API 请求被记录,例如 APISIX 运行时的access.logerror.log

  • ASP.NETWEB API - 接下来,ProductApi文件夹基本保留ASP.NET核心应用程序,带有 Controller、Domain 和 Service 类。

.NET 应用程序文件夹

您还可以看到ProductsController.cs文件,其中有一个简单的 API 可以从服务层获取所有产品列表。我们将在接下来的步骤中为此端点启用路由和 Apache APISIX 插件。

    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        private IProductsService _productsService;
        public ProductsController(IProductsService productsService)
        {
            _productsService = productsService;
        }

        [HttpGet]
        public IActionResult GetAll()
        {
            return Ok(_productsService.GetAll());
        }
    }

现在让我们看一下ProductApi文件夹中的一个Dockerfile。它只有标准的 Docker 文件结构,该文件负责从 docker 注册表中提取 .NET6 SDK 和 ASP.NET6 映像,构建和运行应用程序 docker 映像。

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app

COPY . ./
RUN dotnet restore "ProductApi.csproj"
RUN dotnet publish "ProductApi.csproj" -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:6.0
ENV TZ=America/Sao_Paulo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "ProductApi.dll"]
  • Docker compose 文件 -docker-compose.yml文件定义了一个包含一些服务的应用程序:

*apisix-dashboard- 它在端口9000上运行APISIX Dashboard。 i️ Dashboard 提供了另一种与 APISIX Admin API 交互的方式,我们可以使用 CLI 实现与使用 Dashboard 相同的配置结果。

*apisix- 部署 APISIX 并在端口9080上公开它。在您的本地机器上,您可以通过向以下 URLhttp://127.0.0.1:9080/发送请求来访问 APISIX Admin API

*etcd- APISIX 使用etcd来保存和同步配置。

*prometheus- APISIX 可以与prometheus 插件一起获取有关上游 API 的指标数据。

*grafana- 由 [prometheus plugin]apisix.apache.org/docs/apisix/plugins/prome..导出的指标也可以在 Grafana 中绘制,您可以在端口3000上看到正在运行的仪表板。

*ProductApi- 在部署 .NET 应用程序时,docker compose 将后端服务容器的端口5555映射到主机的端口80

☝️您可能会注意到所有服务都映射到apisix网络。

apisix-dotnet-docker项目使用了类似的示例APISIX docker compose template。

通过 Docker CLI 构建多容器 APISIX

现在我们可以通过从项目的根文件夹运行docker compose up命令来启动我们的应用程序:

docker-compose up -d

样本输出:

[+] Running 7/7
 - Network apisix-dotnet-docker_apisix                Created                                                              0.0s
 - Container apisix-dotnet-docker-apisix-dashboard-1  Started                                                              1.2s
 - Container apisix-dotnet-docker-prometheus-1        Started                                                              0.7s
 - Container apisix-dotnet-docker-etcd-1              Started                                                              0.9s
 - Container apisix-dotnet-docker-grafana-1           Started                                                              1.2s
 - Container apisix-dotnet-docker-productapi-1        Started                                                              0.7s
 - Container apisix-dotnet-docker-apisix-1            Started                                                              2.0s

您可以通过运行docker compose psCLI 命令或使用 docker 桌面查看正在运行的容器列表:

NAME                                      COMMAND                  SERVICE             STATUS              PORTS
apisix-dotnet-docker-apisix-1             "sh -c '/usr/bin/api…"   apisix              running             0.0.0.0:9080->9080/tcp, 0.0.0.0:9091-9092->9091-9092/tcp, 0.0.0.0:9443->9443/tcp
apisix-dotnet-docker-apisix-dashboard-1   "/usr/local/apisix-d…"   apisix-dashboard    running             0.0.0.0:9000->9000/tcp
apisix-dotnet-docker-etcd-1               "/opt/bitnami/script…"   etcd                running             0.0.0.0:12379->2379/tcp
apisix-dotnet-docker-grafana-1            "/run.sh"                grafana             running             0.0.0.0:3000->3000/tcp
apisix-dotnet-docker-productapi-1         "dotnet ProductApi.d…"   productapi          running             0.0.0.0:5555->80/tcp
apisix-dotnet-docker-prometheus-1         "/bin/prometheus --c…"   prometheus          running             0.0.0.0:9090->9090/tcp

容器运行后,在 Web 浏览器中导航到http://localhost:5555/api/products,您将看到以下输出:

产品列表 .NET API 响应

配置APISIX API网关

当您为 API 设置 Apache APISIX API Gateway 时,它会添加许多功能,包括🔽

  • 路由。

  • 请求聚合。

  • 认证。

  • 授权。

  • 速率限制。

  • 缓存。

  • 重试策略/QoS。

  • 负载均衡。

  • 记录/跟踪/指标。

  • 标头/方法/查询字符串/gRPC/声明转换。

  • 配置/管理 REST API。

  • 还有更多...

有关详细信息,请参阅文档。

Apache APISIX 基于几个原语:

  • 其中之一是Route

  • 另一个是上游

我们可以创建一个 Route 并配置底层的 Upstream。当 Apache APISIX 接收到与 Route 匹配的请求时,它会将其转发到底层的 Upstream。

现在让我们开始为/api/products端点添加 Route 和 Upstream。以下命令与上游一起创建示例路由:

curl "http://127.0.0.1:9080/apisix/admin/routes/1" -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" -X PUT -d '    
{
  "methods": ["GET"],                                       
  "uri": "/api/products",                   
  "upstream": {                           
    "type": "roundrobin",
    "nodes": {
      "productapi:80": 1
    }
  }
}'

一旦我们创建了 Route 和上游,我们就可以检查它是否有效。 Apache APISIX 应该将请求转发到我们的目标 API/api/products

curl http://127.0.0.1:9080/api/products -i

Urraaa👏,是的,确实如此。您可以看到示例输出:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.13.1

[{"name":"Macbook Pro","price":1299.9},{"name":"SurfaceBook 3","price":1599.9}]

您还可以向 API 网关添加两个或多个路由,假设一个将为您的产品提供服务,另一个为 URL 路径为/api/customers的客户微服务提供服务。

启用流量管理插件

API Gateway 的帮助下,可以为外部上游 API 或微服务设置自动重试、超时、断路器或速率限制。速率限制是一种限制网络流量的策略。它限制了某人在特定时间范围内重复操作的频率——例如,尝试登录帐户。

限制计数插件🔌 是众多限制插件之一。它通过给定时间窗口内固定数量的请求来限制请求速率。

让我们在 Route 和 Upstream 上启用limit-count插件。为此,请运行以下命令:

curl -i http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["GET"],                                       
    "uri": "/api/products",
    "plugins": {
        "limit-count": {
            "count": 2,
            "time_window": 60,
            "rejected_code": 403,
            "rejected_msg": "Requests are too frequent, please try again later.",
            "key_type": "var",
            "key": "remote_addr"
        }
    },
    "upstream": {                           
      "type": "roundrobin",
      "nodes": {
       "productapi:80": 1
     }
   }
}'

以上配置将请求数限制为60 秒内两个**。 Apache APISIX 将照常处理前两个请求,但同一时期的第三个请求将返回 403 HTTP 代码:

curl http://127.0.0.1:9080/api/products -i

在 60 秒内调用 API 3 次后的示例输出:

HTTP/1.1 403 Forbidden
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.13.1

{"error_msg":"Requests are too frequent, please try again later."}

实际上,达到阈值后,APISIX 不允许后续请求。

结论

我们使用了Apache APISIX docker composerepo,我们在一次运行中部署了多个组件,并演示了如何使用 API 网关来管理示例 ASP.NETCore 应用程序来检索产品数据产品微服务的 API。此外,您还学习了如何为 API 端点启用limit-count插件。 Apache APISIX 中还有许多其他内置插件,您可以在插件中心页面上查看它们。基本上,APISIX 可以是轻量级的中间件 API 网关,无论您正在开发微服务或应用程序的编程语言、框架、工具或平台。

推荐内容💁

  • ➔ 观看视频教程Apache APISIX 入门。

  • ➔ 阅读博文Apache APISIX API 网关插件概述。

  • ➔ 阅读博文在 Microsoft Azure 容器实例上运行 Apache APISIX。

  • ➔ 阅读博文API Security with OIDC by using Apache APISIX 和 Microsoft Azure AD。

  • ➔ 阅读博文API Observability with Apache APISIX Plugins。

社区⤵️

  • 🙋加入 Apache APISIX 社区

  • 🐦在 Twitter 上关注我们

  • 📝在 Slack 上找到我们

  • 📧将您的问题发送给我们。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐