AWS+Windows環境における大規模ソーシャルゲーム開発/運用の実際

第2回 大規模Windows環境におけるデプロイ

この記事を読むのに必要な時間:およそ 3 分

ASP.NET(C#)におけるビルドとデプロイ

私たちの会社ではASP.NET MVCという.NET Framework上で動くWebフレームワークを使って開発しています。前回書いたとおり,開発言語にはC#を採用しています。

C#で書いたコードを.NET Framework上で動作させるには,コードをビルドして実行可能なバイナリを生成する必要があります。正確にはCILという中間言語にコンパイルし,CLRと呼ばれる共通言語ランタイムが実行時にネイティブコードにコンパイル(JITコンパイル)しながらプログラムを実行します。ASP.NETの場合,Windows Server上に構築したIISと呼ばれるアプリケーションサーバ上で動かすことが多いですが,その場合もビルドして生成されたバイナリをIISにデプロイします。このとき,C#で書かれたコードは拡張子dllを持つバイナリファイルに変換され,設定ファイルなどとともにIISサーバ上の特定のフォルダに配置されます。C#からバイナリに変換するビルド処理,およびIISへの単純なデプロイ処理に関しては,統合開発環境であるVisual Studioが標準機能としてサポートしています。

CIツールとの連携

MSBuildとMSDeploy

チーム開発の場合,ソースコード管理システムを用意し,コードがコミットされたら自動的に開発サーバに変更を反映してテストする,いわゆるCIツールを利用することが多いと思います。CIツールと連携してビルドやデプロイを行うためのコマンドとして,MSBuildMSDeployなどが提供されています。

Visual StudioのビルドはMSBuildを使用しますが,MSBuild自体はVisual Studioに依存していません。そのため,CIサーバにVisual StudioをインストールしなくてもMSBuildによるビルドが行えます。さらに,プロジェクトやライブラリの依存関係,ビルド時の処理などの制御方法はVisual Studioのプロジェクトファイルに定義されているため,Visual Studioでの開発に用いたファイル一式をそのままMSBuildに与えるとビルドできます図1)。

図1 MSBuildのコマンド例

msbuild.exe /m /p:Configuration=Debug,MvcBuildViews=true /t:Build /v:Minimal

MvcBuildViews=trueというオプションは,Webページのテンプレートを静的に型付けしてコンパイルする,という指定です。ASP.NET MVCにはRuby on RailsやPHPと同様,Webページのテンプレートがあります。静的型付けと構文チェックを行いながら,このテンプレートをコンパイルできるのです。

また,今IIS上で動いているアプリケーションがGitのどのコミットをビルドしたものかをデプロイ後に追跡可能にするため,MSBuildを実行するときにGitのコミットハッシュをdllのメタ情報に埋め込む処理も行っています。

MSDeployはIISへのWebアプリケーションの配置や管理を簡単に行うためのツールで,IIS Web配置ツールと呼ばれます。先ほどお話したとおり,IISにはdllと設定ファイル群をデプロイします。MSBuildのオプションを指定すれば,これら一式をMSDeployでデプロイ可能な,固有のフォルダ階層を持つZIPファイルとして出力できます。MSDeployを利用すると,このZIPファイルをリモートのIISサーバにデプロイできます図2)。

図2 MSDeployのコマンド例

msdeploy.exe -verb:sync -source:package=C:\WebApp.zip -dest:auto,computerName="http://
webserver/MSDeployAgentService",userName="username",password="password",includeAcls="False"

Jenkinsとの連携

弊社ではCIツールとしてJenkinsを使っています。Windows Server上にJenkinsを構築し,Jenkinsのプラグイン注1を利用してMSBuildをビルドジョブとして選択しています。また,Jenkinsの「Windowsバッチコマンドの実行」でMSDeployを利用すると,ビルドした成果物を開発サーバにデプロイできます。

注1)
MSBuild Plugin

本番環境へのデプロイ

MSBuildをツールとして組み込む

弊社のWebサーバは,Amazon ELBの下に100台規模のサーバを並べたものです。アプリケーションを更新する際には,サーバをグループに分け,グループごとにELBから外し,アプリケーションを更新してELBに戻しています。また,機能追加のためのデプロイの頻度が高いので,各アプリケーションエンジニアが直接デプロイするという特徴があります。そこで,一連の手順のデプロイを手軽にできるように,デプロイツールを作成/利用しています。このデプロイツールはデプロイ用サーバから実行しています。デプロイ用サーバは,デプロイ以外にも本番Webサーバ群への操作を行う操作元になっています。先ほどの開発環境と併せてサーバの役割を図にすると図3のようになります。

