Gazelle という新しいPlack::Handler(Server)をリリースしました

https://metacpan.org/release/Gazelle

前のISUCONの結果報告で「Chobi」として紹介していたものを名前を変更しました。

GazelleはnginxやApacheでreverse proxyを行うことを前提に書かれたPlack::Handlerです。nginxの後ろにunix domain socketを利用して配置した場合、”Hello World”のベンチマークで、Starmanの3倍、Starletの1.7倍程度高速に動作します。

gazelle_bench.png

一番左はnginxで静的ファイルを配信した場合のQPSです

ベンチマークの詳細はこちら↓です

https://github.com/kazeburo/Gazelle/wiki/Benchmark

特徴など

Gazelleは以下のような特徴をもっています

  • HTTP/1.0のみをサポート。ただしKeepAliveはサポートしない。これにより実装がシンプルに
  • io処理をすべてXSで記述。Perlのファイルハンドルは使わない
  • Linuxではaccept4(2)を使う。accept4(2)がサポートされていないプラットフォームではaccept(2)を使います
  • kazuhoさんのpicohttpparserを使って高速にリクエストのパースを行う
  • acceptから最初のpacketを読み込み、ヘッダーをパースするまで1つのXSで書かれた関数内で処理する。Perlの処理が入らず、またZero Copyで動作する
  • レスポンスの書き出しはwritev(2)を使う
  • Starletを使っているところはそのままの設定で入れ替え可能

その他、Starletと同じく

  • Parallel::Prefork によるPreforkアーキテクチャ
  • Server::Starterを使ってのhot deploy

一言でまとめると、kazuhoさんのソフトウェアで出来ているサーバです。既に某サービスの1台のサーバで使い始めたのでぜひ使ってみてください。

去年に引き続き、ISUCONにLINEの選抜チーム「チーム生ハム原木」で出場して優勝することが出来ました!!!!

@tagomoris、@sugyan お疲れ様でした!!

#isucon 2014で優勝しました - すぎゃーんメモ

最後の最後、残り15分でnginxの設定を行う場所を間違えていたということに気付き、ローカルのベンチマークでしか検証ができず、どの程度のスコアになるのか、またfailするのか分からない状況でしたが、結果的に良いスコアになってほっとしました。

自分でも何度も言いながら「nginxのrewriteはinternal redirect」の大原則を忘れていました。はい。1日100回唱えるようにします。

予選アプリケーションの復習

劇的なスコアは出ていませんが、地道に復習をしていて、

$ ~/benchmarker bench --workload 8
07:26:29 type:info      message:launch benchmarker
07:26:29 type:warning   message:Result not sent to server because API key is not set
07:26:29 type:info      message:init environment
07:26:44 type:info      message:run benchmark workload: 8
07:27:44 type:info      message:finish benchmark workload: 8
07:27:49 type:info      message:check banned ips and locked users report
07:27:52 type:report    count:banned ips        value:1048
07:27:52 type:report    count:locked users      value:5478
07:27:53 type:info      message:Result not sent to server because API key is not set
07:27:53 type:score     success:291580  fail:0  score:62985

これくらいの数字が出るようになってました。nginx、perl、redisの構成で、CSSの出力も変えず、GOGCもデフォルトのままです。CSSと画像を消すと、23万ぐらいだったかな。

具体的に、どんなことをやったのかは別のエントリに書こうと思いますが、新しく2つのモジュールを作りました。

  • Redis::Jet - 高速に動作し、Redisサーバからの返事を待たない「noreplyモード」を備えるRedisクライアント
  • Plack::Handler::Chobi - nginxのupstreamのサーバとして動作するという前提で書いたアプリケーションサーバ。HTTP/1.0のみサポート、KeepAliveもサポートしませんが、クライアントのコネクションとヘッダーのパースがすべてC言語で書かれている。環境にもよるがStarletの1.5倍から2倍ぐらい性能がでる

両方とも銀の弾丸ではないですが、高RPS勝負になった時に少しでも上に行く為の武器になるんじゃないかと考えてました。

復習したrepositoryはこちら

https://github.com/kazeburo/isucon4-elimination-myhack

準備

ISUCONは準備も大切です。

去年の本選や今年の予選と同じようにgithubのprivate repositoryを用意し、そこに最初に行うべきsshの鍵の配置やgitの設定、使いそうなソフトウェアのインストール方法をまとめました。

