YAPC::Asia 2015 1日目

Consulと自作OSSを活用した100台規模のWebサービス運用

  • @fujiwara
  • Agenda
  • 最近のロンチサービスは使い方はいろいろだけど全てにConsulが入っている

Lobi

  • Playdog、ゲームのストリーミング配信SDKの開発など
  • '10〜、ap-northeast-1登場以前のAWSで始まった
    • App2, DB2の4台とか
  • '13.11 ~ AWS東京リージョン Maxで100台くらい
  • AppのASG、SDKのASG、画像変換のASG、ストリーミング、バッチサーバ、ログ集約/解析(Norikra)、動画変換ASG
  • モダンになるまえからやってるのでマネージドサービスより役割の違うEC2が多い
    • ホストの種類が多い
  • Perl(アプリ), Node.js(ストリーミング), Go(ストリーミング)
  • ミドルウェアいろいろ

  • AWS移行後の悩み

    • 当時内部DNSがなかった
      • hostsをchefで書いていた
      • 名前が引けないとChefが滑ることがあったので、Chef実行そのものがわかれていた
      • DNSサーバ自前構築は面倒
      • Internal DNSはなかった

Consul

  • 本番運用しているのは会場で3%くらい
  • Agent
    • DNSとHTTPのインターフェースがある
    • consul1バイナリに引数でデーモンになったりCLIになったり
  • Server
    • クラスタ内の特定の奇数台で動いている
      • うち1台がLeader
      • 一人だとLeadarになれない、過半数(→最低でも2/3台)の賛成で選出される
    • Raft

Service / Node Discovery

  • サービス内のnode
    • consul members
      • 順番はランダム
      • Failed(監視失敗), Left(クラスタから除去)
    • @127.0.0.1 -p 8600にDNSポート
      • Leftしたノードは返らない
  • Service Definition of App
    • jsonでサービスを定義、dig app.service.consul @127.0.0.1 -p 8600で引く
      • DNS-RRでコロコロ変わる
      • 10ノードでもうちランダムで3アドレスのみ返る
      • TTLは0
    • TCPで引けば全て返ってくる
  • :8500にRESTポート
  • 最近外部DNS連携が出来るようになりました

Health Checking by script

  • ユーザ定義のヘルスチェックコマンドを実行
    • 終了コードで判別、Nagios互換
    • consul agentがHTTPチェック
    • TTLで数分間隔以内でpushしにこれるかのTTLチェックもある
  • KVS
    • memcachedのフラグにあたるユーザ定義を付けれる
    • パフォーマンスはリーダーノードに向かって40000qps
      • 他のノードはリーダーに問い合わせるので下がる
      • かなり早い、遠慮なくGETできます
    • PUTは427qps、そんなに頻繁に置かないはずなので深刻ではないハズ
    • stale modeにするとリーダ以外でも応答できる

内部DNSとしてConsulを使う

  • :8600に向けないといけない
  • /etc/resolv.confではポート指定は無理
  • 無理やり:53に向けるにはroot特権が必要で怖い
    • :53は再帰問い合わせしないといけない、Consulはcache機能がないので難しい
  • dnsmasq, bindなどからConsulをフォワードする
    • .consulならlocalhost 8600にフォワード、それ以外はunboundへ
      • たまにVPC標準DNSが返さない時があるので、自前のunboundを置いています
  • resulv.conで(node+service).consulを検索ドメインに指定
    • node/service名だけで検索できる
  • BINDは夏休み取りたいので使いません

Deployment Table

  • Server node: 本番では最低3台、5台が推奨
    • 3と4では耐障害性は変わらない
    • 2CPU、RAM20MB、2MBストレージ、くらいの消費
      • RAMとストレージはKVS次第
    • Serverには専用ホストが必要か
      • たぶん不要
      • ディスクIOが激しいとRaftでリーダーが入れ替わりがちなのでIOの穏やかな所が良い
      • デーモナイズ機構がないのでdaemontoolなんかでお願いします
  • start_join
    • consul serverには固定サーバ
  • Atlas連携
    • 大統一理論
    • Atlasのトークンで全部引っ張れる
    • 10ノードまで無料、それ以降は40USD/m、join自動化のためだけには高い
  • Server nodeのフェイルオーバーは自動、リーダーが落ちたら再選出が終わるまでDNSが引けなくなる

    • だいたい2,3秒で終わるが、stale modeを使えばそれも潰せる
    • DNSキャッシュがあればTTLを明示しておける、ただしその分反映は遅れる
  • 運用中のUpgrade

    • クラスタは一回立てると落とせない
    • ローリングアップデート方式
  • 0.2時代からproductionに入れて1年運用してますが、agentが落ちたりクラスタが崩壊したりした記憶はないです
    • Quorumが満たせないレベルまで減るとクラスタが崩壊します、データが飛んでしまう
      • KVSは定期的にバックアップ、ユーザデータは絶対に入れないように

