如何使用集群上共享相同端口的子路径在 Azure Service Fabric 上部署 Asp.Net 核心应用程序

How to deploy Asp.Net Core apps on Azure Service Fabric using subpaths sharing same port on the cluster

Web 应用程序像 wordcount 这样的 Service Fabric 示例在子路径中的端口上侦听,如下所示:

http://localhost:8081/wordcount

此配置的代码是:(参见 GitHub https://github.com/Azure-Samples/service-fabric-dotnet-getting-started/blob/master/Services/WordCount/WordCount.WebService/WordCountWebService.cs 上的文件)

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
        {
            return new[]
            {
                new ServiceInstanceListener(initParams => new OwinCommunicationListener("wordcount", new Startup(), initParams))
            };
        }

通过此配置,我们可以使用相同的端口 (8081) 在同一集群上部署其他 Web 应用程序

http://localhost:8081/wordcount

http://localhost:8081/app1

http://localhost:8081/app2

以此类推

但是 Asp.Net 核心项目模板不同,我不知道如何在侦听器配置上添加子路径。

下面的代码是我们在项目模板(Program.cs class WebHostingService)中的代码:

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
            {
                return new[] { new ServiceInstanceListener(_ => this) };
            }

Task<string> ICommunicationListener.OpenAsync(CancellationToken cancellationToken)
            {
                var endpoint = FabricRuntime.GetActivationContext().GetEndpoint(_endpointName);

                string serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}";

                _webHost = new WebHostBuilder().UseKestrel()
                                               .UseContentRoot(Directory.GetCurrentDirectory())
                                               .UseStartup<Startup>()
                                               .UseUrls(serverUrl)
                                               .Build();

                _webHost.Start();

                return Task.FromResult(serverUrl);
            }

语义有点不同,但都在同一点上结束。 问题是,即使我在 serverUrl 的末尾添加子路径,它也不起作用,网络应用程序总是在根 http://localhost:8081/

上响应

看看我在下面的代码片段中是如何尝试的:

string serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}/app1";

如何使用 asp.net 核心实现与 "classic" 网络应用程序相同的结果?

目标是在 80 端口上发布到 Azure 上,让用户有更好的体验,例如:

http://mywebsite.com/app1

http://mywebsite.com/app2

非常感谢!

我还没有这样做,但是这个 GitHub 存储库有用吗?

https://github.com/weidazhao/Hosting

About The Sample

This sample demonstrates:

1.How ASP.NET Core can be used in a communication listener of stateless/stateful services. Today the scenario we've enabled is to host ASP.NET Core web application as a stateless service with Service Fabric. We wanted to light up the scenarios that people also can use ASP.NET Core as communication listeners in stateless services and stateful services, similar to what the OwinCommunicationListener does.

2.How to build an API gateway service to forward requests to multiple microservices behind it with the reusable and modular component. Service Fabric is a great platform for building microservices. The gateway middleware (Microsoft.ServiceFabric.AspNetCore.Gateway) is an attempt to provide a building block for people to easily implement the API gateway pattern of microservices on Service Fabric. There are a couple good articles elaborating the API gateway pattern, such as http://microservices.io/patterns/apigateway.html, http://www.infoq.com/articles/microservices-intro, etc. For more information about microservices, check out https://azure.microsoft.com/en-us/blog/microservices-an-application-revolution-powered-by-the-cloud/, http://martinfowler.com/articles/microservices.html.

@Nick Randell

使用示例方法可以 运行 同一端口上的多个服务使用它们的名称,例如:

http://localhost:20000/service1 <--- Application1 中的 Svc

http://localhost:20000/service2 <--- Application1 中的 Svc

这是可能的,因为是否有网关服务将 URI 中的地址 service1 和 service2 映射到正确的服务。

但我找不到让 2 个不同的应用程序 运行ning 在同一个端口上的方法。

可能吗?

http://localhost:20000/service1 <--- Application1 中的 Svc

http://localhost:20000/service2 <--- Application2 中的 Svc

Kestrel 不支持 URL 前缀或多个应用程序之间的端口共享。您必须改用 WebListener

using Microsoft.AspNetCore.Hosting ... _webHost = new WebHostBuilder().UseWebListener()

正如@Vaclav 所说,有必要通过 UseWebListener 更改 UseKestrel。

但问题是 WebListener 绑定到地址是不同的。

查看此线程以了解更多详细信息https://github.com/aspnet/Hosting/issues/749

必须在 serverUrl 上使用 + 而不是 localhost 或其他机器名称。

因此,将模板代码更改为:

            Task<string> ICommunicationListener.OpenAsync(CancellationToken cancellationToken)
        {
            var endpoint = FabricRuntime.GetActivationContext().GetEndpoint(_endpointName);


            string serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}/service1";

            _webHost = new WebHostBuilder().UseKestrel()
                                           .UseContentRoot(Directory.GetCurrentDirectory())
                                           .UseStartup<Startup>()
                                           .UseUrls(serverUrl)
                                           .Build();

            _webHost.Start();

            return Task.FromResult(serverUrl);
        }

            Task<string> ICommunicationListener.OpenAsync(CancellationToken cancellationToken)
            {
                var endpoint = FabricRuntime.GetActivationContext().GetEndpoint(_endpointName);

                string serverUrl = $"{endpoint.Protocol}://+:{endpoint.Port}/service1";

                _webHost = new WebHostBuilder().UseWebListener()
                                               .UseContentRoot(Directory.GetCurrentDirectory())
                                               .UseStartup<Startup>()
                                               .UseUrls(serverUrl)
                                               .Build();

                _webHost.Start();

                return Task.FromResult(serverUrl);
            }

而且效果很好。