ソフトウェアはOpenRestyやmemcached、MySQL、cpanfileに追加するモジュールのリストなど、ほとんど去年と同じ内容ですが、今年はRedisが新しく加わっていました。

本選のアーキテクチャ

動画ファイルを配信するサービスということで、とりあえず動画ファイルを全てのサーバに配るという去年と同じようなアーキテクチャをとりました。これがその時に書いたメモ。

IMG_2748.jpg

この図では1番でアップロードを受けて、2,3に配っていましたが、実際には1番のサーバにも動画ファイルを配りました。

nginxの設定をtagomoris、動画の配布とログをRedisに書きだすアプリケーションの改修をsugyan、サーバの足回りの設定を自分が担当して作業を行い、上の構成となったのが14時ぐらい。そこで1Gbpsの壁にあたってしまい、何をしてもスコアがあがらない時間がはじまりました。

スコアが上がらない中で、tagomorisが広告取得時のredirectをなくしたり、nginxから直接動画を返したり、sugyanが動画の中で一番サイズの小さいものを返すように改修を行っていましたが、どれも1Gbpsに壁にあたっている中では効果がでずに悩んでいました。

動画を返さない方法を探る

1Gbpsの壁を突き破る為には動画ファイルを返さない方法があるはずだ、ということであれこれ開始したのが17時過ぎ。gitのcommitをみると、どうやら「チームフリー素材」さんが33万点を出す前からやっていたようですが、33万点がでたことで、必ずその方法あるだろうということでいろいろ試しました。

例えばこんなのとかやってました。

location ~ /asset$ {
  # /slots/{slot:[^/]+}/ads/{id:[0-9]+}/asset
  #rewrite ^/slots/(.*)/ads/([0-9]+)/asset$ /data/$1-$2.mp4;
  return 206;
}