オートスケール環境で使う

  • Lobiの動画変換機能(ElasticTranscoder)
    • S3に上げてキックしたら変換してくれる
      • ちょっとお高い
      • 1投稿2分で25円、1万人分で25万円
  • モンストにSDK導入しました
    • 家が立つレベルでお金が飛んでしまう!!!
    • →SPOTで変換する
      • cc.88xlarge(32core) = 0.45USD/h
      • 1/10〜1/100にまで削減
    • ピーク時で45台くらいまでスケール、最低2台
  • スケールアウトはJobの量で

    • リアルタイム性は低いので遅れてもOK
  • 自動でuniqueなホスト名を付ける、join、Chef,デプロイ...

    1. user-dataでユニークホストを名付ける
    2. ChefのノードをConsulのKVに入れる
    3. Stretcherでdeploy
    4. Zabbixに登録
    5. OS起動時に登録するとアラートが飛んでしまう

Stretcherを利用したデプロイ

  • 自作しました
  • ConsulとSerfで動くデプロイツール
  • これまでは中央サーバからのデプロイ
    • このpush型はオートスケールに対応できない
    • pull型で中途半端なときに持っていかれると困る
  • gruntやGoの生成物を格納したくない
  • デプロイのたびにAMI再生成はやりたくない、10デプロイ/日もできない

Stretcher

  • sorah/mamiyaAWS CodeDeployとほぼほぼ同じです

    • AWS以外でもつぶしが利く
    • rsync&コマンド、というフローを踏襲
    • sshではなくConsulのイベントで通知
    • golang
  • ビルドしたものをtarにしてS3へ

  • YAMLの定義ファイルmanifestもS3へ

    • 各ホストのConsulがtarとYAMLを読んでデプロイしてくる
  • Consul Event

    • ゴシッププロトコル
    • consul event .....で発火
    • consul watchでイベントの伝搬を監視
  • ビルドプロセスはStretcherには関与しない
  • 各クライアントでtar.gzを一旦TMPDIRに展開して、ローカルrsync

  • Lobiでのデプロイ例

  • tgz 200MB
    • CPAN 110MB
    • nade_modules 10MBx5
    • Go app binaries 8MBx5
    • static files(S3に逃したい)
  • ビルドで1分
  • パックとアップロードで1分
  • イベント通知から10~30秒
    • S3は200MBを100並列で取得してもびくともしない、おそろしく頑健
  • ロールバックで威力を発揮
    • 元のmanifestだけ送ればOK

Chef/Serverspecの通知を一覧したい

  • 100台で失敗すると100行エラーが出て阿鼻叫喚
  • Consul KV Dashboard

    • 作りました
    • golang
    • ConsulのHTTP APIで送る
  • Blocking query

    • 次のリクエストが来るまでリクエストを待たせる機構

オートスケールでのデプロイのtips

  • 最新のmanifestをConsulのKVに格納
  • AMIに残ってる古いアプリが起動すると事故る
    • 最新のデプロイID出ない場合は起動しない
      • 初回起動時のみ、daemontoolを起こす前にKVとローカルの値を比較する

bash-completionでsshのホスト名補完

  • known_hostsを参照するときのfunctionを.bash_profileで上書きしてKVを参照するようにするとすっきりする

まとめ

  • Consulは機能豊富、だが使いたい機能だけ使えば良い
  • KV, Event, Health Check...
  • consul-templateで動的LB設定

Q&A

  • rsyncが滑った時(消せないファイルがある)はStretcher全体がabortするように設計
  • ためにし1台、のときはeventを1台に送る
    • consul-lockを使えばn=5にすると5台ずつ完了を待って実行していく
    • あとはグループを分けるとかしてBlue-Greenっぽい挙動を作る感じ
  • 同じアプリをポート番号だけ変えて複数持つ、みたいなケースにも使える?
    • SRVレコードを引くとポート番号を含めたディスカバリができる
    • サービス名、サービスIDは一意に
  • StretcherとかDashboardはどれくらいで実装?

