DockerでcronしたいときはBusyBox crondが便利

Dockerコンテナでプログラムを定期実行したいとき、それぞれの言語で実装されたタスクスケジューラを使うほか、手っ取り早くcronを使ってしまう方法もあります。しかしDockerで使うにはやや面倒な点があります。

  • cronで実行するプログラムにコンテナに設定した環境変数を渡したい
  • ログは標準出力・標準エラー出力に書き出したい
    • 標準出力に出せばdocker logsで扱えるし、ファイルだとローテートが面倒

このようなとき、BusyBoxに含まれるcrondを使うと、以上の課題を解決してシンプルに定期実行することができます。

インストール

Debian系ではapt-get install busybox-staticでインストールし、busybox crondで起動します。
Alpine LinuxであればそのままBusyBoxなのでcrondで起動できます。

オプション

-dオプションは比較的最近追加されたようで、Debian jessie(BusyBox v1.22.1)には含まれていませんでした。stretchでもv1.22.1のままのようです。

Alpine Linux 3.6 / BusyBox v1.26.2

1
2
3
4
5
6
7
8
9
10
11
12
# crond --help
BusyBox v1.26.2 (2017-06-11 06:38:32 GMT) multi-call binary.
Usage: crond -fbS -l N -d N -L LOGFILE -c DIR
-f Foreground
-b Background (default)
-S Log to syslog (default)
-l N Set log level. Most verbose:0, default:8
-d N Set log level, log to stderr
-L FILE Log to FILE
-c DIR Cron dir. Default:/var/spool/cron/crontabs

Debian jessie / BusyBox v1.22.1

1
2
3
4
5
6
7
8
9
10
11
# busybox crond --help
BusyBox v1.22.1 (Debian 1:1.22.0-9+deb8u1) multi-call binary.
Usage: crond -fbS -l N -L LOGFILE -c DIR
-f Foreground
-b Background (default)
-S Log to syslog (default)
-l Set log level. 0 is the most verbose, default 8
-L Log to file
-c Working dir

ログレベル

ログレベルが0から8まであってよくわからなかったのでソースを読んだところ、

1
2
3
4
/* Log levels:
* 0 is the most verbose, default 8.
* For some reason, in fact only 5, 7 and 8 are used.
*/

とのことでした。For some reasonとは一体……という感じですが、デフォルトの8でもコマンドの実行ログは出るので特に問題なさそうです。

というわけで、Dockerで使う場合は以下のコマンドにすればよいでしょう。新しく追加された-dオプションが標準エラーに出力しているので、Debianの場合でもこれに統一しています。

1
2
3
4
5
6
7
# Alpine
# crond -f -d 8
CMD ["crond" "-f", "-d", "8"]
# Debian
# busybox crond -f -L /dev/stderr
CMD ["busybox", "crond", "-f", "-L", "/dev/stderr"]

実行する

/var/spool/cron/crontabs/rootにいつものようにcrontabを書いて実行します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ cat crontab
* * * * * echo '=== environment variables ===' && env
$ docker run --rm -e FOO=BAR -v $(pwd)/crontab:/var/spool/cron/crontabs/root alpine:3.6 crond -f -d 8
crond: crond (busybox 1.26.2) started, log level 8
crond: USER root pid 7 cmd echo '=== environment variables ===' && env
=== environment variables ===
USER=root
no_proxy=*.local, 169.254/16
HOSTNAME=eac1d9f28400
SHLVL=1
HOME=/root
LOGNAME=root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
FOO=BAR
SHELL=/bin/sh
PWD=/root

このように、コンテナに設定した環境変数FOO=BARが実行コマンドからも見えること、ログが標準エラー出力に書き出されていることを確認できました。

タイムゾーン

cronと直接関係はありませんが、タイムゾーンを日本時間にしておかないと意図した時刻に動かなくてハマるので注意しましょう……(1時間無駄にしました😇)。

1
ENV TZ=Asia/Tokyo

参考記事


ブログをHexoで作り直してNetlifyにデプロイした

