今更ながら Windows Azure MySQL PHP Solution Accelerator を試す
今は、Azure Companion を利用してインストールするのが旬?のようですが、インストールできるDBがMariaDBだったり、細かい設定とかがいじれるのか不安なので、いぶし銀のMy SQL PHP Solution Accelerator を利用してみることにしました。
Azure 上でJava を動かすにせよ、PHPを動かすにせよ、Ruby を動かすにせよ、一応MySQLが動かないことには実用的に話にならないので、何は無くてもMySQL(+PHPMyAdmin)の設定は避けては通れません(SQL Azure はひとまず置いといて・・・)。
で、設定なのですが、
基本的には
http://msdn.microsoft.com/ja-jp/windowsazure/ff406399
を参考にすれば動くはずなのですが、なかなかどうして動きません・・・。
ネットを検索すると「さらっと、動きます!」的なエントリがあるのですが、そんな気配は全くありません。2009年のリリース当初はさらっと動いたのでしょうか・・・。
というわけで、長文、散文ですが、ハマった点などをメモ。
まず、準備するものは、何はなくとも、Solution Accelerator。それは、ここからダウンロードし、インストールします。32bit版と64bit版があります。私は、64bit版をダウンロードしました。ダウンロードしたら、インストールします。標準インストールすると、
C:\Samples\AzureMySQLPHP_x64
配下にインストールされます。
インストール直後のディレクトリ構造は下記のような感じ。
次に、Solution Accelerator の構成に必要なMySQLやPHP、PHPMyAdminなどのバイナリファイルをダウンロードします。
が、これが、どれをダウンロートしてよいやらわかりません・・・。とりあえず、
- MySQLは mysql-noinstall-5.1.56-winx64.zip
- PHPは php-5.2.17-nts-Win32-VC6-x86.zip
- PHPMyAdminは phpMyAdmin-3.3.9.2-all-languages.zip
っていうのをダウンロードしてきました。
残念ながらSolution Accelerator 登場当時のものはもうありませんでした・・・。MySQLは、インストーラではないやつ、PHPはNon Thread Safeのやつ、PHPMyAdmin はとりあえず、最新のやつにしました。
これをダウンロードしてきて、適当なディレクトリに展開しておきます。後で使うBuildmeというコマンドラインツールにて、各バイナリの場所を指定することになるので、パスがシンプルでわかりやすいディレクトリにしておく方がいいです。
私は、
C:\downloads\
以下に、それぞれ、
C:\downloads\mysql
C:\downloads\php
C:\donwloads\phpmyadmin
と展開しました(下記参照)。
この時、各ディレクトリ配下直にBinやexeなどのファイルが来るようにしておきます(普通に展開するとmysqlとかの下に、mysql-5.2.15とかのディレクトリができてしまうのでそうならないようにします)。
基本的な流れとしては、Accelerator フォルダ以下にて、
- Buildme.cmd を実行し、必要なファイル等のパスを指定して、ビルド。
- PHPやPHPMyAdmin等の設定ファイルの変更など。
- Runme.cmd で、ローカル実行し、デバッグ。
- 問題なければPackme.cmd で、Upload用パッケージ作成。
だけなのですが、これがなかなか。
とりあえず、マニュアル通りにやってみます(エラーでますけど)。
1.Buildme の実行
まず、Windows Azure SDK Command Prompt を立ち上げ、Accelerator フォルダにて、
Buildme.cmd
を実行します。すると、MySQL のバイナリがあるディレクトリを聞いてきますので、入力します。私の場合、
C:\downloads\mysql
です。PHP(C:\downloads\php)、PHPMyAdmin(C:\downloads\phpmyadmin)についても同様に入力していきます。
Build Complete...
が表示されます。
が、同時にWarningも表示されます。これは、ServiceDefinition.csdef のファイル形式が古い!と怒られているのですが、<Site>タグ等を加えた表記にすると、今度は「<Site>なんて知らん!」と怒らててしまうので、とりあえず無視します。
Buildmeの実行と表示される警告(とりあえず無視)
Buildme が完了すると、MySQL等のバイナリファイル等が、必要なディレクトリにコピーされ、さらに、その中から必要なファイルがAccelerator ディレクトリ直下に自動作成されたMySqlPhpMyAdmin.csxフォルダにコピーされ、実行環境が作成されるようです。
2.各種設定ファイルの設定・変更
各サーバやアプリケーションを正しく動作させるためには、いくつかのファイルを編集する必要があるようです。
まず、PHP関連(php.ini)
PhpMyAdminWebRole フォルダ以下のPHPフォルダにある php.ini-recommendedをphp.ini とリネームし、その内容を変更します。変更点は、
extension_dir が"./" となっているところを"./ext" とします。また、コメントされたextension のうち、
extension=php_mysql.dll
extension=php_mbstring.dll
extension=php_mcrypt.dll
の3つをコメントアウトします。
PHPMyAdmin 関連(config.defualt.php)
PhpMyAdminWebRole フォルダ以下のphpmyadmin\libraries\config.defualt.php を開き内容を変更します。変更点は、
$cfg['AllowArbitraryServer'] = false を true に変更します。
それで、問題のMySQL、、、
マニュアルにはないのですが、正しいMy.ini を正しい場所に設置し、正しく設定してやる必要があります。
まず、正しい、My.iniとは、MySql_WorkerRole直下に最初から存在しているMy.iniです。実は、このMy.ini。中身を見ればわかるのですが、Accelerator 用に特化したMy.ini なのです。なので、自分でMy.ini などをゼロから作成すると正しく動きません。
次に、My.ini を正しい場所に置く必要がありますが、その場所とは、C:\Samples\AzureMySQLPHP_x64\MySql_WorkerRole\bin\Release\mysqlとなります(赤字は環境に依存します)。
ローカル実行時に利用するcsxフォルダや、AzureにUpするcspkgの生成には、MySql_WorkerRole\bin\Release\以下のMySQLが利用されるらしく、ここににおいてやらないと設定が全く反映されません(PHPMyAdminは、PHPMyAdminWebRole直下のものがコピーされるのに・・・)。
次に正しい設定ですが、このMy.ini の中に、
skip-locking
という起動オプションが設定されているのですが、最近のmysqld がこれを受け付けず、こっそりとエラーを吐いて起動しません。最新の推奨は、
skip-external-locking
らしいので、そのように記述します。
設定ファイルの設定・変更はとりあえず以上です。
3.Runme の実行
次に、Runme.cmd を実行し、ローカルで動作を確認します。Runmeは、MySqlPhpMyAdmin.csx 以下のファイル群を実行するようです。
Runmeの実行は、Accelerator 直下にて
Runme.cmd
とします。ローカルでの実行がはじまります。この時、あらかじめCompute Emulator とStorage Emulator を起動しておくとよいでしょう(起動してなくても、起動するか聞いてきますけど)。また、裏でBuildmeがもう一度実行されるので、Buildme実行時と同様のエラーが出力されますが、同様に無視です。
しばらく待つと、PHPMyAdmin の画面が起動し、一見うまく動いているように見えます。
が、結論から言えば、うまく動いていません。
ログインしてもログインできません。ちなみに、初期状態で設定されるIDとPasswordは
ID : mysqluser
PW : #ms123
です。なお、そもそもの、サーバ名はlocalhostでいいのですが、Port が動的に割り振られるのでPort 番号を指定する必要があります。動的に割り振られたPort 番号を知るためには、PHPMyAdmin のページが表示される前に表示されていたWebページにて確認することができます。
この場合、Port は 5119 になりますので、サーバ名をlocalhost:5119 と指定すればいいのですが、そもそもMySQL が起動していないため、アクセスすることができません。
Compute Emulator を起動して、MySQL のコンソール画面を見てみますと、何やらエラーをはいています。
エラー箇所を見てみると、
[fabric] Role Instance: deployment(60).MySqlWithNewSdk.MySql_WorkerRole.0
[fabric] Role state Busy
[runtime] Role entrypoint . CALLING OnStart()
[WaWorkerHost.exe] Error when reading control container:Microsoft.WindowsAzure.StorageClient.StorageClientException: The specified account is disabled. ---> System.Net.WebException: リモート サーバーがエラーを返しました: (403) 使用不可能
という感じで、どうやらStorage 関連のエラーのようです。どうやら、アカウント等が正しく設定されていないことによるもののようです。
3.5. エラーの修正
では、エラーを修正していきます。csdefやcscfg等を正しく設定します。ファイルをテキストエディタで編集してもよいのですが、私は必ず設定ミスをするので、VisualStudio 2010 (VS2010) を利用しました(これがハマるポイントでしたが・・・)。
Accelerator フォルダのソリューションファイルをVS で開きます。私はVS 2010 を利用しているので、変換ウィザードが起動します。
ウィザードを利用すると、途中で「使ってる.NETが古いけど4.0にする?」と聞かれますが、これでYesと答えてはだめです。あとで、.NET Framework のバージョンが違う!と怒られます。
ソリューションが開くと、MySql_WorkerRole のSettings を確認すると、
Strorage のEndpoint やDataConnectionString がダミーのものになっています。これを正しく設定していくのですが、2つの方法が考えられます。1つは、とりあえず、ローカル環境の設定を行うパターンと、Azure 上のStrage アカウントを設定してしまうパターンの2つです。
ローカルのパターン
ローカルの場合は、
http://table.core.windows.net を http://127.0.0.1:10002/
http://blob.core.windows.net を http://127.0.0.1:10000/
ConnectionString および DiagnosticsConnectionString を UseDevelopmentStorage=true
とします。が、どっち道、最後はAzure上に上げないといけないので、私はAzure上のStorageを直接指定しました。
Azure上のStorage を直接指定する場合は、
http://table.core.windows.net を http://account_name.table.core.windows.net
http://blob.core.windows.net を http://account_name.blob.core.windows.net
ConnectionString および DiagnosticsConnectionString に適切なAccount Name およびAccount Key を設定します。なお、Account Name とAccount Key はAzure Management Portal 画面から確認し、記入します。
私はついでに、BackupをFalseにし、起動するインスタンスを"1"に変更しました。
修正後、再度、Buildme、Runme を行うのですが、実は、この2つのプログラムが利用するcscfg および csdefファイルは、Accelerator 直下のもので、VS を起動し、編集したものは、MySQLPHPフォルダ以下のものなので、VSでの編集は実行ファイルに反映されません。
Accelerator 直下のファイルと、MySQLPHPフォルダ以下のファイルはほぼ同じものなので、VSで編集できるMySQLPHP がビルドや実行に利用されるようにBuildmeおよびRunmeバッチファイルの内容を少し変更します。
それぞれのバッチファイルの中の
ServiceDefinition.csdefおよびServiceConfiguration.cscfg
となっている箇所を
MySQLPHP\ServiceDefinition.csdefおよびMySQLPHP\ServiceDefinition.csdef
と変更することでMySQLPHP 以下のファイルが利用されるようになります(ついでにPackmeも編集しておくとよいでしょう)。変更が終了したら、一度、Buildmeを実行してみてください。
今度はWeb/がどうしたこうしたと怒られます。これは最新のVS2010でファイルを編集したために、Full IIS用のコードが挿入されてしまったために出るエラーです。このエラーを防止するには、csdefファイル中に(勝手に)挿入された<Sites>タグを削除します。なお、このコードはWebRoleのところ2カ所にありますので、ご注意を。
<Sites>
<Site name="Web">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" />
</Bindings>
</Site>
</Sites>
削除したら、再度Buildmeを実行してみます。エラーはでません。
Buildme が終わったら次はRunmeを実行してみます。
エラーは消えました。
このとき、XMLエラーが出ることがありますが、これはAccelerator のcscfgファイルの文字コードがANSI になっているためで、これをUTF-8 に変更することで解決できます。
MySQL の起動は、MySQL の起動時にWindows Firewall がMySQL の接続許可を求めてくるので確認わかります。
Firewall がOFF になっていたら、これは出ませんが、Task Manager のプロセスにmysqld が現れるのでわかります。
MySQL の起動を確認したのち、
http://127.0.0.1:81/admin.aspx
にアクセスしてみましょう(自動起動しますが、その時は、まだMySQL が起動していないので正しく動作しません)。
すると、
こんな画面が表示されるので、「Show MySQL Instances」ボタンを押してみます。MySQL が正常に起動していれば、
このような画面が表示されます。The server is online となっていることがポイントです。なお、一般的にMySQL のPort は3306 ですが、Accelerator では、動的に割り当てられます(固定にすることもできます。もちろん)。
この場合、5105を利用しています。このPort はPHPMyAdminログイン時に必要なので、覚えておきます。
上記画面はしばらくすると、自動的にPHPMyAdminのログインページにリダイレクトされるので、ログイン情報を入力し、ログインしてみます。
サーバ名は、Port 番号と合わせて入力します。ユーザ名はmysqluser、パスワードは#ms123が初期状態で設定されています。
ログインできました。下段にいろいろエラーというか警告が出ていますが、DLLとかのミスマッチなので、ま、簡単に治るでしょう。ここではとりあえず無視。
で、とりあえず、ローカルではOKなので、Packmeコマンドを利用して、Azure にUpするcspkgファイルを作ります。そのためにはAccelerator フォルダにて、
Packme.cmd
を実行するだけです。このとき、Packme.cmd がMySQLPHPフォルダ配下のcsdefファイルを利用するように、バッチの中を、
cspack.exe MySQLPHP\ServiceDefinition.csdef /role:InstanceManagerClien~(省力)
と修正することをお忘れなく。しばらく待つとcspkgが作成されるので、Azure上にUpします。この時も、cscfgファイルは、MySQLPHP配下のものをUpするように注意してください。
これでOK。めでたしめでたし!のはずなのですが、残念ながら、Upしたものはすんなりとは動いてくれません。
一度は、全てのRole がReady 状態になるのですが、しばらくたつと、Stablizaing とか、Initializingになったり、Stoppingになったりします・・・。
うー。なんだろう・・・。
Blobにたまった無数のログを1つ1つ確認していると、
Error in MySqlAccess start(): There is not enough space on the disk.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
at MySql_WorkerRole.MySQLClient.Start(Int32 id) in D:\VSTF-AzureSolAcc\Solutions\P0MySqlPHPWiki\MySqlPhpMyAdmin\MySql_WorkerRole\MySQLAccess.cs:line 395
なるエラーを発見。Accelerator はご丁寧に、My.iniの設定を自動生成するんですけど、その手続きの中で、「ディスクの容量が足りない!」と言っているようなので、MySql_WorkerRoleのLocal Storage の大きさを増やしてやることにしました。
MySQLが75MBとなっていたので、1000MBに変更。
この状態で、再度、Buildme、Packemeをかまして、Upすると、、、、
とりあえず、動きました!!!。
DLLの不整合アラートとかは相変わらずですが、とりあえず、MySQLは動いてます・・・。
Port の固定とか、いろいろありますが、それはまた別の機会に・・・。
その他の注意事項
既に、MySQLがインストールされている環境で開発すると、Portが衝突し、起動しません。また、既にPHPがインストールされている環境で開発すると、既存の(IISにマップされた)PHPの設定が優先され、PHPMyAdminが「DLLが見つからない!」などのエラーを吐きます。なので、開発環境では、MySQLやPHPをアンインストールし、IISを停止させるなどしておくのが良いでしょう。