うっかりをなくす技術

  • @karupanerura
    • うっかりACアダプタを忘れてしまった
      • 貸して頂けました
    • Kenta SATO
    • Perl/XS/Swift/Kotlin/Java/Crystal/C99
    • Gotanda.pm
    • Senior Engineer at Mobile Factory, Inc.
    • CPAN
      • Time::Strptime
      • Geo::Hex:V3::X5
      • etc
    • YAPCで毎年少しずつ大きなところで話させてもらい、主催側に
      • YAPCありがとう

人間は失敗する生き物である

  • ヒューマンエラー
  • 安全工学とかですごい研究されてる
  • この観点から見たアプリケーション開発

  • Agenda

    • ヒューマンエラー
    • どのようにして気づくのか
    • どのようにエンジニアリングでなくしていくか

Huan Error

  • We neet safe code.
    • アプリをクラッシュさせたくない
    • うっかり間違えるし、すごい工数が発生するときもある
  • ヒューマンエラー≒うっかりミス
    • ちゃんとした定義をいろんな人が定義してる
    • David Meister
      • システムから要求された行為からの逸脱
      • エンジニア的には↑のオペレータ視点は"他の開発者"
    • 他の開発者の視点でコードやシステムを見つめる
    • 「システム」は人によってはインフラ、アプリ、ソースコード...
  • ファクター
    • 人的要因
      • うっかり
      • そもそもの間違い
      • 安全工学的には意識レベルを意図的に高める
        • 指差し確認、体と声を動かしながら意識を高める
      • NKY
    • マネジメント要因
    • 環境要因
      • 理解しづらいもの{コード、仕様、手順}
      • フェイルセーフにする、ミスに気付けるようにする

near-miss

  • ヒヤリハット
  • 実際に顕在化してないミス
  • ハインリッヒの法則
    • 1つの重大なインシデントの裏には30個の小さなインシデントがあり、そこにはさらに300のニアミスがある
    • それらはほぼ同じ要因で起きている
  • ニアミスの要因をなくしていけば、大きなミスも無くせる
  • 実際に損害を出さないので、非常に気づきにくい
    • どうやって集める?
    • github issues
      • 一覧できることが重要
    • コードレビュー
      • 他の開発者の視点を取り込める
      • 認識が違っていたらマズい合図

エンジニアリングによるアプローチ

  • 環境要因はエンジニアリングのアプローチが非常に有効

  • break

    • 五反田のおにやんまのうどんをバックに

easy to understand

  • 読みやすいコード
  • 説明的な命名
  • 副作用を減らす
  • "Art of Readable Code"

    • 読んで下さい!それでこの話は終わりです!
  • ドキュメント・コメント

    • そのコードの読み手は、コードに書かれていないことはわからない
    • なぜこのアプローチ・ワークアラウンドが必要なのか
    • これらを書いておけば、正しい取捨選択に役立つ
  • 副作用をなくす

    • 当然ながらグローバル変数を使わない
    • オブジェクトのライフサイクルを短くする
    • Immutableなオブジェクト・値を使う
    • 関数型的なアプローチ
    • オブジェクトはほとんどの場合状態を持つ
      • これを減らすためにはオブジェクトそのもののライフサイクルを小さくすること
    • Switch Frameworkをご存知のかた?
      • (Perlのカンファレンスなのに少ない!)
      • eg.)Sledge::Plugin::Stash

Simple ways

間違いに気づきやすくする技術

型制約

  • strict.pm
    • Perl5標準
    • 未定義変数の参照をコンパイルエラーしてくれる
    • soft referenceなどの危険な機能を制限してくれる
  • warnings.pm
    • perlは非常にコンテクストに敏感
    • '3:' + 2; # => 5 (!?)
      • +の手前をatoiしてしまう
      • こんなケースの時に警告を出してくれる

        コードの静的解析

  • perlclitic
  • perllint
  • 実行せずに間違いに気づく

  • swiftにおけるint?

    • Optional<int>シンタックスシュガー
    • Optional型がnullでないことを確認しないとコンパイルエラーを出す、nullが代入されえるかを明示する
  • guard.pm

  • GoとSwiftdeferに相当

