是否有一种方法可以通过编程方式确定Azure DevFabric中用于端点的实际IP?
我正在Azure开发结构下托管一个IIS应用程序 将应用程序部署到Azure compute emulator时,将创建一个临时IIS应用程序,该应用程序将侦听5100左右的端口。来自公共终结点的传入请求被重定向到此端口 不过,Azure开发结构似乎并不总是使用在项目配置中声明的公共端口。例如,我们的应用程序应该公开一个公共端口80——但当我运行它时,它几乎总是端口81,但有时是端口82,以此类推 因此,我可以确保在我的应用程序中创建的URL是正确的,我想知道这个外部端口是什么 不幸的是,我不能简单地查看是否有一种方法可以通过编程方式确定Azure DevFabric中用于端点的实际IP?,azure,azure-compute-emulator,Azure,Azure Compute Emulator,我正在Azure开发结构下托管一个IIS应用程序 将应用程序部署到Azure compute emulator时,将创建一个临时IIS应用程序,该应用程序将侦听5100左右的端口。来自公共终结点的传入请求被重定向到此端口 不过,Azure开发结构似乎并不总是使用在项目配置中声明的公共端口。例如,我们的应用程序应该公开一个公共端口80——但当我运行它时,它几乎总是端口81,但有时是端口82,以此类推 因此,我可以确保在我的应用程序中创建的URL是正确的,我想知道这个外部端口是什么 不幸的是,我不能
Request.Url.Port
,因为这是临时应用程序的端口号——通常是5100RoleEnvironment.CurrentRoleInstance.InstanceEndpoints也不起作用,因为它还返回从服务器5100及其后的端口。是否尝试使用
RoleEnvironment.CurrentRoleInstance.InstanceEndpoints
我不确定自动取款机,因为我不在我的电脑后面,但很快会再次检查。无论如何,在每个端点上都有一个属性IPEndPoint,它也有端口。如果您也获得了公共端点(我认为您对当前角色实例也是如此),那么您应该能够从那里获得地址
希望对您有所帮助……您是否尝试使用
RoleEnvironment.CurrentRoleInstance.InstanceEndpoints
我不确定自动取款机,因为我不在我的电脑后面,但很快会再次检查。无论如何,在每个端点上都有一个属性IPEndPoint,它也有端口。如果您也获得了公共端点(我认为您对当前角色实例也是如此),那么您应该能够从那里获得地址
希望对您有所帮助……我认为出现“错误”端口(如81/82等)的原因是所需端口忙
可能您有其他应用程序正在侦听端口80,因此它永远不可用。此外,我也见过好几次emulator中的Azure compute实例关闭不够快,因此如果启动一个新实例,它会获得下一个端口,等等。如果我杀死它,请稍等,然后重新启动-它会获得所需的端口
它在生产中永远不应该是一个问题,这可能就是它不通过API公开的原因。在测试过程中,只需确保您没有与其他应用程序发生冲突,并留出一些时间让compute notes干净地关闭并释放端口。我认为出现“错误”端口(如81/82等)的原因是所需端口忙
可能您有其他应用程序正在侦听端口80,因此它永远不可用。此外,我也见过好几次emulator中的Azure compute实例关闭不够快,因此如果启动一个新实例,它会获得下一个端口,等等。如果我杀死它,请稍等,然后重新启动-它会获得所需的端口
它在生产中永远不应该是一个问题,这可能就是它不通过API公开的原因。在测试过程中,只需确保您没有与其他应用程序发生冲突,并留出一些时间让compute notes干净地关闭并释放端口。通过使用Reflector查看csrun.exe解决了这一问题
SDK DLLMicrosoft.ServiceHost.Tools.DevelopmentFabric
似乎是关键,尤其是方法FabricClient.GetServiceDeployments()
和FabricClient.GetServiceInformation()
。因此:
使用制度;
使用Microsoft.ServiceHosting.Tools.DevelopmentFabric
class Program
{
static void Main(string[] args)
{
FabricClient client = FabricClient.CreateFabricClient();
foreach (string tenantName in client.GetServiceDeployments())
{
var information = client.GetServiceInformation(tenantName);
foreach (var item in information)
{
Console.WriteLine(string.Format("{0} {1} {2} {3}", item.ContractName, item.InterfaceName, item.UrlSpecification, item.Vip));
}
}
Console.ReadLine();
}
}
我要找的东西将作为项.Vip返回
请注意,显然,这将只在开发结构中起作用。。。但无论如何,这就是我在这里寻找的东西。通过使用Reflector查看csrun.exe来解决这个问题
SDK DLLMicrosoft.ServiceHost.Tools.DevelopmentFabric
似乎是关键,尤其是方法FabricClient.GetServiceDeployments()
和FabricClient.GetServiceInformation()
。因此:
使用制度;
使用Microsoft.ServiceHosting.Tools.DevelopmentFabric
class Program
{
static void Main(string[] args)
{
FabricClient client = FabricClient.CreateFabricClient();
foreach (string tenantName in client.GetServiceDeployments())
{
var information = client.GetServiceInformation(tenantName);
foreach (var item in information)
{
Console.WriteLine(string.Format("{0} {1} {2} {3}", item.ContractName, item.InterfaceName, item.UrlSpecification, item.Vip));
}
}
Console.ReadLine();
}
}
我要找的东西将作为项.Vip返回
请注意,显然,这将只在开发结构中起作用。。。但无论如何,这就是我在这里寻找的。我无法让dev fabric程序集为我工作(看起来API已经更改),所以我求助于解析“csrun/status”的输出以找到给定角色名的IP地址。这里有一些获取IP的代码,但是您需要做一些额外的工作来获取端口
public static string GetEmulatorIPAddress(string roleName)
{
var psi = new ProcessStartInfo();
psi.FileName = @"C:\Program Files\Microsoft SDKs\Windows Azure\Emulator\csrun.exe";
psi.Arguments = "/status";
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
StringBuilder sb = new StringBuilder();
DataReceivedEventHandler errorHandler = (object sender, DataReceivedEventArgs e) =>
{
};
string lastIPAddress = null;
string foundIPAddress = null;
DataReceivedEventHandler dataHandler = (object sender, DataReceivedEventArgs e) =>
{
string line = e.Data;
if (line != null && foundIPAddress == null)
{
if (line.StartsWith("EndPoint: http://"))
{
int ipStart = line.IndexOf("://") + "://".Length;
int ipEnd = line.IndexOf(":", ipStart);
lastIPAddress = line.Substring(ipStart, ipEnd - ipStart);
}
if (line.Trim() == roleName)
{
foundIPAddress = lastIPAddress;
}
}
};
Process p = new Process();
p.StartInfo = psi;
p.ErrorDataReceived += errorHandler;
p.OutputDataReceived += dataHandler;
p.EnableRaisingEvents = true;
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
return foundIPAddress;
}
我无法让dev fabric程序集为我工作(看起来API已经更改),所以我求助于解析“csrun/status”的输出以找到给定角色名的IP地址。这里有一些获取IP的代码,但是您需要做一些额外的工作来获取端口
public static string GetEmulatorIPAddress(string roleName)
{
var psi = new ProcessStartInfo();
psi.FileName = @"C:\Program Files\Microsoft SDKs\Windows Azure\Emulator\csrun.exe";
psi.Arguments = "/status";
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
StringBuilder sb = new StringBuilder();
DataReceivedEventHandler errorHandler = (object sender, DataReceivedEventArgs e) =>
{
};
string lastIPAddress = null;
string foundIPAddress = null;
DataReceivedEventHandler dataHandler = (object sender, DataReceivedEventArgs e) =>
{
string line = e.Data;
if (line != null && foundIPAddress == null)
{
if (line.StartsWith("EndPoint: http://"))
{
int ipStart = line.IndexOf("://") + "://".Length;
int ipEnd = line.IndexOf(":", ipStart);
lastIPAddress = line.Substring(ipStart, ipEnd - ipStart);
}
if (line.Trim() == roleName)
{
foundIPAddress = lastIPAddress;
}
}
};
Process p = new Process();
p.StartInfo = psi;
p.ErrorDataReceived += errorHandler;
p.OutputDataReceived += dataHandler;
p.EnableRaisingEvents = true;
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
return foundIPAddress;
}
曾经尝试过,但不幸的是,这些都是“临时”端点,例如5100。我已经更新了我的问题。我害怕这个=/就像我说的,我没有办法检查。。。您只获取内部端点。但是是的,正如@Michael指出的,这是emulator中的一个bug,所以端口号不应该是一个问题。对于url部分,我们也在寻找解决方案,但不幸的是,到目前为止,我们已经求助于将url存储在配置文件中。csrun
成功地解决了这个问题(顺便说一句,似乎没有那么频繁地增加端口)-我将继续挖掘。您可以做的是使用Azure管理API()并获取当前部署的链接(RoleEnvironment.DeploymentID)。但要使其正常工作,您需要包括您的管理证书,这并不总是一件好事。不好:服务管理API在开发环境中不起作用。fabric:已经在那里尝试过了——不幸的是,这些是“临时”端点,例如5100。我已经更新了我的简历