我们的服务架构应用程序包括一个无状态服务,通过OwinCommunicationListener
公开HTTP端点。
此服务的ServiceManifest.Xml指定服务端点<Endpoint Name="ServiceEndpoint" Type="Input" Protocol="http" Port="8090" />
然后可以通过http://localhost:8090/
上的浏览器访问无状态服务我们要做的是通过ApplicationManifest在同一Service Fabric应用程序中的不同端点上实例化此服务的多个实例。
ServiceManifestImport
导入我们的服务包并允许在应用程序级别进行配置覆盖。我们无法以这种方式覆盖ServiceEndpoint,只能覆盖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>
我们可以通过在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>
是否可以通过配置为每个服务实例指定配置覆盖?
我尝试通过使用服务名来确定服务实例在特定端口上侦听以确定哪个端口,以便FooInstanceA侦听端口8090,并且FooInstanceB侦听8091.
显然,Service Fabric在部署期间会发挥一些作用,因为当FooInstanceB侦听ServiceEndpoint配置上指定的端口以外的端口时,该服务无法访问。
第一个原因是端点上没有设置DACL,这可以通过运行来解决;
netsh http add urlacl http://+:8091/ user=everyone listen=yes
这允许服务在Service Fabric Explorer中出现并显示健康,但是当我们使用http://localhost:8091/访问时,FooInstanceB响应HTTP 503错误
我们如何才能让服务实例在不同的端口上进行监听?
我希望明白,谢谢。
答案 0 :(得分:7)
实现这一目标并不是很多很好的选择。以下是一些想法:
答案 1 :(得分:0)
我认为在SF群集前面有一个url重写服务是一个非常好的主意。
这可以为您提供多个端点并进行网址重写,防火墙/黑名单,https等。
其他方式是将服务打包为lib或Nuget,并使用不同的服务清单创建所需的N个服务。
答案 2 :(得分:0)
我已经设法使用ApplicationParameter xml文件执行此操作,并在VSTS中部署期间选择正确的文件。 例如,这是我用于部署到测试环境的Cloud.xml。技巧是第二行的Name参数。我已使用此文档指定了端口: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>
这是Staging:Staging.xml
的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>
如上所述使用Traefik反向代理here我可以使用主机名来访问我的服务。 在VSTS中,我使用tokenizer来替换ServiceManifest中的主机名,并在部署期间替换ApplicationManifest中的ApplicationTypeName。
这是我的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>