ようやく重い腰を上げてブログを作り直しました。
以前のブログはとりあえずWordPressでやっていたのですが、普段のエディタでMarkdownを書きたい…Git管理したい……となったので移行しました。

静的サイトジェネレータ

静的サイトジェネレータとしてはHexoを採用しました。
当初はGo言語製のHugoを使おうとしたのですが、投稿ごとにアセット用のディレクトリを切って管理できるPost Asset Folder機能など、ディレクトリ構成の柔軟性や機能の充実度を考えてHexoにしました。

WordPressからの移行にはwordpress-to-hugo-exporterを使用(当初はHugoの予定だったので…)。Markdownで書き出したあとの調整はエディタによる一括置換やGit管理で楽ちん。Hexoへの切り替えはfront-matterやヘルパーを少しいじっただけなので、ジェネレータ間の移行もしやすいのがいいですね。

デザイン・テーマ

TumblrテーマのApolloをHexoに移植したhexo-theme-apolloを、さらにフォークして使っています。
コードブロックの空白行が詰まって行番号とずれる問題を修正したりアーカイブページにページネーションをつけたりはてブボタンをつけたりしました。

デザイン自体がシンプルですし、実装も素朴なのでカスタマイズしやすかったことが決め手です。いろいろ変えたいところはあるので次はテーマを自作したいです。今回はDone is better than perfect精神でいっています…。

サーバー

サーバーは、静的サイトのホスティング先として最近話題のNetlifyを利用しています。

チーム機能を使うには有料ですがパーソナルであれば無料で、独自ドメイン利用・Let's EncryptによるSSLも無料。当然のようにHTTP/2対応で、アセットはCloudFrontのCDNで配信されます。
ビルドコマンドを指定すればあとはNetlifyが全部やってくれるので便利です。GitHub連携もあり、masterにマージしたら自動でデプロイされます。おまけにHeroku Review Appsのような、Pull Requestごとにプレビュー用の環境まで作ってくれます。すごい……。

まとめ

静的サイトジェネレータは様々な言語で実装されて、いまや450以上あるようです。機能やエコシステムも洗練されてきているような感覚があります。静的サイトの自動ビルド・デプロイはCIサービスを使う方法が主流でしたが、Netlifyは意外とありそうでなかったサービスですね。すごい。

ロリポップ!マネージドクラウドにもNetlify的な静的サイトをビルドしてくれるコンテナがあると便利そうな気がしました。よろしくお願いします🙏(勤務先です)


コーディング規約チェックを日常に〜無理なくチーム全員で取り組める仕組みを作ろう

この記事はpepabo Advent Calendar 2016の4日目です。
3日目は@r_takaishiさんの「IIJmioのクーポン残量をAWS LambdaとMackerelでプロットしてみよう」でした。

コードレビューでよくある風景

突然ですが、コードレビューを行っていると、このようなコメントを一度はする・されると思います。

細かいコーディングスタイルに関する指摘

インデントやスペースの抜け漏れといった、細かいコーディングスタイルに関する指摘ですね。
人力でフォーマットの指摘をするのは見逃しが発生しやすく、細かい部分を確認するコストがかかります。小言のようなコメントになってしまいがちで、開発者・レビュアー双方に負担が増えてしまいます。

このような作業は機械に任せましょう。RuboCopPHP-CS-FixerESLintといったコーディング規約チェックツール(Lintツール)が役立ちます。
Lintツールを導入することでコーディング規約の実践にかかるコストを減らし、可読性・保守性の向上に貢献したり、より本質的な部分のレビューに時間を使えたりできることは、多くの方が実感していることでしょう。

既存プロジェクトに導入する際の課題

しかし、既存のプロジェクトにLintツールを導入するには課題があります。たとえば、

  • 尋常じゃない量の違反が見つかってどうしたらいいかわからない😱
    • 一度に自動修正すると差分が多すぎて、きちんと動くのか検証が困難とか……
  • 導入したはいいものの、開発サイクルの一部としてチームに定着できていない😇
    • 忘れる、面倒くさい、よくわからない→結局自分しかやってないとか……

