是否可以快速开发 - (Service)Service Fabric项目中的(门户)Web应用程序

时间:2018-04-01 19:10:36

标签: asp.net-mvc azure-service-fabric

我添加了一个WebApplication来构建我们的Web门户到现有的ServiceFabric集群VS sln设置中。但是,我很快意识到这对快速开发/调试周期不起作用。为了更改CSHTML文件然后在浏览器中快速尝试它们,我需要能够在VSTS中点击F5并快速运行portal.exe并提供页面;所以我切换到“Portal”项目作为Startup项目(它是粗体)并使用IISExpress或Portal配置文件(来自launchSettings.json)。

然而,失败的例外情况是:

System.Fabric.FabricException: 'An error occurred during this operation.  Please check the trace logs for more details.'

从这一行:

ServiceRuntime.RegisterServiceAsync("PortalApp",
     context => new APIGateway(context)).GetAwaiter().GetResult();

这是因为我没有在SF群集中运行。这是有道理的。

那么如何让这个场景有效?有没有办法进行我的开发而不必每次都要将解决方案部署到集群?即使在单节点本地集群中也是非常缓慢(高达30-45秒),并且生产力严重下降。

我是否可以添加“RunLocal”代码路径来规避并创建一个不依赖于SF运行时的WebHost,但仍然使用我项目的其余部分并在集群外部运行?

2 个答案:

答案 0 :(得分:1)

好的,我(主要)解决了这个问题。

这就是我的所作所为。基本上,不是使用Service FabricRuntime在program.cs中创建WebHost(它基本上只在SF集群内部工作),而是检查我们是否在集群内部运行(从这里借用),然后实例化我自己的WebHost实例使用相同的Startup类,因此webHost(在我的情况下是Kestrel)配置了相同的设置。从那时起,它就是接管的所有原始代码。

这适用于托管WebHost(http侦听器)的ServiceFabric项目。但是,我有一个其他SF项目没有,并且由其他人通过Service Remoting调用。不幸的是,我怀疑可以像上面那样轻松地工作。

进行这些更改后,您可以更改Solution的StartUp项目以包含1个或所有webhost EXE。然后按F5,它将在群集外部本地启动(1..N)EXE,您可以在那里调试它们。这样我的工作流程就是让webhost EXE运行,更改我的CSHTML文件,保存,然后只刷新网页。变化可以立即看到和测试!对其他编译代码的更改也可以非常快速地测试。

(从这个帖子中得到了一些上述想法:How to see if running under service fabric

以下是代码:

// program.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.ServiceFabric.Services.Runtime;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Web.Portal
{
    internal static class Program
    {
        /// <summary>
        /// This is the entry point of the service host process.
        /// </summary>
        private static void Main(string[] args)
        {
            if (Environment.GetEnvironmentVariable("Fabric_ApplicationName") == null)
            {
                ServiceEventSource.Current.Message("Detected as running locally OUTSIDE the Fabric Cluster");
                BuildWebHost(args).Run();
            }
            else
            {
                ServiceEventSource.Current.Message("Detected as running INSIDE the Fabric Cluster");
                try
                {
                    ServiceRuntime.RegisterServiceAsync("Web.PortalType",
                        context => new Portal(context)).GetAwaiter().GetResult();

                    // The ServiceManifest.XML file defines one or more service type names.
                    // Registering a service maps a service type name to a .NET type.
                    // When Service Fabric creates an instance of this service type,
                    // an instance of the class is created in this host process.

                    ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(Portal).Name);

                    // Prevents this host process from terminating so services keeps running. 
                    Thread.Sleep(Timeout.Infinite);
                }
                catch (Exception e)
                {
                    ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
                    throw;
                }
            }
        }

        public static IWebHost BuildWebHost(string[] args)
        {
            // for some reason, the appSetting.json values arent getting loaded by default config builder
            // even though, per MSDN, they should be in ASPNET Core 2.0. I am adding them in manually for now.
            IConfiguration config = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appSettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appSettings.Development.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();

            return new WebHostBuilder()
                    .UseConfiguration(config)
                    .UseKestrel()
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseStartup<Startup>()
                    .Build();
        }
    }
}

答案 1 :(得分:1)

在服务结构SDK上,您具有名为&#34; Refresh Application&#34;的应用程序调试模式,部署使用此功能将创建从SF部署到您的开发路径的符号链接,您所做的每项更改到您的文件,将反映SF运行应用程序的更改

要使用此部署模式,您可以通过以下方式更改此设置:右键单击您的SF项目&gt;属性&gt;属性窗口将显示设置(下方)&gt;切换到&#34;删除应用程序&#34;到&#34;刷新应用程序&#34; Service Fabric Project Settings

此模式有一些限制:

  
      
  • 它仅适用于单节点开发群集。
  •   
  • 它仅支持在ASP.NET的情况下对代码,配置或数据包的内容以及项目目录内容的更改   核心项目。应用程序结构更改 - 比如更改   ServiceManifest.xml或ApplicationManifest.xml - 不受支持   因为部署的应用程序的结构可能会随之改变   不想要的结果你仍然可以在进行结构改变   刷新应用程序调试模式,但如果这样做,应用程序将是   重新部署。
  •   
  • 如果您重新编译,有状态服务不会保持其状态。为了使您的新二进制文件运行,必须删除该服务   停止进程所以新的二进制文件可以写入磁盘,其中   当然意味着你的所有国家都被消灭了。这通常很好   快速发展,但要真正测试你的有状态服务,你会   仍然需要在5节点集群中运行它们。
  •