図3 PwoerShellの例開発環境とデプロイの流れ

図3 開発環境とデプロイの流れ

デプロイツールの開発には,WPFというWindowsデスクトップ向けのフレームワークとC#を使っています。MSDeployはコマンドとして実行するだけでなく,.NET Framework上でAPIとしてプログラムから実行することも容易です図4)。

図4 プログラムからMSDeployコマンドを実行する例

var sourceBaseOptions = new DeploymentBaseOptions();
var destBaseOptions = new DeploymentBaseOptions()
{
    ComputerName = "http://webserver/MSDeployAgentService",
    UserName = "username",
    Password = "password",
    IncludeAcls = false
};
var deploymentObject = DeploymentManager.CreateObject(
    DeploymentWellKnownProvider.Package,
    @"C:\tmp\Package\MvcApplication4.zip",
    sourceBaseOptions);
deploymentObject.SyncParameters
                .Single(p => p.Name == "IIS Web Application Name")
                .Value = "Deploy";
var syncOptions = new DeploymentSyncOptions();
var changes = deploymentObject.SyncTo(
    DeploymentWellKnownProvider.Auto,
    "",
    destBaseOptions,
    syncOptions);

MSBuildをPowerShellコマンドとして組み込む

ユーザが活発にプレイする時間帯と深夜帯でアクセス数が大きく異なるのも,ソーシャルゲームの特徴の1つです。弊社では容易にサーバの台数を増減できるパブリッククラウドの利点を生かし,サーバの台数をスケジュールに沿って増減させています。日中にサーバを新たに追加する場合は,その時点で動いているアプリケーションをデプロイさせる必要があります。スケジュールの処理はPowerShellで記述していますが,アプリケーションバイナリをデプロイする処理はPowerShellのコマンドレットとして分離しています。このコマンドレットはツールとして組み込んであるC#のバイナリと同一で,コードを共通化できるというメリットもあります注2)。また,ビルドの際にGitのコミットハッシュをdllのメタ情報に埋め込むとお話しましたが,サーバの台数を増やすときにもこの情報を利用します。すでに動いているWebサーバ上のアプリケーションのdllから現在デプロイされているバージョンに対応するコミットハッシュを取得し,それに対応するMSBuildで生成されたZIPファイルを取得して追加するサーバにデプロイします。これにより,サーバの台数を減らしている時間帯の新しいバージョンのアプリケーションのデプロイにも対応しています。

注2)
PowerShellのコマンドレットはPowerShellで記述して作成する以外に,C#による記述が可能。

MSDeployによる静的コンテンツのデプロイ

ここまでASP.NETのアプリケーションをMSDeployを使ってデプロイする方法を紹介してきましたが,MSDeployはASP.NETに限られたコマンドではありません。たとえば弊社では,静的コンテンツのホストサーバに対してMSDeployによるデプロイを行っています。Linuxサーバならばrsyncなどで静的ファイルをデプロイできますが,Windows ServerでもMSDeployによって同様のことが実現できます。図5のサンプルでは,ローカルマシンにcloneしたgitリポジトリ管理下のファイルを,.gitフォルダ以下を除いてデプロイするコマンドを実行しています。

図5 MSDeployによって静的コンテンツをデプロイする例

msdeploy.exe -verb:sync -source:dirPath="C:\Repository" -dest:computerName="http://
webserver/MSDeployAgentService",userName="username",password="password",includeAcls="False",
dirPath="C:\www\Image" -skip:objectName='dirPath',absolutePath='\\\.git'

まとめ

Visual Studioはビルドやデプロイの機能を備える強力な統合開発環境ですが,CIツールや本番環境へのデプロイを自動化するためのMSBuild,MSDeployといったコマンドも用意されています。また,C#という言語に視点を移してみると,ASP.NETのアプリケーションを開発するだけでなく,デプロイを容易にするためのツール(WPF)や自動化するためのコマンド(PowerShellコマンドレット)も開発でき,運用の分野でも力を発揮できます。弊社ではC#を中心としたこのような技術を活用して,アプリケーションの開発だけでなく運用の自動化にも取り組んでいます。

提供/株式会社グラニ
http://grani.jp/
グラニでは各種エンジニアを募集しています。
詳細はこちら→http://grani.jp/recruit/

著者プロフィール

田中孝佳(たなかたかよし)

株式会社グラニ インフラエンジニア。Microsoft MVP for Visual C#。

仕事では C# が動くインフラを担当し,趣味では C# で開発できるアプリを開発しています。

Twitter:@tanaka_733
Blog:http://tanaka733.net

コメント

コメントの記入