Lintツールを導入すること自体が目的ではありません。Lintツールの助けを得て、継続的に、将来にわたって読みやすいコードを作っていくことが目的です。
せっかく導入しても開発サイクルの一部として定着しなければ意味がありません。

つまり、無理なくチーム全員で取り組めるような仕組みを作り、段階的に導入していくことが必要になるでしょう。

今回Lintツールを導入したチームも、上の課題に当てはまっていました。

  • 既存のコードが大量にあり、一度に自動修正すると差分が多すぎる
  • リポジトリにLintツール自体は入っていたが、活用されなかった悲しい過去が……😇

無理なくチーム全員で取り組めるような仕組み

では、「無理なくチーム全員で取り組めるような仕組み」とはなんでしょうか?
様々あるかと思いますが、今回は以下の3つの対策を行うことで課題に対処しました。

  1. Pull Request内で追加・変更したファイルのみを対象にチェックをかけ、段階的かつ確実に直していく
  2. 言語をまたがってチェック・修正を一発でできるスクリプトを用意しておく
  3. CI中に実行することで目に見えてわかる結果を出し、強制力をもって開発サイクルに載せる

では、ひとつずつ紹介していきます。サンプルリポジトリは以下にあります。

Pull Request内で追加・変更したファイルのみを対象にチェックをかけ、段階的かつ確実に直していく

全ファイルを対象にチェックをかけると大量の違反が見つかり、自動修正しても差分が多すぎて正しく動くかの検証が困難になります。
そこで、新しく追加するコードに対してのみチェックをかけるようにします。

ブランチで追加・変更したファイルはgit diffのオプションを使って取得することができます。

1
git diff --name-only --diff-filter=ACM origin/master...HEAD

対象ファイルを限定することで、新しく追加するコード、および差分が出たファイルは確実にコーディング規約が守られた状態になります。
少しずつではありますが、普段行う開発のついでに、無理なく自動的にコードがきれいになっていく世界を作ることができます。

言語をまたがってチェック・修正を一発でできるスクリプトを用意しておく

言語ごとにLintツールは異なるため、(共通点は多いものの)各ツールやコマンド体系を覚える必要があります。
たとえばフロントエンドのコーディングであれば、PHPテンプレート・CSS・JavaScriptファイルを同時に編集する場合もあるでしょう。このときにLintツールをそれぞれで実行する必要があるのは面倒です。