Poka-yoke

まとめ

  • ニアミスをなくしてインシデントをなくす
  • 簡単に使えること、間違いに気づきやすいこと

Q&A

  • 一番うっかりが減ったアプローチは
    • 静的型付け言語を触ると補完の強みも相まって想定外の挙動はかなり減った気がする
  • コメントがコードを反映してない現象への対策
    • コードをみんなでレビューして、その場でコメントをコードと同等にレビュー対象にしてもらう
    • コードとコメントの整合性を機械的にチェックできる機構ができれば良い未来がありそう
  • うっかりが出そうな、ニオうコードの傾向は
    • 他の人の書いたAPIをどのように自分が叩くだろうか、といった考え方で触れてみる
    • コードから連想する使い方をそのままぶつけてみる
  • 静的解析ツールの、理不尽な指摘への対処
    • perlcliticなんかは重箱の隅をつつく感じの理不尽な指摘がある
    • それをほったらかしても問題が出ない、と経験的に確信が持てるものなら無視しても良いと思う
      • たとえばundefを返すコードが怒られる
        • カラコンテキストだとundef、リストコンテキストだと[undef]が返って罠っぽい
    • 自分は破るときは意図して破るようにしています

LT

良いオフィスランキング

  • 941
  • くしい
  • '10~13 YAPC::Asia主催
  • いろんな会社に訪問して紹介してます
  • 941::BLOGのすごいところ
    • 業界の知名度が抜群
  • もっと選択肢は有るよ!と昔の自分に言い聞かせたかった

  • 良いオフィスランキング

  • NHN Japan
  • Gree
  • Cookpad
  • 現Wantedly
  • 旧Freakout
  • ネクストイノベーション
  • リッチマン・プアウーマンのモデル
  • 超リッチ: Microsoft
  • 頭おかしい: バーグハンバーグバーグ

Gitのつくりかた

  • DQNEO
  • どきゅねお
    • 今月メルカリに就職しました
  • "gitを理解する最良の方法、それはgitを自ら作ることです" --DQNEO
  • gitはVCS、というよりコンテンツ管理システム
    • キーバリューストア
      • キーはSHA1ハッシュ
      • バリューはzlib圧縮するされた何か
  • "hello world\n"
  • blob 12\0hello world\n
    • 圧縮して保存: git add
    • 解凍して取得: git cat-file -p
  • git checkoutは

SaaSで作る僕らの障害対応術

  • @papix
    • GAIAX
  • みなさんびっくりどっきりメカで対応体制を作ってると思います
  • 障害は、ただ治ればOKではありません
    • 何故起きたのか、どう解決したのか、どう再発防止するのか
  • 今回はSaaSを組み合わせた障害対応の仕組みを作ってみました
  • Mackerel::Webhok::Manager
  • Meckerelを軸とした障害対応の仕組み
    • Webhookを投げて再現
    • 「今ホントにアラート飛んできた」
    • Qiita:TeamとTwilioに通知
    • Reactioを使って対応
  • 障害はなくなりません
    • (さらに障害アラート)
    • 備えあれば憂いなし

cpm

  • Shoichi Kaji
  • cpm
    • CPAN client
    • cpan.pm、cpanplus、cpanmがある中で何故?
      • 皆さんちゃんとperlでものを作るときにはたくさんのCPAN依存を持つことになる
      • 既存のツールは直列で膨大な時間がかかる
    • 実際のところ新しいことはなくて、
    • menlo(cpanm 2.0)を並列で叩いてインストールします
    • Plack 50s -> 18s
  • cpanm --dev App::cpm

Norikraで作るPHP検知システム

  • Masanori Nagano
  • PHPの例外を検知し通知するシステム
    • error_log()で返す
    • set_exception_handler
      • try~catchの外の例外を受け取る
    • set_error_handler
      • エラーと例外は別物、例外をエラーに変換する
    • error_reporting & error_log
      • 設定してないとApacheエラーログに出て行く
      • プロセスごと落ちるとさらに別の場所にエラー
    • PHP(mod_php)は4箇所に吐かれる
    • Norikraを使ってます
      • td: in_tail x 4
    • 調べたらudzullaさんが全部書いてました
      • udzullaさんすごい

