こんちは。開発2部の吉岡です。
ソーシャルゲームのサーバーで、陰ながら頑張ってくれるのがバッチサーバーです。
タスクを指定した時間か定期的に実行するサーバーになります。
バッチタスク管理daemon
処理としては、データベースに接続し、タスク溜め込み用のテーブルをチェックします。
そして、実行時間が過ぎているタスクがあれば、それを実行します。
最初にこの処理を作成した頃は、phpのdaemon用ライブラリを使用していたのですが、最新版では単純に無限ループをしています。
で、そのスクリプトをsupervisorで落ちないようにしています。
かなりざっくりと処理を書くと下のような感じです。
while( true ){
sleep(1);
try{
$MasterDB = getDB('master');
$MasterDB->startTransaction();//トランザクションフラグを立てる
//ジョブの取得(行ロックをかけて排他する)
$newJob = LogicJob::getNewJob( $MasterDB );
//実行するジョブがなければ、continue
if ( !$newJob ){
$MasterDB->close();
continue;
}
//ジョブの実行(execで別phpスクリプトを蹴る)
LogicJob::execJob( $newJob ); //exec( $newJob['php_file'] . ' > /dev/null &' );
//ジョブステータスを実行中に変更
LogicJob::updateJobStatus( $MasterDB , $newJob, LogicDaemon::JOB_STATUS_EXEC );
//コミット
$MasterDB->commit();
}
catch( Exception $e ){
$MasterDB->rollback();//トランザクションフラグが立っていればrollback
}
$MasterDB->close();
}
タスクテーブルと行ロック
上のように実行すべきタスクがあるかチェックをするのですが、冗長化のため、この処理は複数のサーバーで走ることがあります。
同じテーブルのデータの取り合いになるので、ここで行ロックが必須となります。
この実装はなかなか苦労しましたが、現在は問題なく動作しています。
課題!
このバッチの実装は、ミドルウェアを使って、もっと高機能でカッコイイ感じにしたいんですが…
と、個人的には思います。
celerydとかどうなんでしょうか。pythonですが。
バッチサーバーの構築・運用、情報交換したいです!
























ピックアップ
