又してもWindows Azureを弄ったノウハウが溜まってきたので放出。突っ込み希望、質問等ももちろん希望!みんな、Windows Azureをもっといじろうじゃないか!!
*.cscfg と *.csdef ファイルの位置づけを理解せよ!!
Windows Azureの設定ファイルは *.cscfg と *.csdef の二つが存在します。こ奴らの位置づけとしては以下な物だと考えます。
- *.csdefファイル
- ⇒ 設定値のキーだけ定義
- ⇒ ポータルサイトにデプロイ後は変更不能
- *.cscfgファイル
- ⇒設定値の値を定義
- ⇒ ポータルサイトにデプロイ後は変更可能
以下、これ等設定ファイルの具体的な使用例を載せてみます。
- csdefファイルの内容 〜定義だけだよw〜
<WebRole name="CloudMvcApp" enableNativeCodeExecution="false"> <InputEndpoints> <InputEndpoint name="HttpIn" protocol="http" port="80" /> </InputEndpoints> <ConfigurationSettings > <!-- 自分で定義した情報 --> <Setting name="MVC_Message" /> </ConfigurationSettings> </WebRole>
- cscfgファイルの内容 〜csdefファイルで定義したキーの値を定義〜
<Role name="CloudMvcApp"> <Instances count="1" /> <ConfigurationSettings > <Setting name="MVC_Message" value="Hello Azure ASP.NET MVC なのだが、日本語OK?" /> </ConfigurationSettings> </Role>
上記の設定ファイルに記述した内容について、ソースファイル内では以下の様に使用します。RoleManager#GetCongigurationSettingに、キー名の文字列を引数に与えると値が取得できます。
- HomeController.cs (抜粋)
public ActionResult Index() { ViewData["Message"] = RoleManager.GetConfigurationSetting("MVC_Message"); return View(); }
が、本番環境にデプロイした際に大問題…。cscfgファイルで定義した値が日本語の場合、本番環境では以下の様に文字化けする模様、みんな気をつけよう!!
複数のWebロールを共存させる件について…
複数のWEBロールを一つのアーカイブにまとめてデプロイする場合、以下の様に接続ポートを変更します。
- csdef ファイルの内容
<WebRole name="LogWebRole" enableNativeCodeExecution="false"> <InputEndpoints> <!-- ポート番号は8080 --> <InputEndpoint name="HttpIn" protocol="http" port="8080" /> </InputEndpoints> (中略) </WebRole> <WebRole name="CloudMvcApp" enableNativeCodeExecution="false"> <InputEndpoints> <!-- ポート番号は80 --> <InputEndpoint name="HttpIn" protocol="http" port="80" /> </InputEndpoints> (中略) </WebRole>
接続ポートが異なるので、もしもWEBロール間で遷移させたかったら、以下の様に書いたりすると行けます*1。
public ActionResult Index() { try { ViewData["Message"] = RoleManager.GetConfigurationSetting("MVC_Message"); } catch (Exception e) { ViewData["Message"] = e.StackTrace; } ViewData["ASP_NET_URL"] = "http://" + Request.Url.Host + ":8080"; return View(); }
Windows Azureのログシステムを使う…?
Azureでのログ出力ですが、コードとしては以下の形で出力されます。
using Microsoft.ServiceHosting.ServiceRuntime; public class WorkerRole : RoleEntryPoint { public override void Start() { // ここでログの出力 RoleManager.WriteToLog("Information", "Worker Process entry point called");
ローカル環境での実行では、Development Fabricからログ出力を確認可能です(以下の画像参照)。
本番環境ではDevelopment Fabricが存在しない為、どうやってログの確認をするのかなぁと思いまして、Windows Azure Platform Training Kitを探っていたところ、「WindowsAzurePlatformKit\Demos\WindowsAzureGuestBookLogging\Demo Script - Logging and Configuration.docx」に方法が載ってました。
が、中身を参照して手順どおりに作業を進めたところ、Azure ポータルサイトのlogginシステムが改善中になっている・・・。後日試す事にしよう・・・。
http://blogs.msdn.com/windowsazure/archive/2009/10/03/upcoming-changes-to-windows-azure-logging.aspx
北米に繋ぐのは重い&時間がかかる
試しに以下のASP.NETのコードを書いてみました。処理自体は
- 1秒ごとにポストバック処理をする
- 現在の日付・時刻を画面に描画する
だけを行う簡単な処理です。
- Default.aspx(抜粋)
<h1> ログ用のテストプロジェクト</h1> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <div> <asp:Label ID="NowTimeLabel" runat="server" Text="Label"></asp:Label> </div> <asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick"> </asp:Timer>
- Default.aspx.cs(抜粋)
protected void Timer1_Tick(object sender, EventArgs e) { NowTimeLabel.Text = DateTime.Now.ToString(); RoleManager.WriteToLog("Verbose", "Time1_Tick"); }
- 動作イメージ
こ奴を実行したところ、ローカル環境では元気に動いていましたが、本番環境では更新される時間が2〜3秒ペースとなっております。うーん、この程度のポストバック処理で遅延するのは結構ダメージが大きそうだ…。
本番環境で日本語が入ったSite.Master使うと、文字化けをしてしまう
ASP.NET MVCを使っている人にとって、以下はおなじみの画面だと思います。まずは以下の画像をご覧ください。
赤で囲んでいる部分の日本語が文字化けしており、青い部分は日本語が文字化けしていません。実はこれ、Site.Masterの日本語 or Index.aspxの日本語かの違いしかないのです。ローカル環境では文字化けが起きないのですが、実行環境ではこの有様。うーむ…。