我有一个带有Web角色和Worker角色的Windows Azure云服务。我已经建立了一个网站,允许我对云服务执行各种管理功能(停止/启动、重新启动实例、添加实例、删除实例)。所有功能都是通过web api执行的。我的问题是,当我添加web角色的实例时,工作者角色会重新启动。请注意,如果我通过Azure门户添加实例,则不会发生这种情况。代码在所有其他方面都能正常工作。你知道如何做到这一点吗?这样只有受影响的角色才能回收,而不是所有角色都能回收?
我的代码:
public void AddInstance()
{
XDocument configDoc = this.GetDeploymentConfiguration();
var ns = configDoc.Root.GetDefaultNamespace();
configDoc.Root
.Elements( ns + "Role" )
.FirstOrDefault( r => r.Attribute( "name" ).Value.ToLower() == this.RoleName.ToLower() )
.Element( ns + "Instances" )
.Attribute( "count" )
.Value = ( int.Parse( configDoc.Root
.Elements( ns + "Role" )
.FirstOrDefault( r => r.Attribute( "name" ).Value.ToLower() == this.RoleName.ToLower() )
.Element( ns + "Instances" )
.Attribute( "count" )
.Value ) + 1 ).ToString();
string encodedString = Convert.ToBase64String( Encoding.UTF8.GetBytes( configDoc.ToString() ) );
this.SetDeploymentConfig( encodedString );
}
public XDocument GetDeploymentConfiguration()
{
string uri = string.Format( this.servicePropertiesOperationFormat, this.subscriptionID, this.serviceName, "production", "" );
ServiceManagementOperation operation = new ServiceManagementOperation( this.thumbprint, this.versionID );
var xdoc= operation.Invoke( uri );
var myelm = xdoc.Element( wa + "Deployment" ).Element( wa + "Configuration" );
var mystring= Encoding.UTF8.GetString( Convert.FromBase64String( myelm.Value ) );
return XDocument.Parse( mystring );
}
public string SetDeploymentConfig( string configurationFile )
{
string uri = string.Format( this.servicePropertiesOperationFormat, this.subscriptionID, this.serviceName, "production", "/?comp=config" );
ServiceManagementOperation operation = new ServiceManagementOperation( this.thumbprint, this.versionID );
string payloadString = string.Format(
@"<?xml version=""1.0"" encoding=""utf-8""?>
<ChangeConfiguration xmlns=""http://schemas.microsoft.com/windowsazure"">
<Configuration>{0}</Configuration>
</ChangeConfiguration>", configurationFile );
XDocument payload = XDocument.Parse( payloadString );
return operation.Invoke( uri, payload );
}
这不是很直观,但你必须取消缩放事件,否则这将告诉Azure重新启动其他实例。在RoleEntryPoint文件中的OnStart方法中添加以下行:
RoleEnvironment.Changing += (sender, args) => { args.Cancel = false; };