azure-service-fabric - service fabric azure tutorial
Service Fabric Múltiples instancias de servicio con anulación de configuración (4)
Nuestra aplicación de tejido de servicio incluye un servicio sin estado que expone un punto final HTTP a través de OwinCommunicationListener
.
El ServiceManifest.Xml para este servicio especifica el punto final del servicio <Endpoint Name="ServiceEndpoint" Type="Input" Protocol="http" Port="8090" />
Se puede acceder al servicio sin estado a través de un navegador en http://localhost:8090/
Lo que estamos tratando de hacer es crear instancias múltiples de este servicio en diferentes puntos finales en la misma aplicación de Service Fabric a través de ApplicationManifest.
El ServiceManifestImport
importa nuestro paquete de servicio y permite anulaciones de configuración en el nivel de la aplicación. No podemos anular el ServiceEndpoint de esta manera, solo los valores en Settings.xml
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="FooServicePkg" ServiceManifestVersion="1.0.0" >
<ConfigOverrides Name="Config">
<Settings>
<SectionName Name="MySettings">
<Parameter Name="MySetting" Value="SomeValue">
</Settings>
</ConfigOverrides>
</ServiceManifestImport>
Podemos crear instancias con nombre del servicio especificando varios nodos de Service
DefaultServices
<DefaultServices>
<Service Name="FooInstanceA">
<StatelessService ServiceTypeName="FooType" InstanceCount="1" />
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="FooInstanceB">
<StatelessService ServiceTypeName="FooType" InstanceCount="1" />
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
¿Es posible especificar anulaciones de configuración por instancia de un servicio a través de la configuración?
Traté de hacer que las instancias de servicio escuchen en un puerto específico usando su nombre de servicio para determinar qué puerto escucha FooInstanceA en el puerto 8090 y FooInstanceB escucha en 8091.
Claramente, Service Fabric está haciendo algo de magia durante la implementación porque cuando FooInstanceB escucha en un puerto diferente al especificado en la configuración de ServiceEndpoint, no se puede acceder al servicio.
La primera razón es que el DACL no se establece en el punto final, esto se resuelve ejecutando;
netsh http add urlacl http://+:8091/ user=everyone listen=yes
Esto permite que los servicios aparezcan y se muestren correctamente en Service Fabric Explorer, sin embargo, FooInstanceB responde con un error de HTTP 503 cuando accedemos con http://localhost:8091/
¿Cómo podemos hacer que las instancias de servicio escuchen en diferentes puertos?
Espero que quede claro, gracias.
Creo que es una muy buena idea tener un servicio de reescritura de url frente a un clúster de SF.
Esto le puede dar múltiples puntos finales y hacer reescrituras de url, firewalls / lista negra, https, etc.
Otra forma es empaquetar el servicio como lib o en Nuget y crear los servicios N que necesita con diferentes manifiestos de servicio.
Logré hacer esto usando los archivos XML ApplicationParameter y elegir el correcto durante la implementación en VSTS. Esto, por ejemplo, es mi Cloud.xml que utilizo para la implementación en mi entorno de prueba. El truco es el parámetro Nombre en la segunda línea. He especificado el puerto utilizando esta documentación: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-how-to-specify-port-number-using-parameters
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/DotNetCoreTest" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Web1_InstanceCount" Value="2" />
<Parameter Name="ServiceEndpoint_PortNumber" Value="8909" />
</Parameters>
</Application>
Este es el archivo xml para Staging: Staging.xml
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/DotNetCoreStaging" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Web1_InstanceCount" Value="2" />
<Parameter Name="ServiceEndpoint_PortNumber" Value="8910" />
</Parameters>
</Application>
Utilizando el Proxy inverso de Traefik como se describe blogs.msdn.microsoft.com/azureservicefabric/2018/04/05/… , puedo usar un nombre de host para llegar a mi servicio. En VSTS, estoy usando un tokenizador para reemplazar tanto el nombre de host en el ServiceManifest como para reemplazar el ApplicationTypeName en el ApplicationManifest durante la implementación.
Este es mi ServiceManifest:
<ServiceTypes>
<!-- This is the name of your ServiceType.
This name must match the string used in RegisterServiceType call in Program.cs. -->
<StatelessServiceType ServiceTypeName="Web1Type">
<Extensions>
<Extension Name="Traefik">
<Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
<Label Key="traefik.frontend.rule.hostname">Host: #{HostName}#</Label>
<Label Key="traefik.expose">true</Label>
<Label Key="traefik.frontend.passHostHeader">true</Label>
</Labels>
</Extension>
</Extensions>
</StatelessServiceType>
</ServiceTypes>
No hay muchas opciones geniales para lograr esto. Aquí hay algunas ideas:
- Cree múltiples instancias de aplicación en lugar de múltiples servicios del mismo tipo dentro de una aplicación. Eso le permitiría usar los parámetros de la aplicación para configurar el comportamiento del servicio en particular.
- Crea múltiples paquetes de configuración dentro de tu tipo de servicio. Cada paquete de configuración estaría destinado a una de las instancias de servicio. ¿Determinar a qué paquete de configuración se asigna una instancia de servicio tendría que ser dinámico, quizás basado en el nombre de la instancia de servicio? No es una buena opción, por supuesto, ya que combina la definición de servicio con el número de instancias que se crearán.
- Una implementación de configuración personalizada. Tal vez haga que su servicio exponga un punto final que le permita configurarlo después de la implementación. O haga que el servicio llame a algún otro servicio de administración que proporcione su configuración en el momento de la activación.
También puede dejar que Service Fabric asigne los puertos automáticamente y luego usar el proxy inverso que viene con Service Fabric.