33

在观看了 Azure Service Fabric 的 BUILD 会议视频后,我开始想象这可能非常适合我们当前基于微服务的架构。但是,我不完全确定如何解决一件事 - API 网关/代理。

考虑一个不那么简单的微服务体系结构,其中有 N 个服务在 Azure Service Fabric 中运行,暴露 REST 端点。在许多情况下,您希望将这些零散的 API 端点打包成一个单入口 API 供消费者使用,以避免让它们直接连接到服务结构实例。Azure Service Fabric 解决方案似乎在各个方面都如此完整,以至于当我在 BUILD 会谈中提到的功能中看不到可以轻松解决此问题的方法时,我有点想知道我是否遗漏了一些明显的东西。

Vulcan这样的服务旨在通过让服务在etcd中注册他们想要路由到它们的路径来解决这个问题。我猜测解决这个问题的一种方法可能是创建一个单独的有状态 Web 服务,其他服务可以注册自己,提供服务名称和它们需要路由到它们的路径。然后,有状态 Web 服务可以根据其状态将流量路由到正确的实例。但是,这似乎并不完全理想,例如在删除应用程序时删除路由以及通常使状态与部署在集群中的服务保持同步。有没有人考虑过这个问题,或者知道如何在 Azure Service Fabric 中解决这个问题?

4

8 回答 8

25

您需要执行此操作的服务注册/可发现性实际上已经存在。有一个称为命名服务的有状态系统服务,它基本上是服务实例和它们正在侦听的端点的注册器。因此,当您启动服务(无论是无状态的还是有状态的)并在其上打开一些侦听器时,该地址就会在命名服务中注册。

现在您需要填写的部分是用户与之交互的“网关”。这不必是有状态的,因为命名服务管理有状态的部分。但是你必须想出一个适合你的寻址方案,然后它将请求转发到正确的位置。基本上是这样的:

  1. 接收请求。
  2. 使用 NS 查找可以接受请求的服务。
  3. 将请求转发给它,并将响应转发给用户。
  4. 如果该服务不再存在,则 404。

一般来说,我们不喜欢规定任何关于您的服务如何相互通信的内容,但我们正在考虑将 HTTP 作为一个完整的内置解决方案来解决这个问题的方法。

于 2015-05-02T00:56:29.700 回答
19

为此,我们还实现了一个 HTTP 网关服务。为了确保我们可以为任何内部协议提供一个 HTTP 网关,我们使用 ASP.NET 5 中间件为基于 HTTP 的内部服务(如 ASP.NET WebAPI)实现了网关。它通过使用ServicePartitionClient和一些来自CommunicationClientFactoryBase.

我们开源了这个中间件,你可以在这里找到它: https ://github.com/c3-ls/ServiceFabric-HttpServiceGateway

该项目的 wiki 中还有更多文档。

于 2016-01-04T14:01:23.833 回答
13

从 Service Fabric 5.0 版开始,此功能内置于 http 端点。该文档位于https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reverseproxy/

于 2016-07-26T16:34:30.583 回答
4

我们使用了一个名为Traefik的开源项目并取得了惊人的成功。它周围有一个Azure Service Fabri c 包装器 - 它本质上是一个 GoLang exe,作为托管可执行文件部署到集群上。

它支持断路器、加权循环 LB、路径和标头版本路由(这对于托管多个 API 版本来说非常棒),不胜枚举。它有一个方便的门户来查看配置和健康统计信息。

它的真正力量在于你如何配置它。它是通过ServiceManifest.xml. 这使您可以部署新服务并立即将它们路由到 - 无需更新路由表等。

例子

<StatelessServiceType ServiceTypeName="WebServiceType">
  <Extensions>
      <Extension Name="Traefik">
        <Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
          <Label Key="traefik.frontend.rule.example">PathPrefixStrip: /a/path/to/service</Label>
          <Label Key="traefik.enable">true</Label>
          <Label Key="traefik.frontend.passHostHeader">true</Label>
        </Labels>
      </Extension>
  </Extensions>
</StatelessServiceType>

强烈推荐!

于 2018-03-23T11:02:18.937 回答
3

Azure Service Fabric 可以轻松实现此方案的标准体系结构:网关服务作为客户端连接的前端,所有 N 个后端服务与前端网关进行通信。作为 Service Fabric 的一部分,有一些通信 API 堆栈可用于轻松地从客户端到服务以及在服务内部进行通信。Service Fabric 提供的通信 API 堆栈隐藏了发现、连接和重试连接的详细信息,以便您可以专注于实际的信息交换。使用 Service Fabric 通信 API 时,服务不必实现将其名称和终结点注册到特定路由服务的机制,除非是创建服务本身的常规步骤。本文提供了一个很好的起点,可帮助您决定哪些通信 API 最适合您的特定情况,具体取决于您使用的是 Reliable Actors 还是 Reliable Services,还是 HTTP 或 WCF 等协议,或者选择的编写服务所使用的编程语言。在文章末尾,您将找到指向不同通信 API 的更详细文章和教程的链接。有关 Web API 服务中通信的教程,请参阅

于 2015-05-02T00:18:20.723 回答
1

我们使用带有网关模式的 SF 和网关后面的大约 13 个服务。我们使用 SF 提供的内置 DNS 服务,参见:https ://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-dnsservice ,这允许内部服务以已知 ( internal to SF) DNS 名称,包括到内部服务的网关服务。有一些众所周知的 asp.net 核心网关(Ocelot、ProxyKit)可供使用,但我们推出了自己的。我们有一个外部负载均衡器来路由到 SF 中的多个网关实例。

于 2019-02-20T16:27:53.560 回答
0

当服务启动时,它会向结构命名服务注册它的端点。然后,使用 Fabric 客户端 API,您可以向 Fabric 询问已注册的端点,与注册的服务名称相关联。

所以是的,就像您描述的情况一样,您将拥有一个网关,该网关将接受传入的 URI 进行连接,然后将该路径信息用作服务名称查找,然后在传入请求和实际内部请求之间创建代理连接端点位置。

看起来团队发布了一个显示如何执行此操作的示例:https ://github.com/Azure/servicefabric-samples/tree/master/samples/Services/VS2015/WordCount

于 2015-05-02T01:22:18.533 回答
0

我想知道,与其在 N+ 服务上公开 Rest,不如在服务结构内的任何地方使用默认的 comm 堆栈(或尽可能在内部保持简单)。仅在结构的边缘入口点公开 REST。使用 std stateless web 2.x api 包装您的服务和参与者的结构代理,和/或使用结构服务以相同的方式公开休息。根据需要在面向前的 Rest 服务中聚合您的 api。不确定我是否需要额外的聚合器开销来命名重定向(也许我错过了这个想法)。那么这似乎只是用所需的名称空间(即外观模式)组织(和保护)休息端点的练习。

于 2015-09-13T04:03:20.777 回答