他にもetagをonにしてみたりしましたが、どれも効果がなく、straceしてもIf-None-MatchやIf-Modified-Sinceを送って来ている形跡がみつからないので、もう半分諦めムードでしたが、最後に一つnginxの設定を自分が間違えていた事に気付きました。

 location ~ /asset$ {
   # /slots/{slot:[^/]+}/ads/{id:[0-9]+}/asset
   rewrite ^/slots/(.*)/ads/([0-9]+)/asset$ /data/$1-$2.mp4;
+  expires 24h;
 }

 location /me {

これ、17:44のcommitです。はい、すみません、死にます。大変申し訳ございません。

「nginxのrewriteはinternal redirect」「nginxのrewriteはinternal redirect」「nginxのrewriteはinternal redirect」「nginxのrewriteはinternal redirect」もう皆さん分かりますよね。正解はこう書かなければなりません。

location /data {
  root /data;
  client_body_temp_path /data/client_temp;
  dav_methods PUT DELETE MKCOL COPY MOVE;
  create_full_put_path  on;
  dav_access            all:rw;
  expires 24h;
}

location ~ /asset$ {
  # /slots/{slot:[^/]+}/ads/{id:[0-9]+}/asset
  rewrite ^/slots/(.*)/ads/([0-9]+)/asset$ /data/$1-$2.mp4;
}

このcommitが18:43。いやぁ、厳しかった。。。

あれこれ

最終的に何が起きたか、確認はしてないのですが、たぶんこういう事でしょう

  • expiers 24hがついたことで、レスポンスにCache-Contol: max-age=86400、Expiresヘッダが付くようになった
  • ベンチマークツールがそれをみて、初めてIf-Modified-Sinceを送るようになった

長年画像配信野郎をやってますが、正直「おや。。」という感想をもちます。通常であれば

  • Last-ModifiedヘッダがあればブラウザやCDN、Proxyサーバはコンテンツをとりあえずキャッシュする
  • ソフトウェアによって異なるが、ブラウザやCDNは任意のタイミングでサーバにIf-Modified-Since付きでリクエストを送る。サーバはコンテンツが更新されてなければ304を返す事ができる
  • サーバ側がCache-ControlやExpiresヘッダを返した場合は、そのヘッダで定められた期限までブラウザ、CDN、Proxyはキャッシュを行い、サーバには一切アクセスしない。 — ただし、CDNやProxyの設定で最大の有効期限が決まっていることもあるので、その場合はCache-Controlヘッダで決めた期限より速くアクセスがくることがある — 期限がすぎてアクセスした場合にIf-Modified-Sinceヘッダが付く(と思う)

もし、ベンチマークツールがLast-Modifiedを検出するような仕組みになっていれば、うちのチームでは14:26の時点で304が返せるようになって、もっとアプリケーションのチューニングに集中できていたのかなと思う。その上でCache-Controlを指定することでアクセスすら来なくなってさらに高得点がでるとかあったかもしれない。

んで、どうしたらこのあたりの動作が分かりやすくなるか、一つの案としてはベンチマークがLast-Modifiedをみて、If-Modified-Sinceを送り、さらに「Cache-Control: max-age=0」を送っていれば分かりやすいかなと思いました。これはブラウザが「リロード」を繰り返している状態、またはCDNでcacheの有効性を毎回確認する機能を使っている状態と同じです。

これだと、動画をファイルに落としてnginxから配信したチームから点数をかなり上げて、高RPS勝負になりやすかったのかなと思います。 ただ、簡単にそうはさせない罠を用意する必要があったかもしれませんね。そのネタはあります。

最後に

問題出題のクックパッドの@mirakuiさん、@rosylillyさん、@sora_hくん、大変おつかれさまでした。ぎりぎりでした!!wishlist公開お願いします!

テコラスの皆様、941さん、やぶたさんをはじめ運営スタッフのみなさまありがとうございました!あと、途中で応援に来てくれた奥さんと、息子と娘にも感謝!

最後に 2

今回、選抜チームをのぞき、弊社から本選に残ったチームがいなかった。これはどうにかしたい

最後に 3

頂いたドローン、家の中で動かしたら音が大きかったのか娘が号泣しました。次は外でやりたい

IMG_2745.jpg

今年もこの季節がやってきました。

今年のISUCON4は出題がクックパッドになりました。自分たちは去年に引き続き @sugyan @tagomoris とLINE選抜チームを組んで参加しました。

共催枠なので予選免除で本選には出れるのですが、場数も重要だと去年参加して分かったので予選も参加しました。参加は1日目の土曜日です。

結果は「51192」ランキングには入りませんが、10位相当のスコアになります。言語はPerlです。ちなみに、2日目のベンチマークツールでも実行しましたが同等のスコアがでました。

準備

とりあえず、会社のchatに専用のchannelをつくり、@sugyan @tagomorisと簡単に確認し、去年の自分たちが用意したwikiを読み直しておこうと話をしました。

去年の本選前と同じく、使うであろうソフトウェアについては、コピペでインストールができるように準備しておきました。とは言っても去年とほぼ同じでいくつかバージョンがあがっているぐらいです。

準備したソフトウェアは

  1. memcached
  2. openresty
  3. mysql
  4. 使うであろうperl moduleを書いたcpanfile

なかんじ。

開始〜

去年の経験から、コードに手を付けるよりもまず、どんなサイトか確認し、冷静にプロファイルを取ろうということで、アクセスログの解析と、pt-query-digestをつかってMySQLのプロファイルをとりました。

そこで、今回のアプリケーションがログインの機能しかなく、アクセスするURLもクエリの種類も非常にすくなく、データ量もそれほど多くないことがわかりました。

この時点ですべてのデータを1つのプロセスの中でもつ、ISUCON用語でインメモリDBアプリにしたらよいスコアでるよね〜と分かりましたが、その本選に向け、スケールするような構成で行きたいということで現状のアプリケーションを改善していく方向でやりました。開催枠なので予選を通過出来るスコアをだせばいいやという余裕もありました。

ソフトウェアインストール

アプリケーションはmemcachedにデータを移動し、MySQLを使わないアプローチに決まったので、sugyanとtagomorisはアプリケーションの改善を行い、自分はソフトウェアのインストールや入れ替えを行いました.

perlの初期スコアが「1495」、workloadを4にあげて「3186」、ここからnginxをopenrestyに入れ替え、秘伝のタレnginx.confをいれ、StarmanをStarletに入れ替えるなどして「3489」。次にMySQLをこれまたチューン済みのmy.cnfとともに入れ替えてworkload 8で実行「2964」

この次に、使わなくなる予定のMySQLのインデックスの追加を行ってみました。すると、「cannot assign requested address」などのエラーがでたので、あぁ、keepalive効かないんだーと思って、sysctl.confにいくつか足してチューニング、ファイルデスクリプタもlimits.confを弄るなどして増やした。

すると、workload 4で「38417」、workload 8で「40690」とかいう数字がでた。

このあたりで13時。

アプリケーションの変更

ここから主に sugyanとtagomorisのアプリケーション変更。初期化フェーズでmemcachedに入れるところ、アクセス拒否を行うためのカウント、ログなどと段階的に進んでました。自分はその裏で、index.htmlを静的に吐き出したり、Starletを改造したり細かいチューニングをしていましたが、それほど効果なかったように思えます。

途中でreportが合わない問題に当たってなかなかスコアが上がらない時間が続きましたが、memcachedにデータを移しつつ、SQLがなくなっていく毎に45k=>50kとスコアがあがり、最後にプロセス数を弄ったりしつつ、50000〜52000ぐらいのスコアがでるようになりました。

バグに苦しんでた4万中盤で、5万点ぐらいは行きたいなーと思っていたので、その点数がでて一安心。

本選に向けて

事前の話通りに、プロファイルをとり方向性を明確にした上で取りかかり、実装できたところが良かった。それでも上はまだいるので本選に向けて予選の復習と、あれこれ作戦をチームで考えていきたい所存です。

クックパッドの皆様、そして941さんとりあえず予選おつかれさまでしたー。本選もよろしくお願いします!

YAPC::Asia Tokyo 2014 Tokyo の1日目の「Web Framework BenchmarksとPerlの現状報告会」というタイトルでLTと、2日目に「Dockerで遊ぼう」という発表をしてきました。

うしろのばやしさんにラーメンと一緒に飲み込まれてしまった感がありますが、PSGI/Plackのパフォ厨としては、どうしても現状を報告しておきたい内容でありました。unicornに勝ちたい!!

2日目の朝イチというコマでありましたが、大勢の方に見に来て頂いて驚きました。前半の内容を盛り込みすぎて時間が足りなくなってしまい、すみませんでした。アンケートで既にDockerを使っている方が凄く多かったので、インストールの部分とかは飛ばしてもよかったんじゃないかと思いましたが、Dockerを使う上で少しでも役に立てば幸いです。

ベストトーク賞

うずらさんのPHP発表は内容面白かったし、喋りはうまいし、スライドも作り込んであってさすがという感じでした。ベンチマークで自分がLTで紹介したオプションを使って頂いて嬉しかった。時代はPHP

その他のトークではgugodの「One layer down below」とSawyerの「Plack for Fun and Profit (But Mostly Profit)」の二人がよかった。新しいものや多機能なものに飛びつくのではなく、ひとつレイヤーの低い部分から必要最小限で高速に動作するものを作ったり、ビジネスの継続という視点で冷静に見極める。Booking.comという大規模なサービスの中身が垣間みれたようで、とても参考になりました。

そうそう、今回はスピーカー登録だけだったので、ベストトーク賞の投票権がなかったのが残念。

microservice

昔からあるものにそれっぽい名前がついて流行るというやつなんだけど、今回のYAPC::Asiaでもいくつかのトークで出て来た。とくにあんちぽくんさんの発表がよくまとまっていた。

個人的に、この分野にコミットできることとしては、内部APIをコールする高速なHTTPクライアントや、内部APIに実行に特化したAppサーバの開発があるのかなぁと漠然と思った。gugodがトークで紹介していたHijkがまさにそれ。

おそらく、それがないと「microservice化したらアプリケーションが100倍遅くなった!!!microserviceは単なるバズワード!!!!!」とかになってしまうので、microserviceを唱えるみなさまにおかれましては如何に通信のオーバーヘッドを減らすかというあたり、「並列実行で万全〜」とかじゃなくもうちょい具体的な解決案の提案が必要なんじゃないかと思いました。

そういえば。2009年のYAPC::AsiaでLWPからCurlに変更してCPU使用率をグッと下げるというのを紹介していた

isuconの宣伝

2つの資料にも入っていますが、今回のYAPC::Asiaでは会う人、会う人にISUCON予選への出場を進めておいた。楽しいし、勉強になるし、100万円は僕らが頂くので貰えませんが賞金でるし、みんな挑戦するとよいですよ #上から目線

参加はこちらから↓↓↓↓

ISUCON4 オンライン予選の参加登録を開始しました

余談

スライドのレゴはこのセットのバイクを組み替えると作れます。Pete Corpさんという方がyoutubeで公開している動画を見て作ってみました

レゴ ムービー スーパーサイクルチェイス 70808
レゴ (2014-02-07)
売り上げランキング: 1,434

レゴムービーは最高の映画です

LEGO (R) ムービー ブルーレイ&DVDセット(初回限定生産/2枚組/デジタルコピー付)  [Blu-ray]
ワーナー・ブラザース・ホームエンターテイメント (2014-08-02)
売り上げランキング: 460

8月28日から30日まで開かれる YAPC::Asia Tokyo 2014 で Dockerの話をします。

コマは2日目、30日の朝イチの「多目的教室3」です

Dockerで遊んでみよっかー - YAPC::Asia Tokyo 2014

各所で盛り上がりに盛り上がっているDockerを試して、遊んで、どんなものなのか理解していこうという内容です。Hello Worldで終わるのではなく、身近な作業に活用したり、ちょっとしたアプリケーションの実行環境として使ってみようという内容です。

資料できてきていますが、やや基本の部分のボリュームが大きくなっています。Dockerに興味がある、でもまだ手を付けてないような方がいましたら、聞きに来てくれると嬉しいです。

前日HUBで飲み過ぎないでね!

<おまけ>

Dockerとは関係ありませんが、ISUCON4 オンライン予選の参加登録が開始されています!!!Webアプリケーションを書いている方もインフラを扱っているエンジニアも運用エンジニアも、ぜひチャレンジしてください!!私もでます!!

参加はこちらから↓↓↓↓

ISUCON4 オンライン予選の参加登録を開始しました

昨日のエントリで紹介した「Webアプリケーションの パフォーマンス向上のコツ 実践編」ですが、いくつかスライドを追加して、「完全版」として公開しました。

ISUCONだけに限らず、一般的なWebアプリケーション、SQLのチューニングの参考となる資料となっていると思いますので、見て頂けたら嬉しいです。

<追記>

ISUCON4 オンライン予選の参加登録が開始されています!!!Webアプリケーションを書いている方もインフラを扱っているエンジニアも運用エンジニアも、ぜひチャレンジしてください!!私もでます!!

参加はこちらから↓↓↓↓

ISUCON4 オンライン予選の参加登録を開始しました

学生さん限定のイベント「ISUCON 夏期講習」今年もやりました。イベントは、tagomorisからISUCONやWebアプリケーションについての座学を行ったあとに、ISUCON3の予選問題にチャレンジをしてもらいました。またチャレンジをしてもらいながら、どのようにWebアプリケーションのパフォーマンスをあげていったらよいのか、自分の方から説明をしました。今年はスコアをあげることができる参加者が多く、驚きました。

去年と同じようにISUCONの問題にチャレンジする環境としてEC2を使いましたので、そのAMIを公開します。

AMI ID:ami-e796b3e6
AMI Name: isucon_summer_class_2014
Region: Asia Pacific (Tokyo)

「ISUCON 夏期講習 2014」サーバのつくりかた

EC2のインスタンスを起動する際に、上記のAMIを指定して起動してください。HVM対応のインスタンスが必要になります。夏期講習では「c3.xlarge」を使いました。スポットインスタンスを活用するとリーズナブルに試す事ができると思われます。

ベンチマークツールにポート5043が必要になるので、ssh、http、tcpの5043をセキュリティグループの設定をつかってアクセス可能にする必要があります。

サーバが起動したら、「ec2-user」でログインしてください。

$ ssh -i keyfile.pem ec2-....amazonaws.com

ISUCON2の環境は「isu-user」ユーザにて構築してあります。

$ sudo su - isu-user

パスワードが設定されてないので、適宜設定するなりsshの公開鍵を設置すると作業がしやすいですね。

ベンチマークツールはWebUIを用意してあります。ブラウザでサーバのtcp 5043にアクセスします

http://ec2-....amazonaws.com:5043/

benchui.png

こんな画面になります。説明が下の方にありますので、読んでください。

ベンチマークツールですが、去年の予選とは若干異なり、時間は30秒。workloadは「1」に固定されています。よりチャレンジしたい場合はソースコード見て変更してみてください。

「Webアプリケーションの パフォーマンス向上のコツ」の発表資料

夏期講習の座学用に用意した資料となります。Webアプリケーションのパフォーマンスをあげるにはどんなことを考えて、やればいいのかについて簡単に解説しています。資料は2つに分かれていて、一つ目が「概要編」、二つ目が「実践編」となっています。

実践編は途中で力尽きている感じですが、ちゃんと書けば仕事でも役に立ちそうなので、あとで完全版にしたいと思っております。

<追記>
完全版公開しました
「ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版」を公開しました
</追記>

学生のみなさまのISUCON4への参加と活躍を楽しみにしております。

追記(2014/08/22)と謝辞

実践編の資料を作るにあたり、@acidlemon さんの記事を参考にしました
ざっくりと #isucon 2013年予選問題の解き方教えます

サーバ環境の構築にあたっては「オンライン予選で使用した問題が手元で再現できるAMIを公開しました」で紹介されているAMIも参考にしています。

改めて出題の @fujiwaraさん @acidlemonさんをはじめKAYACの皆様に感謝しております。

追記2

ISUCON4 オンライン予選の参加登録が開始されています!!!Webアプリケーションを書いている方もインフラを扱っているエンジニアも運用エンジニアも、ぜひチャレンジしてください!!私もでます!!

参加はこちらから↓↓↓↓

ISUCON4 オンライン予選の参加登録を開始しました

最近、Module::CoreListのWebUIと、perl-buildで使っているperlのリリースとアーカイブのリストの生成をHerokuに移動しました。両方とも、情報を更新するworkerとappサーバが必要になるので、Heroku上でProcletを使ってappサーバとworkerなどを動かしてみました。

HerokuでのProcletの使い方

まず、cpanfileとProcfileを用意します。

$ cat cpanfile
requires 'HTTP::Tiny','0.043';
requires 'Getopt::Long';
requires 'Proclet';
requires 'Plack';
requires 'Starlet';

$ cat Procfile
web: ./server.pl --port $PORT

Procfileに書くのは1つだけです。2つ以上起動する場合は、別途お金がかかります。

server.plはこんな感じで、オプションでportを受け取り、workerとStarletのプロセスを起動します。

#!/usr/bin/env perl

use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/lib";
use Proclet;
use Plack::Loader;
use Getopt::Long;
use HTTP::Tiny;

my $port = 5000;
Getopt::Long::Configure ("no_ignore_case");
GetOptions(
    "p|port=s" => \$port,
);

$proclet->service(
    tag => 'worker',
    code => sub {
        my $worker = MyWorker->new;
        $worker->run
    },
);

my $app = MyWeb->to_psgi;
$proclet->service(
    code => sub {
        my $loader = Plack::Loader->load(
            'Starlet',
            port => $port,
            host => 0,
            max_workers => 5,
        );
        $loader->run($app);
    },
    tag => 'web',
);

$proclet->run;

場合によっては定期的にサービスを叩くworkerも合った方がいいかもしれません

$proclet->service(
    every => '*/30 * * * *',
    tag => 'ping',
    code => sub {
        my $ua = HTTP::Tiny->new;
        $ua->get("http://${yourservicename}.herokuapp.com/");
    }
);

Procletはcron likeなworkerもサポートしています。

server.plは実行権限も付けておきます

$ chmod +x server.pl

準備ができたら、herokuコマンドを使ってアプリケーションを登録します。

$ heroku create yourappname --buildpack https://github.com/kazeburo/heroku-buildpack-perl-procfile.git

拙作のbuildpackを使うと、cpanfileを使って依存モジュールをいれ、環境変数を設定してくれます。

最後にpushしてサービスを起動します。

$ git push heroku master
...
-----> Heroku receiving push
-----> Fetching custom buildpack
-----> Perl/Procfile app detected
-----> Installing dependencies

便利ですね!

タイトルがそのままですが、GrowthForecastのDocker imageを作りました。

https://registry.hub.docker.com/u/kazeburo/growthforecast/

使い方は単純に起動するだけなら次のようになります。

$ docker run -p 5125:5125 kazeburo/growthforecast

これだと、データが永続化されないので、適当なボリュームをマウントします。

$ docker run -p 5125:5125 -v /host/data:/var/lib/growthforecast kazeburo/growthforecast

起動オプションを変更したい場合は、コマンドを渡すか、Dockerfileを書いてビルドすると良いでしょう。

$ docker run -p 5125:5125 -v /host/data:/var/lib/growthforecast kazeburo/growthforecast \
    growthforecast.pl --time-zone UTC --data-dir /var/lib/growthforecast

ヘルプの表示

$ docker run -i kazeburo/growthforecast growthforecast.pl -h

Dockerfileの例

FROM kazeburo/growthforecast CMD growthforecast.pl —time-zone Asia/Tokyo —data-dir /var/lib/growthforecast —front-proxy 0.0.0.0/0 ..

GitHubとDocker Hubを組み合わせてDocker imageの作成を自動化

このDocker imageはGitHubとDocker HubのAutomated Build Repositoryの機能を組み合わせて、GitHub上でタグが作れたのをフックして自動的に作られています。

Automated Build Repositoryを使うには、まずDocker Hub側で、ビルドを開始するためのTrigger URLを有効にします。

gf_gh_trigger.png

そして、このURLをGitHubに入力します。新規のwebhookを追加し、Payloadに先ほどのURLをいれます。Secretは使わないので適当に入れました。今回はタグが作成された際にDocker Imageを作りたいので、Webhookを起動するイベントの「individual events」のラジオボタンを押し、出てきた中から、「Create」だけにチェックボックスをいれました。

gf_hook_gh.png

あと、Dockerfileで最新のタグを指定してソースコードを取得し、インストールを行うようにしています。

RUN git clone -b $(curl -s https://api.github.com/repos/kazeburo/GrowthForecast/tags|jq -r '.[0].name') https://github.com/kazeburo/GrowthForecast.git /tmp/GrowthForecast
RUN cpanm -n --no-man-pages -v --no-interactive /tmp/GrowthForecast

GrowthForecast(や他のCPANモジュール)は、MinillaShipItというツールで、タグの追加とCPANへのリリースを同時に行っていますが、上の例でGrowthForecastのインストールをCPANから行わずにgithubから取得しているのは、DockerのAutomated Buildがgit pushした瞬間から開始されて、CPANのインデックスの更新が追いつかずdocker build中に最新版が取得できない可能性があるからです。

どうぞご利用くださいませ。

最近、Vagrantのprovisionerを使ってパッケージの作成などをいくつか行っているのですが、その際にVMを落とし忘れ、ホストしてるマシンの余計なリソースを使ってしまっていることがあります。

なので、provisionerでサーバをdestroy/haltするやつを書いてみました。

rubygems: https://rubygems.org/gems/vagrant-destroy-provisioner
github: https://github.com/kazeburo/vagrant-destroy-provisioner

勝手にshutdownしてイメージを破棄するデモ動画です。

インストールはvagrant pluginコマンドから行います。

$ vagrant plugin install vagrant-destroy-provisioner

使い方はこんな感じ

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "CentOS-6.4-x86_64-v20131103"
  config.vm.box_url = "http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20131103.box"
  config.vm.provision "shell", inline: "echo 'Hello Provisioner'"
  config.vm.provision "destroy"
end

VMのshutdownだけをするモードも一応サポートしていて

config.vm.provision "destroy", destroy: false

とすると、vagrant halt相当のみ実行されます。destroyオプションのデフォルトはtrueです。

Docker Provisionerを使う場合は、destroy: falserun: "always" を使うと多分便利。先日のPerl-Buildのfatpackの例だと

 config.vm.provision "docker", run: "always" do |d|
    d.build_image "/perl-build/author",
        args: "-t perl-build"
end
config.vm.provision "shell", run: "always",
    inline: "docker run -v /perl-build:/perl-build perl-build"
config.vm.provision "destroy", destroy: false, run: "always"

となります。毎度 vagrant up に —provision オプションを付けなくても良いので楽。

vagrant-destroy-provisionerを使うと、VMの使い捨てが自動化されて非常に便利。どうぞご利用ください。

以下のgems、サイトを参考にしました。

https://rubygems.org/gems/vagrant-reload

vagrantのprovisionerを自作する - Qiita

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

アイテム

  • gazelle_bench.png
  • IMG_2745.jpg
  • IMG_2748.jpg
  • benchui.png
  • gf_hook_gh.png
  • gf_gh_trigger.png
  • corelistweb2.png
  • corelistweb.png
  • gf_complex.png
  • jstat2gf.png

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 4.27-ja