在运行时将服务实例 ID 传递给来宾可执行文件
Passing service instance ID into guest executable at runtime
是否可以在运行时将服务实例 ID(int 值)传递给来宾可执行文件?我看过 <ExeHost><Arguments>
,但它只适用于必须预先提供的静态数据。
它在环境变量中可用。请在此处查看可用于服务的环境变量的完整列表:https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-manage-multiple-environment-app-configuration
请注意,您要求的 Fabric_ServicePackageInstanceId 通常仅供内部使用,它标识了整个服务包。这意味着如果您的服务包中有多个代码包(可执行文件),它们都将获得相同的 ID。
环境变量提供的服务包实例ID与instance/replicaID不同。一般来说,SF的环境变量可以提供与使用FabricRuntime
相同的信息,即节点上下文和代码包激活上下文。在本机 SF 服务中,实例 ID 由 Fabric 在 运行 时提供(在 ServiceContext
class 中),因为单个进程可以托管多个分区并且 instances/replicas .
在不使用 SF API 的来宾可执行文件中,唯一的选项 AFAIK 是在单独的可执行文件中查询 Fabric 以获取此信息,运行 它作为 SetupEntryPoint
(运行s 每次在来宾可执行文件之前)并将信息写入文件。
例如(将代码编译成GetFabricData.exe
并添加到代码包中):
private static async Task MainAsync(string[] args)
{
var serviceTypeName = args.FirstOrDefault();
if (string.IsNullOrEmpty(serviceTypeName)) throw new ArgumentNullException(nameof(serviceTypeName));
using (var client = new FabricClient())
{
var activationContext = FabricRuntime.GetActivationContext();
var nodeContext = FabricRuntime.GetNodeContext();
var nodeName = nodeContext.NodeName;
var applicationName = new Uri(activationContext.ApplicationName);
var replicas = await client.QueryManager.GetDeployedReplicaListAsync(nodeName, applicationName);
// usually taking the first may not be correct
// but in a guest executable it's unlikely there would be multiple partitions/instances
var instance = replicas.OfType<DeployedStatelessServiceInstance>()
.FirstOrDefault(c => c.ServiceTypeName == serviceTypeName);
if (instance == null)
{
throw new InvalidOperationException($"Unable to find a service instance for {serviceTypeName}");
}
File.WriteAllText("FabricData", instance.InstanceId.ToString());
}
}
并且在服务清单中:
<SetupEntryPoint>
<ExeHost>
<Program>GetFabricData.exe</Program>
<Arguments>Guest1Type</Arguments>
</ExeHost>
</SetupEntryPoint>
然后,来宾可执行文件可以简单地读取 FabricData
文件。
是否可以在运行时将服务实例 ID(int 值)传递给来宾可执行文件?我看过 <ExeHost><Arguments>
,但它只适用于必须预先提供的静态数据。
它在环境变量中可用。请在此处查看可用于服务的环境变量的完整列表:https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-manage-multiple-environment-app-configuration
请注意,您要求的 Fabric_ServicePackageInstanceId 通常仅供内部使用,它标识了整个服务包。这意味着如果您的服务包中有多个代码包(可执行文件),它们都将获得相同的 ID。
环境变量提供的服务包实例ID与instance/replicaID不同。一般来说,SF的环境变量可以提供与使用FabricRuntime
相同的信息,即节点上下文和代码包激活上下文。在本机 SF 服务中,实例 ID 由 Fabric 在 运行 时提供(在 ServiceContext
class 中),因为单个进程可以托管多个分区并且 instances/replicas .
在不使用 SF API 的来宾可执行文件中,唯一的选项 AFAIK 是在单独的可执行文件中查询 Fabric 以获取此信息,运行 它作为 SetupEntryPoint
(运行s 每次在来宾可执行文件之前)并将信息写入文件。
例如(将代码编译成GetFabricData.exe
并添加到代码包中):
private static async Task MainAsync(string[] args)
{
var serviceTypeName = args.FirstOrDefault();
if (string.IsNullOrEmpty(serviceTypeName)) throw new ArgumentNullException(nameof(serviceTypeName));
using (var client = new FabricClient())
{
var activationContext = FabricRuntime.GetActivationContext();
var nodeContext = FabricRuntime.GetNodeContext();
var nodeName = nodeContext.NodeName;
var applicationName = new Uri(activationContext.ApplicationName);
var replicas = await client.QueryManager.GetDeployedReplicaListAsync(nodeName, applicationName);
// usually taking the first may not be correct
// but in a guest executable it's unlikely there would be multiple partitions/instances
var instance = replicas.OfType<DeployedStatelessServiceInstance>()
.FirstOrDefault(c => c.ServiceTypeName == serviceTypeName);
if (instance == null)
{
throw new InvalidOperationException($"Unable to find a service instance for {serviceTypeName}");
}
File.WriteAllText("FabricData", instance.InstanceId.ToString());
}
}
并且在服务清单中:
<SetupEntryPoint>
<ExeHost>
<Program>GetFabricData.exe</Program>
<Arguments>Guest1Type</Arguments>
</ExeHost>
</SetupEntryPoint>
然后,来宾可执行文件可以简单地读取 FabricData
文件。