RSSをざっくりクロールしてゆるふわにパース

  • 角田さん
  • @ace_project
  • Feedwind
  • 事例(クロール)
    • 配信元に連絡して解除してもらう
    • 連絡がつかない場合はプロキシを使って乗り越えている
  • 事例(パース)
    • Mojo::DOM
    • パースできないやつにぶつかりサービスがダウン
    • <br< <- (!?)
    • 壊れてるDOMをパースできなかった
      • 今後のことも考えてゆるふわにパースするようにしました
  • できるだけ集めてできるだけパースしてあげよう、という姿勢が大事なんでないかと思います

Slack+Hubotでお前の一番好きな二次元嫁キャラと一緒に仕事をする

  • @sairoutine
  • さい
  • 趣味プログラミングしてますか?
    • 結構やってますね、ほいほいほいほい
    • だいたい一人でやるので寂しいですよね?
  • 事例: @marisa
    • 自分と@marisaでチームを作りました
    • Botとふたりきりのチームってとこ、ミソですよ
    • 他の人としゃべることがないようにしておく
  • cronモジュールは全部やるのは面倒なので、jsonにまとめて食べさせます
  • tw ......で投稿だけ
  • deployissue listtrello add
    • 一人なんで自分でやったほうが早い気がするけど、botが自分のために動いてくれる、嫁っぽい!

YAPC?雨事情

  • @likk
    • Mobile Factory
  • 会社を出たら雨
    • エレベーターを降りてから気づく、傘はオフィス
      • 戻るの面倒臭い!
    • 定時に五反田で雨が降ってたら通知したい
    • tenki.jp
      • newして東京の場所を指定すると画像が出てくる
      • 拡大して五反田の位置をマッピング
        • GD::Imageで画像差分検知、差分がアレば雨とみなす
  • すごい過去にも遡れる!
    • 歴代YAPCの雨事情を起こしてみました、懇親会だけ雨みたいな日も
  • 雨通知アプリametto/熱中症検知アプリachitto

PUGS ON STACK

  • HIRATARA
    • Freakout
  • PUGS
    • Perl6のHaskell実装
    • 2007に開発停止、ほとんどの機能が壊れている
    • githubに6.2系のメンテナンス(開発最新は6.28)
  • ghc 7.8でビルド
    • ghcはバリバリ非互換変更があり、最新ではビルドできない
  • 7.10とstackでビルドできるようにしてPR送ったら速攻でリリースしてもらえました
  • ベンチしてみたらめっちゃ遅い!
    • 50ms or dieってことで最適化してみました
    • モナド変換を潰したら早くなるので潰してみる
      • Rakudo実装より早い!?
      • 10000万回にすると逆転

PHPの話をします

  • gongoZ

  • 肉体言語を作ったりEmacs内部で一句を見つけるelispを書いたりしてます
  • PHP5.4のセキュリティサポートは'15 9/14までです
  • 5.3の壁
    • うち最大のものがregister globals
    • 「安全でないコードを書くことが極めて容易になることを意味します。」
    • 未だonのアプリの特徴
    • includeしてきた変数と見分けがつかない
  • php.netにのってる
  • 使ってはいけない、間違っています
  • php.netにない隠された仕様
    • $_FILES
      • 個別にマッピングされる
      • 「その結果に驚くことでしょう。」
        • ちゃんと書け
  • $_SESSIONSも対象です
    • リファレンス渡しで来てる!!!

同人活動の報告と今後の展望

  • 本日はコミケ、じゃない、YAPC
  • Kokusaitenjijomae.pm
  • 先週の金曜から日曜まで夏コミでした
  • 例の紐じゃなくて例のモヒにしたい

  • 同人サークル どんぞこ楽屋

  • Acme大全2015頒布中です
  • Acme大全の裏の裏
    • 表ですね
    • 何で書いてる?
      • Word
    • フォントは何ですか?
      • IPAexフォントです
    • なぜつくるのですか?
      • CPANにあるからです
      • 割と苦役に近くなっている
    • なぜ7/7に?
      • ドキュメントに残さないと忘れます、忘れました
    • Acme::Cake
    • 書いてて行き詰まった時
      • むしろ進みが良いと焦ります
    • 電書版は
      • Perl6と同時リリース予定です!
    • いつまでやるの?
      • Perl6リリースまで...