Как развернуть приложения Asp.Net Core в Azure Service Fabric с использованием подпути, использующей один и тот же порт в кластере

Примеры Service Fabric, такие как wordcount, веб-приложение прослушивает порт в подпутье следующим образом:

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).

http://localhost:8081/wordcount

http://localhost:8081/app1

http://localhost:8081/app2

И так далее.

Но шаблон проекта Asp.Net Core отличается, и я не знаю, как добавить подпуть в конфигурации слушателя.

Код ниже - это то, что у нас есть в шаблоне проекта (Program.cs класс 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?

Цель состоит в том, чтобы публиковать на лазурном сервере порт 80, чтобы пользователи с большим опытом, например:

http://mywebsite.com/app1

http://mywebsite.com/app2

Большое тебе спасибо!


person Murilo Maciel Curti    schedule 06.07.2016    source источник
comment
docs.microsoft.com/en-us/azure/service-fabric/   -  person iamnicoj    schedule 16.08.2017
comment
Отличное дополнение @LaPuyaLoca   -  person Murilo Maciel Curti    schedule 17.08.2017


Ответы (4)


Kestrel не поддерживает префиксы URL-адресов или совместное использование портов несколькими приложениями. Вместо этого вам необходимо использовать WebListener:

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

person Vaclav Turecek    schedule 11.07.2016
comment
Вы можете помочь с образцом? Ни одна комбинация, которую я пробовал, не сработала ... Большое спасибо - person Murilo Maciel Curti; 20.07.2016
comment
Привет, я пытаюсь создать несколько экземпляров одной и той же службы на моем локальном компьютере. но когда я развернулся, первые экземпляры используют порт A, другие экземпляры выдали мне ошибку, порт A уже используется. Еще использую пустельгу. У вас есть решение для этого? Также недоступен UseWebLister. - person Shrirang; 12.02.2020

Как сказал @Vaclav, необходимо изменить UseKestrel на UseWebListener.

Но проблема в том, что привязка WebListener к адресу другая.

Посмотрите эту ветку, чтобы узнать больше https://github.com/aspnet/Hosting/issues/749

Необходимо использовать + вместо localhost или других имен машин в serverUrl.

Итак, измените код шаблона с:

            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);
        }

To

            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);
            }

И это сработало очень хорошо.

person Murilo Maciel Curti    schedule 20.07.2016

Я еще этого не делал, но полезен ли этот репозиторий GitHub?

https://github.com/weidazhao/Hosting

О образце

Этот образец демонстрирует:

1. Как ASP.NET Core можно использовать в прослушивателе связи для служб без отслеживания состояния / с отслеживанием состояния. Сегодня мы включили сценарий размещения веб-приложения ASP.NET Core как службы без отслеживания состояния с помощью Service Fabric. Мы хотели осветить сценарии, в которых люди также могут использовать ASP.NET Core в качестве слушателей связи в службах без отслеживания состояния и службах с отслеживанием состояния, аналогично тому, что делает OwinCommunicationListener.

2. Как создать службу шлюза API для пересылки запросов к нескольким микросервисам, находящимся за ней, с помощью многократно используемого и модульного компонента. Service Fabric - отличная платформа для создания микросервисов. Промежуточное программное обеспечение шлюза (Microsoft.ServiceFabric.AspNetCore.Gateway) - это попытка предоставить людям строительный блок, позволяющий легко реализовать шаблон шлюза API для микросервисов в Service Fabric. Есть несколько хороших статей, в которых описывается шаблон шлюза API, например http://microservices.io/patterns/apigateway.html, http://www.infoq.com/articles/microservices-intro и т. д. Дополнительные сведения о микросервисах см. на странице https://azure.microsoft.com/en-us/blog/microservices-an-application-revolution-powered-by-the-cloud./, http://martinfowler.com/articles/microservices.html.

person Nick Randell    schedule 07.07.2016
comment
Примерный подход позволяет запускать несколько служб на одном порте, используя их имена, например: localhost: 20000 / service1 ‹--- Svc в Application1 localhost: 20000 / service2‹ --- Svc в Application1 Это возможно, потому что там есть служба шлюза, которая сопоставляет адреса service1 и service2 в URI с правильными службами. Но я не мог найти способ, чтобы 2 разных приложения работали на одном и том же порте. Является ли это возможным? localhost: 20000 / service1 ‹--- Svc в Application1 localhost: 20000 / service2‹ --- Svc в Application2 - person Murilo Maciel Curti; 09.07.2016

@Nick Randell

Примерный подход позволяет запускать несколько служб на одном и том же порте, используя их имена, например:

http://localhost:20000/service1 ‹--- Svc в Application1

http://localhost:20000/service2 ‹--- Svc в Application1

Это возможно, потому что существует служба шлюза, которая сопоставляет адреса service1 и service2 в URI с правильными службами.

Но я не мог найти способ, чтобы 2 разных приложения работали на одном и том же порте.

Является ли это возможным?

http://localhost:20000/service1 ‹--- Svc в Application1

http://localhost:20000/service2 ‹--- Svc в Application2

person Murilo Maciel Curti    schedule 09.07.2016