Ist es möglich, eine Service-Fabric-App so zu binden, dass mehrere Ports überwacht werden?Service-Fabric-Bindung an mehrere Endpunkte
Im Grunde versuche ich einen Public-Facing-Service zu haben, der auf http: 80 und https: 443 lauscht und HTTP-Anfragen an https weiterleitet.
Ich habe einen neuen ASP.net Core-Dienst erstellt, der individuell funktioniert. I.e. mit SSL 443 oder nur Nicht-SSL 80, aber wenn ich beide ServiceInstanceListeners
hinzufügen, scheitert es einfach!
Service-Fabric Explorer sagt der folgende Fehler nach mehrmaligem Timeout:
Unhealthy event: SourceId='System.RA', Property='ReplicaOpenStatus', HealthState='Warning', ConsiderWarningAsError=false.
Replica had multiple failures in API call: IStatelessServiceInstance.Open(); Error = System.Fabric.FabricElementAlreadyExistsException (-2146233088)
Unique Name must be specified for each listener when multiple communication listeners are used
at Microsoft.ServiceFabric.Services.Communication.ServiceEndpointCollection.AddEndpointCallerHoldsLock(String listenerName, String endpointAddress)
at Microsoft.ServiceFabric.Services.Communication.ServiceEndpointCollection.AddEndpoint(String listenerName, String endpointAddress)
at Microsoft.ServiceFabric.Services.Runtime.StatelessServiceInstanceAdapter.d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.ServiceFabric.Services.Runtime.StatelessServiceInstanceAdapter.d__0.MoveNext()
die seltsam ist, weil beide Zuhörer unterschiedliche Namen haben - so wie es scheint. Gibt es irgendwo irgendwo den Namen des Zuhörers, den ich verpasst habe?
Ich benutze die Asp.net Core-Vorlage dafür. Mein Stateless Service-Code lautet wie folgt:
internal sealed class Web : StatelessService
{
public Web(StatelessServiceContext context)
: base(context)
{ }
/// <summary>
/// Optional override to create listeners (like tcp, http) for this service instance.
/// </summary>
/// <returns>The collection of listeners.</returns>
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new WebListenerCommunicationListener(serviceContext, "ServiceEndpointHttps", url =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting WebListener on {url}");
return new WebHostBuilder()
.UseWebListener()
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseUrls(url)
.Build();
})),
new ServiceInstanceListener(serviceContext =>
new WebListenerCommunicationListener(serviceContext, "ServiceEndpointHttp", url =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting WebListener on {url}");
return new WebHostBuilder()
.UseWebListener()
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseUrls(url)
.Build();
}))
};
}
}
Der Name sollte mit dem Namen des Endpunkts in den Einstellungen für den Dienst übereinstimmen. Für einen Dienst mit einem einzelnen Endpunkt eines Typs ist es in Ordnung, ihn leer zu lassen, aber sobald Sie mehrere haben, müssen Sie ihn anhand des Namens identifizieren. – yoape
Gut zu wissen, danke! Wird mich in Zukunft nicht stolpern. – Mardoxx