Service Fabric 命名服务未转发到分配给来宾可执行文件的端点
Service Fabric Naming Service not forwarding to endpoint assigned to Guest Executable
我已经按照此处的指南设置了一个包含两项服务的应用程序,一项是标准的 aspnet 核心 api,另一项是节点快速应用程序:
https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-deploy-existing-app
当我在本地部署应用程序时,我可以使用命名服务来访问 AspNetCore 应用程序,例如:
http://localhost:19081/sf_node_test_02/AspNetCore/api/values
同样,我希望能够使用此地址访问我的来宾可执行文件的 api:
http://localhost:19081/sf_node_test_02/NodeApp
但是,这不起作用。
如果我使用服务的直接 url 例如:
http://localhost:30032/
我可以看到节点 js 应用程序实际上按预期工作。
现在,我知道当 运行 AspNet 核心应用程序明确将其侦听地址发送回命名服务时,但来宾可执行文件并非如此,这就解释了为什么它们的行为可能不同。此外,据我所知,当前版本的服务结构不向来宾可执行文件提供有关动态分配端口的信息,因此必须在服务端点和应用程序中进行硬编码以侦听同一端口。
例如如果我有:
<Endpoint Name="NodeAppTypeEndpoint" Port="30032" Protocol="http" Type="Input" UriScheme="http"/>
然后在nodejs应用中我还必须有:
const port = process.env.PORT || 30032;
app.listen(port, () => {
console.log(`Listening on port: ${port}`);
});
在两个地方都注意到 30032。
来自文档:
Furthermore you can ask Service Fabric to publish this endpoint to the
Naming Service so other services can discover the endpoint address to
this service. This enables you to be able to communicate between
services that are guest executables. The published endpoint address is
of the form UriScheme://IPAddressOrFQDN:Port/PathSuffix. UriScheme and
PathSuffix are optional attributes. IPAddressOrFQDN is the IP address
or fully qualified domain name of the node this executable gets placed
on, and it is calculated for you.
我将其解释为如果我的 ServiceManifest.xml
具有两个 UseImplicitHost="true"
那么它应该自动为命名服务提供由端点描述构造的 url。
http://localhost:19081/sf_node_test_02/NodeApp -> http://localhost:30032
service fabric会自动给naming service这个service的这个监听地址对吗?
我可以检查命名服务中的映射吗?
这会让我知道它是否确实有我的节点应用程序的条目,但它与我的预期不同,或者实际上它是否没有条目。
如果它没有条目,那么我不知道这个来宾可执行应用程序在部署在云中时如何对 public 可见。
您可以使用 FabricClient
的 QueryManager
列出集群中服务的已注册端点。这应该显示您的节点服务是否有端点。
var fabricClient = new FabricClient();
var applicationList = fabricClient.QueryManager.GetApplicationListAsync().GetAwaiter().GetResult();
foreach (var application in applicationList)
{
var serviceList = fabricClient.QueryManager.GetServiceListAsync(application.ApplicationName).GetAwaiter().GetResult();
foreach (var service in serviceList)
{
var partitionListAsync = fabricClient.QueryManager.GetPartitionListAsync(service.ServiceName).GetAwaiter().GetResult();
foreach (var partition in partitionListAsync)
{
var replicas = fabricClient.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id).GetAwaiter().GetResult();
foreach (var replica in replicas)
{
if (!string.IsNullOrWhiteSpace(replica.ReplicaAddress))
{
var replicaAddress = JObject.Parse(replica.ReplicaAddress);
foreach (var endpoint in replicaAddress["Endpoints"])
{
var endpointAddress = endpoint.First().Value<string>();
Console.WriteLine($"{service.ServiceName} {endpointAddress} {endpointAddress}");
}
}
}
}
}
}
我已经按照此处的指南设置了一个包含两项服务的应用程序,一项是标准的 aspnet 核心 api,另一项是节点快速应用程序:
https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-deploy-existing-app
当我在本地部署应用程序时,我可以使用命名服务来访问 AspNetCore 应用程序,例如:
http://localhost:19081/sf_node_test_02/AspNetCore/api/values
同样,我希望能够使用此地址访问我的来宾可执行文件的 api:
http://localhost:19081/sf_node_test_02/NodeApp
但是,这不起作用。
如果我使用服务的直接 url 例如:
http://localhost:30032/
我可以看到节点 js 应用程序实际上按预期工作。
现在,我知道当 运行 AspNet 核心应用程序明确将其侦听地址发送回命名服务时,但来宾可执行文件并非如此,这就解释了为什么它们的行为可能不同。此外,据我所知,当前版本的服务结构不向来宾可执行文件提供有关动态分配端口的信息,因此必须在服务端点和应用程序中进行硬编码以侦听同一端口。
例如如果我有:
<Endpoint Name="NodeAppTypeEndpoint" Port="30032" Protocol="http" Type="Input" UriScheme="http"/>
然后在nodejs应用中我还必须有:
const port = process.env.PORT || 30032;
app.listen(port, () => {
console.log(`Listening on port: ${port}`);
});
在两个地方都注意到 30032。
来自文档:
Furthermore you can ask Service Fabric to publish this endpoint to the Naming Service so other services can discover the endpoint address to this service. This enables you to be able to communicate between services that are guest executables. The published endpoint address is of the form UriScheme://IPAddressOrFQDN:Port/PathSuffix. UriScheme and PathSuffix are optional attributes. IPAddressOrFQDN is the IP address or fully qualified domain name of the node this executable gets placed on, and it is calculated for you.
我将其解释为如果我的 ServiceManifest.xml
具有两个 UseImplicitHost="true"
那么它应该自动为命名服务提供由端点描述构造的 url。
http://localhost:19081/sf_node_test_02/NodeApp -> http://localhost:30032
service fabric会自动给naming service这个service的这个监听地址对吗?
我可以检查命名服务中的映射吗? 这会让我知道它是否确实有我的节点应用程序的条目,但它与我的预期不同,或者实际上它是否没有条目。
如果它没有条目,那么我不知道这个来宾可执行应用程序在部署在云中时如何对 public 可见。
您可以使用 FabricClient
的 QueryManager
列出集群中服务的已注册端点。这应该显示您的节点服务是否有端点。
var fabricClient = new FabricClient();
var applicationList = fabricClient.QueryManager.GetApplicationListAsync().GetAwaiter().GetResult();
foreach (var application in applicationList)
{
var serviceList = fabricClient.QueryManager.GetServiceListAsync(application.ApplicationName).GetAwaiter().GetResult();
foreach (var service in serviceList)
{
var partitionListAsync = fabricClient.QueryManager.GetPartitionListAsync(service.ServiceName).GetAwaiter().GetResult();
foreach (var partition in partitionListAsync)
{
var replicas = fabricClient.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id).GetAwaiter().GetResult();
foreach (var replica in replicas)
{
if (!string.IsNullOrWhiteSpace(replica.ReplicaAddress))
{
var replicaAddress = JObject.Parse(replica.ReplicaAddress);
foreach (var endpoint in replicaAddress["Endpoints"])
{
var endpointAddress = endpoint.First().Value<string>();
Console.WriteLine($"{service.ServiceName} {endpointAddress} {endpointAddress}");
}
}
}
}
}
}