我們在微軟的Windows Azure雲計算平台上進行軟體開發時,很有可能會遇到這個需求,那就是擷取使用者的角色環境資訊。比如要擷取目前的執行個體名稱、部署ID(DeploymentID)、甚至是要知道哪些角色在運作?哪些角色沒有運作?如果我們要使用NodeJS來實作這些任務,那就需要一些技巧。因為角色環境類(RoleEnvironment)是托管的.NET代碼。
在本文中,我們會讨論怎樣設定正在運作的Azure角色資訊,以便讓這些資訊能夠很容易地被NodeJS伺服器所通路。訣竅是使用環境變量和使用啟動任務,用運作的PowerShell作為兩者間的橋梁。
下面我建立了一個例子來說明這一點,大家可以自行測試。基本上,它獲得了啟動任務,它把Azure角色環境資訊轉存到環境變量,并用server.js腳本檔案輸出這些變量。無論如何,大家可以從下面的代碼看它到底是怎麼工作的。
我們需要完成下列任務:
1、建立一個啟動任務,該任務運作一個cmd腳本,腳本可通路Azure角色環境資訊;
2、設定環境變量的資訊,以便于可以從NodeJS通路這些資訊;
3、通過process.env對象,用server.js擷取值。
下面進行詳細說明。cmd腳本是這樣的:
腳本一:setupenvironmentvariables.cmd
@ECHO off
%~d0
CD "%~dp0"
IF EXIST %WINDIR%\SysWow64 (
set powerShellDir=%WINDIR%\SysWow64\windowspowershell\v1.0
) ELSE (
set powerShellDir=%WINDIR%\system32\windowspowershell\v1.0
)
ECHO Setting the Environment variables..
CALL %powerShellDir%\powershell.exe -Command Set-ExecutionPolicy unrestricted
CALL %powerShellDir%\powershell.exe -Command "& .\set_azure_role_information.ps1"
ECHO Done!
ECHO Restarting IIS..
CALL iisreset
ECHO Starting the W3SVC service..
CALL NET START W3SVC
上面的代碼解釋如下:
1、要在Azure雲上執行未簽名的PowerShell腳本,你必須把執行政策(Execution Policy)設定為無限制(Unrestricted)。我使用了Set-ExecutionPolicy指令,但要注意它的值不會改變,除非你手動修改值。在PowerShell 2.0環境下,還可以使用-ExecutionPolicy指令來設定在目前範圍下無限制。但是由于預設的WebRole模闆使用了osFamily="1"設定,它在Windows Server 2008 SP2有效,是以我們不會使用此指令。
2、重點:在環境變量設定後,我們需要重新開機IIS伺服器,重新開機W3SVC,讓服務生效。Azure雲平台的W3SVC設定為手工模式,是以這就是為什麼它不會在IIS伺服器複位後自動啟動。
我們來看下一個PowerShell腳本:
腳本二:setazurerole_information.ps1
[Reflection.Assembly]::LoadWithPartialName("Microsoft.WindowsAzure.ServiceRuntime")
[Environment]::SetEnvironmentVariable("RoleName", [Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::CurrentRoleInstance.Role.Name,"Machine")
[Environment]::SetEnvironmentVariable("RoleInstanceID", [Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::CurrentRoleInstance.Id,"Machine")
[Environment]::SetEnvironmentVariable("RoleDeploymentID", [Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::DeploymentId,"Machine")
[Environment]::SetEnvironmentVariable("IsAvailable", [Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::IsAvailable,"Machine")
[Environment]::SetEnvironmentVariable("CustomVariable", "Some value","Machine")
代碼說明:我們通過RoleEnvironment屬性值設定一些環境變量。要注意,還可以設定自定義的環境變量。
腳本三:ServiceDefinition.csdef
"setup_environment_variables.cmd"
executionContext="elevated" taskType="simple" />
最後,我們用NodeJS編寫server.js代碼,它可以輸出響應的結果。
腳本四:server.js
var http = require('http');
var port = process.env.port || 1337;
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write("Role Name: " + process.env.RoleName + "\n");
res.write("Role InstanceID: " + process.env.RoleInstanceID + "\n");
res.write("Role DeploymentID: " + process.env.RoleDeploymentID + "\n");
res.write("Is running?: " + process.env.IsAvailable + "\n");
res.write("Custom variable: " + process.env.CustomVariable + "\n");
res.end();
}).listen(port);
在模拟器上運作上面的例子,顯示的結果如下:
