Azure Service Fabric 多租户

Posted

技术标签:

【中文标题】Azure Service Fabric 多租户【英文标题】:Azure Service Fabric Multi-Tenancy 【发布时间】:2016-05-16 19:43:30 【问题描述】:

我正在尝试对这个已经回答的问题进行一些跟进......

Service Fabric multi-tenant

如果我要将我的租户设置为 Azure Service Fabric 无状态服务(他们将获得带外状态),我如何在集群中的每个节点上放置多个租户?在测试中,如果您尝试使实例数大于节点数,Service Fabric 似乎会出现问题。

这些租户非常轻量级,所以我应该能够在每个节点上运行几十个(我们总共会有数百个),我不想为每个节点做一个节点。具体来说,租户或多或少只是打开与外部客户服务的长轮询 HTTP 连接并将数据流式传输回我们的系统 - 所以这里没有公共端点在起作用。我只需要能够启动许多这样的工作人员,每个工作人员都会打开自己的长轮询连接。

有人能指出正确的方向吗?

仅供参考,我已经在这里解释了更多...https://social.msdn.microsoft.com/Forums/en-US/efd172e2-0783-489b-b3ab-ec62fb7b8ee4/multiple-instances-per-node?forum=AzureServiceFabric

提前致谢!

【问题讨论】:

【参考方案1】:

您需要以某种方式对您的服务进行分区。

有几个选项,但这里有两个很好(以及您链接的 SO 问题):

拥有一个 SF 应用程序,每个租户都可以在其中获取您的服务实例。然后,您需要在前面有一个共享服务,以将请求路由到正确的服务。它应该看起来像这样。

MyAwesomeApp
    SharedStatelessApi <- External API points here
    MyTenantService_Tenant1 <- ServiceType: MyTenantService
    MyTenantService_Tenant2 <- ServiceType: MyTenantService
    ...

另一种解决方案是每个租户拥有一个(或多个)服务结构应用程序,并且看起来类似于:

MySharedApp
    SharedStatelessApi <- External API points here
Tenant1 <- ApplicationType: MyTenantApp
    MyTenantService <- ServiceType: MyTenantService
Tenant2 <- ApplicationType: MyTenantApp
    MyTenantService <- ServiceType: MyTenantService

和第一个例子的概念一样,但是分区是在更高的水平上完成的。

就个人而言,我更喜欢第二种情况。感觉更对了。 在这两种情况下,您都必须在新客户注册时手动创建服务/应用程序,或者在代码中创建。如果你想用代码来做,你应该看看 FabricClient。如果您需要这方面的示例,请告诉我。

此外,如您所见,您应该有一个共享的公共端点,并在该端点中根据某些内容(标头、身份验证令牌、uri、与您的应用程序内联的任何内容)将请求路由到正确的服务。

使用 FabricClient 创建服务的示例:

首先你需要一个 FabricClient。对于不安全的集群(您的本地开发集群),以下内容就足够了:

var fabricClient = new FabricClient("localhost:19000");

当您部署到安全集群(例如在 Azure 中)时,您需要对 FabricClient 进行身份验证,如下所示:

var creds = new X509Credentials

    FindType = X509FindType.FindByThumbprint,
    FindValue = clientCertThumbprint,
    RemoteCertThumbprints = clientCertThumbprint,
    StoreLocation = StoreLocation.LocalMachine,
    StoreName = "My"
;

var clusterEndpoint = "CLUSTERNAME.LOCATION.cloudapp.azure.com:19000"
// or whatever your cluster endpoint is

var fabricClient = new FabricClient(creds, clusterEndpoint);

然后,当您拥有 FabricClient 时,您可以像这样创建无状态服务:

var statelessDescriptor = new StatelessServiceDescription

    ApplicationName = new Uri("fabric:/MYAPP"),
    InstanceCount = 1, // How many instances.
    PartitionSchemeDescription = new SingletonPartitionSchemeDescription(),
    ServiceName = new Uri("fabric:/MYAPP/TenantA"),
    ServiceTypeName = "YourServiceTypeName",
    InitializationData = DATA_TO_PASS_TO_SERVICE_BYTE[] // Only if needed.
;

await _client.ServiceManager.CreateServiceAsync(statelessDescriptor)

如果您在“InitializationData”属性中传递了任何数据,它将在服务中作为 ServiceInitializationParameters.InitializationData 提供

【讨论】:

感谢您抽出宝贵时间提供反馈。也许我需要对 FabricClient 和您提出的解决方案进行更多研究,以确定这是否是我正在寻找的答案的一部分。请记住,我们的多租户服务实际上只是一个打开长轮询 HTTP 连接和来自客户的流数据的过程 - 没有公共端点。问题是我们需要在每个节点上运行这些租户的多个实例,因为它们非常轻量级,并且每个节点使用一个没有意义,这将完全没有充分利用该节点的马力。 我已经改写了我的部分问题,以更好地阐明潜在的工作量,希望这将使问题得到更好的定义。基本上是希望通过使用 Service Fabric 来构建可以长时间运行的长轮询 HTTP 连接以及故障转移、负载平衡等。 好的,假设您有一些内部方式来触发连接的启动,我上面的帖子仍然有效。例如,您可以不触发与租户 A 的连接,而是为租户 A 启动一个无状态服务实例,然后该服务在其 RunAsync 方法中打开它的连接。这有意义吗? 或者我可以尝试更好地理解您的要求。您希望每个长时间运行的连接都有一个有状态服务实例吗?连接/租户的数量是固定的,还是随着时间的推移添加/删除? 是的,我们的想法是为每个“客户”提供一个服务,但是当它“初始化”时,该服务将打开那个长时间运行的连接并在那个打开时持续流式传输数据联系。客户会来来去去,但我可以想象总是激活额外的实例,每小时访问一次配置服务器,看看是否有新客户需要开始流式传输,这将是初始化过程.同样,在关闭连接时,如果客户取消,我们只会将该实例添加回可用工作人员堆中。

以上是关于Azure Service Fabric 多租户的主要内容,如果未能解决你的问题,请参考以下文章

Azure上的Service Fabric Cluster创建失败,错误代码为“VMInstanceCountAllowsBetterReliabilityLevel”

多租户应用程序中的 Azure DocumentDB 用户

Azure App Service 上的根证书

在多租户应用程序中如何检查应用程序在 Azure 门户中注册的租户数据?

多租户 - Azure IoT 客户是不是应该共享一个中心?

Azure Service Fabric部署 - 该地区不提供虚拟机来为您的请求提供服务