如何版本和单独的Service Fabric应用程序?

Fla*_*ape 27 .net c# azure visual-studio azure-service-fabric

所有服务结构示例都描述了单解决方案服务结构示例.这似乎与微服务的理念背道而驰,在这种理念中,您需要在服务之间实现完全依赖性隔离.虽然您可以手动遵循此模式,但更常见的做法是通过将每个服务作为自己的存储库和解决方案/项目来实施它.

如何使用多个解决方案(在多个Git存储库中)管理和部署服务结构服务并实施服务合同(ServiceInferfaces)?

例如

Service Fabric Solution
      App1 - Customers
         - Service1 [Carts] From Other Solution
         - Service2 [LocationInfo]From Other Solution
         - Service3 [REST WebAPI for Admin] From Other Solution
      App2 - Products
         - Service4 [Status]From Other Solution
         - Service5 [Firmware]From Other Solution
         - Service6 [Event Stream] From Other Solution

External Solution
   - Service1
External Solution
   - Service2
External Solution
   - Service3

External Solution
   - Service4
External Solution
   - Service5
External Solution
   - Service6
Run Code Online (Sandbox Code Playgroud)

1)作为开发人员,我想查看并构建所有当前版本的应用程序/服务.我想启动管理所有清单的Service Fabric项目,并将其部署到我的本地开发群集.我想在解决方案之间强制执行相同的服务接口.我不明白你是怎么做的,因为应用程序是服务的外部.

2)作为DevOps团队,我希望自动化下拉应用程序,构建它们并部署到Azure.

我们如何通过单独的解决方案"强制"隔离,但可以轻松地将它们组合在一起并部署到集群中,同时还可以轻松地制作管道以部署为DEV,QA和PROD环境唯一配置的每个集群.

启用此功能的工作流程/流程/项目结构是什么?它甚至可能吗?

Mik*_*tly 15

是的,这是可能的 - 我之前已经做过这些事情.这些是立刻浮现在脑海中的想法......

在每个Service Fabric解决方案中都有一个"公共"项目,其中只包含您希望从该应用程序中的服务公开的接口.此项目的输出可以打包为nuget包并推送到私有存储库.您可以将其称为"接口"项目,但如果您想在应用程序内部考虑其中一些接口,则不必公开所有接口; 这些可以在一个单独的,未暴露的项目中定义.

其他想要引用其他应用程序公开的服务的解决方案只需要下拉相关的nuget包来获取对服务接口的引用.

现在这不是没有问题:

  • 消费应用程序仍然需要知道服务的地址,以便为它们构建代理.您可以将它们作为在nuget包中某处定义的常量公开,或者如果您正在沿着完整的DI路线进行操作并且不介意将自己耦合到DI容器的任何地方(或者想要将其抽象出来),那么您可能会暴露它们nuget包中的一个模块,它可以将服务接口注册为lambda,代表依赖的应用程序创建服务代理.
  • 您是更容易受到破坏的合同.您需要非常小心更新方法签名,因为现在负责应用程序/服务部署的粒度和协调.
  • 您可以过于细化 - 如您所述,Service Fabric工具可指导您在一个解决方案中提供多种服务.即使采用上述方法,我仍然会尝试在某种程度上对我的服务进行逻辑分组,即不要在应用程序和服务之间进行一对一的映射 - 这肯定会比它的价值更加痛苦.

希望有所帮助.

编辑:

在DI模块中注册服务接口的示例(Autofac样式)......

这将是您从公共nuget包公开的DI模块:

using System;
using Autofac;
using Microsoft.ServiceFabric.Services.Remoting.Client;

public class MyAppModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.Register(component => ServiceProxy.Create<IMyService>(new Uri("fabric:/App/MyService"))).As<IMyService>();
        // Other services...
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的消费应用程序的Program.cs中,您将包含以下内容:

public static void Main()
{
    try
    {
        var container = ConfigureServiceContainer();

        ServiceRuntime.RegisterServiceAsync(
            "MyConsumingServiceType",
            context => container.Resolve<MyConsumingService>(new TypedParameter(typeof(StatefulServiceContext), context))).GetAwaiter().GetResult();
        ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(MyConsumingService).Name);

        Thread.Sleep(Timeout.Infinite);
    }
    catch (Exception e)
    {
        ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
        throw;
    }
}

private static IContainer ConfigureServiceContainer()
{
    var containerBuilder = new ContainerBuilder();

    // Other registrations...

    containerBuilder.RegisterModule<MyAppModule>();

    return containerBuilder.Build();
}
Run Code Online (Sandbox Code Playgroud)

当然,只有在不对服务进行分区时,此方法才有效...

  • 这很棒.我希望MSDN/Azure添加一些超出其会议演示材料的SF示例. (2认同)