Azure上で、WorkerRoleから任意のサーバーアプリケーションを起動する方法

Tomcatを動かしていますが、その他のDB Serverとかの動かし方について、基本的なやりかた(・ω・)

ダミーサーバーアプリケーション

今回はTomcatとかのサーバーアプリケーションを使うのではなく、自前のダミーサーバーを作って説明。
っで、テストに使用するプログラムHelloServer.exeのソースはこんなんで。

class Program
{
    static void Main(string[] args)
    {
        int port = Convert.ToInt32( args[ 0 ] );

        Socket listner = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
        IPEndPoint epListen = new IPEndPoint( IPAddress.Any, port );
        listner.Bind( epListen );
        listner.Listen( 10 );

        while( true )
        {
            try
            {
                Socket socket = listner.Accept();

                byte[] buff;
                buff = Encoding.GetEncoding( "Shift_JIS" ).GetBytes( "Hello Usa*Usa." );
                socket.Send( buff );

                socket.Close();
            }
            catch( Exception )
            {
            }
        }
    }
}

引数で指定されたポートでListenして、接続を受け付けたら応答メッセージを送信して切断するだけのプログラム(´д`)
要は「mysql -P 3306」みたいにするかわりに、今回の実験では「HelloServer 9999」を使いますよということ。

エンドポイントの定義

っで、このHelloServerをWorkerRoleから動かす方法について。
まずは、サービス定義にこんな感じでポートを追加(・ω・)

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="AzureTest" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
...
  <WorkerRole name="AzureTestWorkerRole" enableNativeCodeExecution="true">
    <Endpoints>
      <InputEndpoint name="Tomcat" port="8080" protocol="tcp" />
      <InputEndpoint name="Hello" port="9999" protocol="tcp" />
    </Endpoints>
...
  </WorkerRole>
</ServiceDefinition>

HelloServer用に、ポート9999をエンドポイントとして定義しています。

WorkerRoleのソース

WorkerRoleのソースについてはこんな感じで。

public class WorkerRole : RoleEntryPoint
{
    public override void Run()
    {
        RunHello runHello = new RunHello();
        runHello.Start( RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Hello"].IPEndpoint.Port );
...

        while( true )
        {
            Thread.Sleep( 10000 );
        }
    }
...
}
public class RunHello
{
    public void Start(int port)
    {
        try
        {
            Process newProc = new Process();
            newProc.StartInfo.UseShellExecute = false;
            newProc.StartInfo.RedirectStandardOutput = true;

            newProc.StartInfo.Arguments = String.Format( "{0}", port );
            newProc.StartInfo.FileName = Environment.GetEnvironmentVariable( "RoleRoot" ) +
                                         @"\approot\Hello\HelloServer.exe";

            newProc.EnableRaisingEvents = false;
            newProc.Start();
        }
        catch( Exception ex )
        {
            Trace.TraceError( ex.Message );
        }
    }
}

やってることは、エンドポートを取得して、そのポートを引数にしてHelloServerプロセス開始するだけ。
ちょっと補足を書いておくと、RoleEnvironment.CurrentRoleInstance.InstanceEndpointsで取得できるポート番号の値は9999じゃないからね。

デプロイ

っで、WorkerRoleのプロジェクトにHelloServer.exeを含めてデプロイですが。
プロジェクト構成はこんな感じで、HelloServer.exeを出力ディレクトリに含めるように設定。

Azure上にデプロイしてtelnetとかでポート9999に繋いで見ると、「Hello Usa*Usa.」が返ってくることを確認できます(´∀`)


Tomcatについてもやってることは一緒で。
違うのは、コマンドライン引数でポートを指定できないので事前にserver.xmlを書き換えていることと、Tomcat起動のためにJREも一緒にデプロイしたり、startup.batから起動しているくらいのこと(・ω・)


っというわけで、この理屈さえわかれば任意のサーバーをWorkerRoleから動かせますね。
これで、DBサーバとかだけじゃなくて、既存の分散処理をやっている独自サーバなんかもWorkerRole上で動かせますよ(・∀・)
そこで何をやるのかが本題だけどね、ふふふ…。