そこで以下のような一括チェック用のシェルスクリプトを用意しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/bash
function diff-filter-ext() {
git diff --name-only --diff-filter=ACM origin/master...HEAD | grep "\.$1$"
}
lint_langs=()
options=()
for arg in "$@"
do
case "$arg" in
# --で始まっていればオプションとみなし、それ以外はlintする言語指定とみなす
--* ) options+=( "$arg" ) ;;
* ) lint_langs+=( "$arg" ) ;;
esac
done
# 言語指定がなければ全言語に対してlintをかける
if [ ${#lint_langs[@]} = 0 ]; then
lint_langs=(php js)
fi
status=0
for lang in ${lint_langs[@]}
do
diff-filter-ext $lang | xargs -t -n1 -I'FILE' bin/lint-$lang FILE ${options[@]}
if [ $? != 0 ]; then status=1; fi
done
if [ $status != 0 ]; then exit 1; fi

さらに各ツールのインタフェースを合わせるためのラッパースクリプトを用意します。

これでbin/check-coding-ruleを実行すればすべてのLintツールでチェックが行われます。自動修正は--fixオプションで行なえます。
スクリプトはもうちょっといけてる感じにできると思いますが、ツールを意識することなく、コマンド一発でチェック・修正を行えるようにできました。

CI中に実行することで目に見えてわかる結果を出し、強制力をもって開発サイクルに載せる

最後に、コーディング規約チェックをCIで実行し、規約違反があった場合はCIを失敗させるようにします。目に見えてわかるようにすることで、規約チェックがあることを意識でき、自然とチェック・修正を行えるようになります。

実際の業務ではDroneを使っていますが、Travis CIでは以下のように設定できます。

1
2
3
4
5
6
7
8
9
10
11
language: php
php:
- '7.0'
before_script:
- nvm install 6.9 && nvm alias default 6.9
- npm install
- composer install
script:
# コーディング規約チェックチェックスクリプトを実行する
- bin/check-coding-rule
- phpunit

規約違反があるとこのようにCIが失敗します。大抵のLintツールではどこがどのエラーなのか出力するようにできるので、設定しておくととても親切になります。

コーディング規約違反があるとCIが失敗する

強制力をもつことになるため、突然導入されて戸惑わないよう、チームメンバーへ事前共有しておくのがよいでしょう。
ペパボではデザイナーがコーディングまで行うため、事前にデザイナーさんも交えて話を聞き、現状Lintツールが活用できていない要因と、このような対策をとろうと思いますということを話しました。
READMEやWikiに、よくあるエラーとその修正方法をまとめておくことも重要でしょう。

ESLintの例

今回はESLintを新規導入したため、そのTipsもいくつか載せておきたいと思います。

  • すべてのルールのON/OFFが可能なため、コードの現状に合わせて設定することができる
  • ESLintのルール一覧
    • "eslint:recommended"ではチェックマークのついたルールが有効になる
    • レンチマークは--fixオプションによる自動修正が行えるもの
  • Stylistic Issues(,の後のスペースやインデントなど)はロジックに関わらない上に自動修正できるものが多いため、多めに入れておく
    • レビューのときに「細かいところですが…」と言うようなやつを大幅に減らせます
  • 既存のコードのエラーを(雑でいいので)集計し、厳しそうなものをwarningに落とす
    • no-undef(宣言されていない変数の使用禁止)が一番多く、Pull Requestのついでに修正するには厳しそうなためwarningに落としました
  • 今後も調整になるかと思いますが、.eslintrcはこのようにしました

まとめ

コーディング規約チェックを「無理なくチーム全員で取り組めるような仕組みを作る」ことを目指しました。
そのために、以下の対策を行いました。

  1. Pull Request内で追加・変更したファイルのみを対象にチェックをかけ、段階的かつ確実に直していく
  2. 言語をまたがってチェック・修正を一発でできるスクリプトを用意しておく
  3. CI中に実行することで目に見えてわかる結果を出し、強制力をもって開発サイクルに載せる

気になる結果ですが、ESLintの追加はマージできていないため、残念ながら結果はこれからとなります…。
しかし、PHP-CS-Fixerは既に導入されており、非常によいサイクルが回っています。日常的にコーディング規約チェックを行うことができ、既に当たり前のようになっています。
JavaScriptのチェックも同じコマンドで同時にできるようにしたため、同様に良い結果となることを期待しています。

みなさんも、無理なく自動的にソースがきれいになっていく世界、作ってみませんか?

おまけ

記事の内容からは外れるため特に書いていませんでしたが、このタスクは新卒研修のOJTで配属されたチームで行ったものです。
PHP-CS-Fixerの最初の導入は同期エンジニアが行い、ESLintの追加・チェックスクリプトの多言語対応を私が行いました。

ペパボの新卒エンジニア研修については、GMOペパボの新卒エンジニア研修の様子 & テキストを公開します - ペパボテックブログを見ていただけると様子がわかりますので、ぜひご覧いただければと思います。


2016年秋アニメ:1話の感想をざっと

7月までに急いで録画体勢を構築したのはよいのだけど、結局マジェプリ再放送しか見ていなかった夏アニメ。
秋はいっぱい見ようということでブルーレイレコーダーとソファを調達しました。ソファに寝っ転がりながらひたすらアニメを見る連休は最高だった。

というわけで、1話がほとんど出揃ったのでざっと感想を書いていこうと思います。
オリジナル作品も多いし、先が気になる1話が多くてレコーダー大活躍で何より。

見たやつ

終末のイゼッタ

  • おもしろそう。戦争の中に現れた魔女、こういう世界設定好きですね。オリジナルは先の展開がわからないのがいいね

WWW.WORKING!!

  • 今回もWORKINGらしい。なんか安心して見ていられる

魔法少女育成計画

  • 明るそうだけど全体的に不穏な…と思ったら、生き残りをかけて戦うダークファンタジーらしい(原作宣伝のCMで今後の展開を言われるとは…)

機動戦士ガンダム 鉄血のオルフェンズ(2期)

  • 初めてのガンダムがオルフェンズなんだけどなかなか楽しい
  • ビーム兵器がないから戦闘が泥臭くて、鈍器がぶつかりあう効果音がいい感じ

SHOW BY ROCK!!#

  • 2期のキーマンとなりそうなあいつら(名前がよくわからない)、設定がめちゃくちゃすぎて笑った
  • 敵、お前かよって感じになった

刀剣乱舞-花丸-

  • んー、見てはみるけど原作やってないとやっぱりわからんかなー
  • 名前が、覚え、られない……
  • 審神者が描写されないのはちょっと気になる

アイドルメモリーズ

  • CM明けたらいきなり声優が出てきて録画間違ったかと思った。30分枠で半分声優番組をやるのは斬新
  • アイドルアニメ、個人的にはあんまりハマらないかも…

ステラのまほう

  • 割と本気でゲームつくる話っぽい?
  • 硬派なおじさん絵が好きなのうけるな

学園ハンサム

  • 独特な顔とゆるい絵がツボにはまった

装神少女まとい

  • PVからゆるふわ系アニメかと思ってたら、こんな作風なのかよ!って感じ

ユーリ!!! on ICE

  • フィギュア描写すごい(大変そう)
  • 先のドラマや展開の想像が膨らむ1話があると期待が高まるね

フリップフラッパーズ

  • 1話だけでは全然よくわからんかったけど、背景・美術が最高だった。さすがスタジオPablo
  • おばあちゃんが久保田民絵さん

競女!!!!!!!!

  • とても熱くアホらしくて全然エロくなくて笑った。主線が太い。最高。

Lostorage incited WIXOSS

  • 俺待望のWIXOSSアニメ新作。相変わらず不穏。確かに男が入ると雰囲気がまた変わって締まる感じ。
  • 前作のるう子とは違う、バトルは嫌なタイプを主人公にすえて、じゃあどうやって引きずり込むかを考えたときに、記憶を失うこととタイムリミットを設定するのはなるほど感
  • バトルフィールドや白窓の部屋が明らかに繭の世界の成れの果てだけど、つながりは描かれるのかなー。ピルルク(改め清衣)もどうなるか…

クラシカロイド

  • OPが布袋寅泰。

3月のライオン

  • 演出がシャフトっぽいと思ったらシャフトだった
  • 前半の落ち着いた雰囲気も浸れる
  • 茅野愛衣さん、花澤香菜さん、久野美咲さんの3姉妹……なるほど
  • OPもEDもバンプなんて贅沢

うどんの国の金色毛鞠

  • 原作ものだったのね。最後のおまけアニメは一体なんだったんだ…

月曜日のたわわ

→炎上する以前にYouTubeガイドライン違反で消されてて笑った

まだ見てないやつ

  • 12歳。~ちっちゃなムネのトキメキ~ セカンドシーズン
    • 先輩が最高のアニメだと言うので一度見てみようと思う
  • 響け!ユーフォニアム2
    • まだ1期を見ていないんです……
  • 私がモテてどうすんだ
  • ガーリッシュ ナンバー
  • DRIFTERS(ドリフターズ)
  • Occultic;Nine-オカルティック・ナイン-
  • 舟を編む(10/13木から)

再放送その他

銀河機攻隊マジェスティックプリンス(新作25話)

  • 本編は再放送だけど、今度の映画に続く新作25話が放送された
  • メカアクションはもとより特に音響がめちゃくちゃパワーアップしていたし、映画予告も予想以上だったし期待。

進撃の巨人(オリジナルマスター版)

  • 「オリジナルマスター」が何を意味するのかどこにも書かれていないのだけど、提供クレジットの字幕が入っていなかったくらいしか違いがわからない

涼宮ハルヒの憂鬱


研修で1週間でWebサービスをつくった話

  • 「1週間でWebサービスをつくる」研修
    • 「お産ウィーク」と呼んでいる
    • 新卒エンジニア5人+デザイナー1人で2チーム
  • 課題は旅行と料理の2つでどちらかを選ぶ
    • 料理にした
  • 料理は工夫の繰り返し
    • 今日は〇〇を多く入れてみよう、強火にしよう、スパイスを変えよう、…
    • でも結局どれがどのくらい美味しかったのか、自分の料理がどのくらい成長したのかがわからない!
    • →料理の記録をふりかえって、自分の工夫を実感できるサービスを作ろう となった
  • つかれた
    • 何も出てこない
    • 箇条書きで書く
  • まず動くものを作れたことが第一
  • エンジニアの発想の限界
    • かなり素直、というか課題をそのまま作ったような感じ
    • もう一工夫できた
    • 自分たちでは限界がある、他人の視点大事
  • 使ってみると楽しい
    • 使ってみる/使ってもらうと改善点がいろいろ出てくる
    • 最終的に自分が使いたくなるものを作れた
    • 他人のレシピを見ると(ふざけてるのもあるけど真面目に書いてるのもあって)おもしろい
  • やっぱりレシピ公開(共有要素)を入れてよかった
    • そうするとユーザーネームいれたほうがよかった
    • 最初は全部非公開で日記みたいになる想定だった
  • 月額課金で収益を得る想定なので、WebPayを使って支払情報の登録をできるようにしておいた
    • 「こうなる予定でした」と夢物語にならないようにはできた
  • 新卒デザイナーがひとりなので、こっちのチームにはデザイナーがいなかった
    • その割にはがんばった
    • フレームワークを使ってそれなりに仕上げているだけ
    • できることから考えてしまう癖
    • ユーザーにこういう経験をしてもらいたい→じゃあ具体的にこんなデザインにしよう→実装 という形ではなかった
  • 自分の存在意義とは
  • テスト書いたり本番環境で一連の操作をしてみるなど、検証まで含めて機能の完成
    • テスト書かなかったなー
    • 発表1時間前に本番環境で一部の操作にエラーが出ることが発覚
    • 突如ISUCONが開催された
    • 落ち着いてログを見てエラーを潰せたのはちょっと経験値が上がった?
  • 作りたい機能が5個あるけど時間が足りないとなったとき、検証を省いて5個作るんじゃなくて、3個に減らしてそこまでは確実に機能するものをつくる
    • 動かなければないものと同じ
    • 優先順位や「やらないことリスト」
    • 自分たちのやりたいことに最低限必要なものは何なのか(MVP)
    • 自信を持って減らせる
  • 公開したい
    • 使いたいし改善したい
    • 会社のプライベートクラウドにデプロイしているのでアドレスさえわかれば見れる状態
    • ログイン制なのにSSLじゃない
    • テストも書いてないし手動の検証も不足しているので、プライベートなものが本当にプライベートになっているかよくわからない

ヒップホップユニットのミュージックビデオに出演した

「明日は秘密の撮影会があるそうです」
そう研修スーパーバイザーのじょーさんが言う。

会社で、撮影。耳慣れない響きだが、ここペパボにあたってはさほど驚くことではない。
採用やイベントのための社員写真はもとより、サービスのバナー画像といった宣材写真もほとんどを内製でまかなっている。
「ペパボに入社したらフリー素材になる」と言われるほどだ。

新卒1年目の我々も、既に全員1回は、人によっては数度の撮影を経験している。
例えば新卒エンジニアは学生アルバイト・インターンの募集に出たりしている。

やれやれ、いつものあれか。と、脳内の村上春樹が声をあげる。

だが、どうやら今回は様子が違うようだ。
担当者からは「伝説を作ろう」などとわけのわからない言葉が飛び出している。

どんな撮影なのだろうか?
よくわからないまま当日を迎えると、そこにはラッパーがいた――。

……

ここから先は説明するより動画を見てもらったほうが早いのと、一人称小説みたいな文体に飽きてきたので以下の動画をどうぞ。

ミュージックビデオに出演しました。仕事で。
もはやわけがわからない。
ビデオでの撮影で、しかもMVと聞いたときには驚きました。

企画背景と、ここに至るまでの流れは以下のテックブログの記事で。テックってなんだっけ。

プレスリリースも出ているのだけど、タイトルの情報量とつっこみどころの多さに圧倒されるのと、PRの真面目な文体に強烈な画像が流れてくるのがとてもじわじわくるのでオススメ。

【PR】スタッフ積極採用中!

GMOペパボでは、新しい仲間を熱烈に求めています。詳細につきましては、以下をご覧ください。


ペパボ社内ISUCONで撃沈しました

ISUCONとは「いい感じに スピードアップ コンテスト」(Iikanjini Speed Up CONtest)の略だそうで、課題として与えられたWebアプリケーションを制限時間内でチューニングし、ベンチマークツールによる得点を競う大会です。

本物の方は年1回開催され、賞金はなんと100万円。今年は9/17〜18に予選が行われますが、技術力やモチベーション向上の良い機会であることから、社内で開催される事例も増えているようです。
社内ISUCONにはpixivカヤックなどの事例があります。

その流れに乗ってペパボでも開催することになり、今日がその本番。
参加者は全員ではなく立候補ですが、新卒エンジニアはWebアプリ・Webオペレーション研修と学んできたタイミングなので時期的にもちょうどよく、研修の一環のような形で参加しました。

事前知識なしで突っ込むと何もできずに終わりかねないことから、事前に先輩からISUCONとは何かや、基本的な進め方のレクチャーは受けていました。

が、結果は……見事に撃沈。。。

実力を考えればハイスコアは難しいと思ってはいたが、最後までエラーが直せず完全にお手上げ状態になってしまった。
途中からベンチマークが失敗し続けたので、「ここの設定は知ってるぞ!」とできる範囲でチューニングしてもそれが正しいかどうかまったくわからず、闇の中をひたすら歩き続けるつらさだった。

速度が出なかったりエラーが出る原因は複雑に絡み合っていて、そのチューニング自体は正解だったけど実は主要因は別のところにあったとか、原因の見当がつかないと迷走して時間をロスすることになってしまう。

近視眼的になりすぎた

エラー対処をするうちに近視眼的になりすぎたのも反省点。
先輩によるレクチャーや参考記事は少し読んでいたので、MySQLのslow_query_logなど、まずきちんとログを読んで原因のあてをつけたりなど、開始当初はよい心構えでできたと思う。
しかしアプリに500エラーが頻発する問題が発覚。おそらくチューニングポイントとして用意されていたものだが、その原因が一向に特定できず、ベンチマークが全然通らなくなった焦りもあり、その対処で頭が一杯になってしまった。

今回の参考実装にはRubyとPHPが用意されていたので、Rubyでエラーが出続けるならPHPで試してみたらどうだろうとか、アプリケーションサーバはPumaだったがUnicornに変えてみるとか、試してみることはいろいろあった。
Unicornは研修でも使っていて比較的慣れているのもあり試したのだが、その作業タイミングでベンチマークツールがちょっと不安定になっており確認が有耶無耶になってしまった。
Unicorn化がうまくいっていなかったのか、変更はできたけどエラーは出たままだったのか、それとも単にベンチが不安定で失敗していただけだったのか……それもわからない。

アプリケーションに課題はいっぱいあったのに

ミドルウェアの対処に時間をかけすぎた結果、コードやデータベース構成をきちんと読み込んでアプリケーションを把握することができなかった。
「オペレーション(System Engineering)で点を守り、 プログラミング(Software Engineering)で点をとる」のとおりで、もっと早くアプリケーションコードの課題解決に入るべきだった。

リクエストのボトルネックを見るのにブラウザの開発者ツール使えばわかりやすいじゃんと気付いたのはだいぶ後になってからだし、画像を毎回DBから取り出していることがわかって、ここを静的に、あるいはキャッシュにできればよさそうだとわかってももう時間はなかった。
SQLのチューニングも、データベースの行数を確認して効果がよく出そうなポイントだけに絞るとか、SELECT *を必要なカラムだけ指定する基本のリファクタだけはやるとか、慣れていなくてももっとやりようがあったなと。

「原因の切り分け」や「優先順位」って本当に大事だなと痛感する一日だった。
うう……次はリベンジするぞ。

参加したチームの皆様、そして環境構築・運営のtnmtさんとpyamaさん、おつかれさまでした。


3回目のシン・ゴジラはIMAXで

また金土日と日記を書かない週末になってしまった…
用事がないときは安定して書く時間はとれるけどネタがなくなり、出かけたときはネタはあるけど日記書く気力がなくなるという。

台風も近く、天候・気圧も不安定で体調もよくはないけど、がんばっていこう。

さて

土曜日に3回目のシン・ゴジラを見に行った。IMAXで。
だいぶ覚えてきて細かいところを見れるようになってきた。
ラストの人型のあれにようやく気付けた。

3回目のシン・ゴジラはIMAXでした

Hiroshi Shimojuさん(@shimoju_)がシェアした投稿 -

前から3列目で見たのだけど、これだけスクリーンが大きくてしかも近いとは思わなかった。おかげで首がちょっと痛い。
前列では視界に収まりきらないほどで、おっさんたちのシワがよく見えた。とてもよく見えた。

IMAXシアターではブランドを強調していきたいようで、上映前にIMAXの魅力を示すデモ映像が流れていた。飛行機の轟音や針の落ちる繊細な音まで明瞭なのがわかるデモとなっている。
予告編も音がよかったのでIMAX用に調整されていそうな感じで、「この音で聞けるから次もIMAXでよろしくね!」と訴えているようだった。

立川シネマシティの極上爆音上映にも行ったが、音のインパクトはやはり立川にかなわないが、明瞭さや映像と合わせた没入感はIMAXが上を行くかなと思った。
スクリーンのでかさは違うな〜と思ったので、シネマシティには6000万のスピーカーの上に、うん千万(億?)の最新映像システムの導入にも期待したいところです。
がんばってシネマシティに貢ぎましょう。

最後に上映中の勘違い。


内定者が来た

新卒7期生となる内定者が職場見学に来た。

既に一部の人はアルバイトに来ていたりこの前のバーベキューなどで会っていたが、全員と会うのはこれが初めてだ。
これからももう少し増える予定だそうだ。

配属まもなくだし特にエンジニアはまだ研修中なのにもう次か〜〜〜、みんなこんな気分で新人じゃなくなっていったのだろうな。

ということなので、まだまだ募集中だそうです。


Webオペレーション(インフラ)研修が佳境に入りました

数日書かないだけでなかなか筆が進まなくなるね…

さて、Webオペレーション(インフラ)研修も佳境に入った。
研修の概要についてはWebオペレーション研修、そして夏季休暇に書いたとおりで、いまはApp・DBの冗長構成ができて基本的な構成の完成に近づいた。

これからは監視機構の導入や、本番環境への適用(インスタンス作成、Puppet適用、アプリのデプロイまでの一連の流れ)にまだ手作業が残っているところがあるので、自動化を進めたりなど本番で運営できるような完成度を高めていく作業となる。

また、今回は本番環境ではDockerを使わないので、docker-composeが勝手にやってくれていたネットワークやDNSなどの部分もきちんと考慮して作っていく必要がある。
例えば、実運用を想定してグローバルIPを持つインスタンスはリバースプロキシとSSH踏み台サーバのみとするのだが、試しにローカルネットワークしかないインスタンスを作ったらもちろんインターネットに出られずapt-getも何もできなかった(そりゃそうだ)。つまりNATしてあげる必要があり、そのための設定を組んだりしている。
あとはLAN内の名前解決の仕組みもないので、ここもDNSサーバーを立てたりして便利にしていく必要がある。いまは/etc/hostsを職人の手によりひたすら編集している。

あたたかみのある手作業はもういやだ。

さらに余力があればオートスケール対応やCDN、リバースプロキシ冗長化など、挑戦できる課題は山ほどある。
あと数日しかないが、ようやく基本構成ができてやりたい課題も出てきて楽しくなってきたのでいろいろ試していきたい。