Serverless FrameworkでAWSフルマネージドなツールをいくつか作って得たアーキテクチャ設計の知見

Serverlessとは

  • サーバ単位ではなくイベント単位で物事を考える
    • スケール 課金 生存期間 管理 監視
    • スケーラブル
  • AWS Lambda
    • イベント単位でコンテナが立ち上がる、CGIのようなイメージ
    • 実行後のコンテナは破棄されるのでステートレスな実装
  • LAMPとの比較
    • LAMPはサーバから全てユーザ管理領域
    • サーバレスはLambdaFunctionだけがユーザ管理領域
  • OSSなFaaSを理解して設計することが重要

Serverless Framework

  • LambdaはFUnction as a Serviceを中心においた開発をサポートするツール
  • インフラもアプリケーションコードも一括管理できるデプロイツール

作ったもの

  • backslack
    • バックログ起票をフックしてAPIgateway->Lambda
  • faultline
    • クローリングをLambdaで行ってS3にHTMLを突っ込む
  • uthusemi
    • 動的な更新が可能な静的サイト生成ツール
    • 更新をフックして静的サイト化するLambda
  • そもそも運用にたるのか
    • 管理できる領域が少ないので落ちても復旧するのはAWS側
    • 画像などのバイナリリクエストレスポンスの取扱が難しいけど設計ちゃんとやればOK

設計方法

  • POST with config
    • 定チロツール側で保存するだけでステートの管理対象が増える
      • できるだけ値を保持しないのが鉄則
    • APIベースのツールなのであればリクエストに必要な設定を毎回付与
  • Reserved Timestamp id
    • RDSはサーバレスアーキテクチャではたいていアンチパターン
    • DynamoDBでテーブルすべてのデータの一覧を作るのはアンチパターン
    • S3を書いとして
      • prefixの使い方がポイント
      • IDからファイル生成時刻を判別できるようにする
  • Instant Job Queue
    • SQSにキューを入れて順々にLambda処理を行う
  • S3 objext Tagging
    • S3のオブジェクトにmetadataをぶっこめる
  • Env Sync
    • デプロイ時の環境変数とfunctionが実行されるコンテナの環境変数を動悸させる
    • Twelve factor app 設定を環境変数に格納する
    • Serverless Frameworkを使ってるとSTAGEに環境変数を流し込みやすい

まとめ

  • サーバレスアーキテクチャはハマれば強力
  • 上手く構築するためにはLAMPアーキテクチャと違うことを意識する
  • FaaSとその周辺のマネージドサービスの特性をうまく活用して設計する

広告配信管理システムを支えるPHP レガシーシステムからの段階的以降戦略

  • 全体を把握できないくらい育ってしまったがコードに価値がある(=稼いでいる)
    • コードを加えるのも減らすのも怖いが価値があるから壊せない
    • 価値のあるコードをより良くしたい

背景

  • 価値を出しているが読みにくい、長い
  • 単体テスト、統合テストは全てCIで自動実行
  • コードレビューされなければmasterにマージしない、テストなくてもマージしない

下準備

  • 静的解析で大まかに複雑そうなところを見つける
  • grepで重複コードを洗い出す
  • こんなコードも…
    • とりあえずルート例外をthrow
    • ルート例外でcatch
    • ログもエラー画面も同じメッセージ
  • 原因を追えないログを出すのはやめろォ

足固め

  • アプリケーションベース例外を定義
  • アプリケーショングローバルな例外ハンドラを実装
  • ロギングとエラー表示をいいかんじにする
  • set_exception_handler
    • 例外は怖くないよ!
  • ルート例外をimplementsしたクラスを作成
    • ユーザ向けに表示するメッセージ定義などを用意
    • 最終的にアプリケーションベース例外をcatchすればOK
    • スタックトレースもログに追加
      • システム管理者向けのエラーメッセージとユーザ向けメッセージを作る
  • 安心して例外をthrowできる環境を作るべし
  • NewRelic モニタリングツール
    • いつどのパスでどのくらいの例外が発生したかがわかる
    • スロークエリログとかも分かる

改善

  • 全員PhpStormを使え
    • Inspectionが優秀
    • 無駄コードも表示を出してくれる
  • PHP 5.3->5.6->…
  • 無駄プログラムの削除
    • GoogleAnalyticsで使っていない画面を削除
    • 利用頻度の少ない画面はRedashにクエリだけ移行して担当者に伝えてまるっと削除
  • 最良のコードはコード無し
    • 外部ツールに上手く頼ろう、いらないコードはどんどん消そう
  • 実装ガイドラインを作る
    • PSR-1,2準拠、php-cs-fixerのCI組み込み
    • クラス名関数名などの命名ルールを決める
    • PHPDocをちゃんと書く
  • 規約を作ったらペアプロ
    • ペアプログラミングで書き方を伝える
    • レビューだとぶつかりやすい時に特に有用

まとめ

  • 価値のあるコードをより良くしたい
  • 誰だって不安はある
    • この変更で挙動を壊したらどうしよう
    • 守りをまず固める
  • コードを自分たちの手に取り戻す

現代におけるプロダクト開発とPHPを選定するワケ

このセッションで伝えたいこと

  • なんとなく の言語化
  • なんとなくでPHPを採用する理由
    • 現場にPHPerが多い、PHPが使われている慣習など
  • 技術選定、意思決定をより円滑にする

PHPの得意分野と適材適所

  • HP制作
    • ホームページ制作系・コーディング案件
    • お問い合わせフォームの作成など
    • 基本的に更新頻度が低い、ホームページなので機能拡張はほぼ無い
  • CMSカスタマイズ
    • CMSのベースを維持しながら要件に合わせて拡張
    • WordPressだけでも世界の1/4を占める
  • Webシステム開発
    • 自社サービス、業務系のシステム、プロダクト開発など
    • 要望やロジックが大きくなるためのメンテナンスコストがかかる案件
  • メリット
    • 小さなロジックの差し込みやすさ
    • CMSが用件に入るからこその排他的な技術選定
  • あまり難しくないことを早くかつ上手く

ユースケースにおけるPHPの起用

  • 秩序ある開発を行うために必要なこと
    • 例えば Laravel+最新のPHP環境 とかを使っていこうぜ
    • パッケージマネージャはComposerがあってバージョン統一しやすい

別の選択肢

  • webアプリケーション開発 1
    • SNSアプリケーションを開発したい
    • ユーザーや投稿、基本的なCRUDが存在してデータが複雑に紐づく
    • なんて場合はRuby on Railsとかでもいい
  • webアプリケーション開発 2
    • 業務アプリケーションを開発したい
    • 業務上の数字に関わるため出来る限り堅牢なシステムを組みたい
    • なんて場合はJavaやJVM上で動く言語でもいい
  • webアプリケーション開発 3
    • リアルタイム性のあるアプリケーション開発をしたい
    • SSEやWebSocketベースでクライアントとデータのやり取りをしたい
    • なんて場合はNodeJSでもいい

まとめ

  • リソース・人員の確保の容易さ
  • どんなことでもとりあえず動くので選定されやすい
  • 歴史的経緯とメンテナンス性やナレッジが多い
  • ひとまず走り出すための言語として認識しても相違ない
  • PHPを利用する時は
    • 仮置きしやすい特徴を有効活用
    • 意思決定のオーバーヘッドを減らす

PHP Version Up と AWS への移行

  • レガシーと戦って僕達が手に入れた武器
  • 僕達が手に入れた武器でやったこと

基本システム

  • オンプレ
  • ロードバランサ、アプリケーションサーバはPHP、MySQLサーバ
  • オンプレのレガシー化
    • 数千大規模のサーバ入れ替えが必要で対応が遅れた
    • 息の長いサービスが密結合化されている
    • API化されていなかったり同じサーバで複数ゲーム動いていたり
    • 抜け出せないレガシーの沼
  • レスポンス速度の改善も限界
    • 売上を立てる以前に大きな問題が出てくる

入れ替えに当たって

  • 少人数によるプロトタイピング(2,3ヶ月)
  • 各サービスの共通コードを完成させる
  • ノウハウ共有
    • 全サービスで共有のエラーレポートフローを定義
    • チームや領域によらずに修正
  • まずは現環境PHP5.2と新環境5.5で必ず動くように修正
  • リリースは1第二投入して2週間以上様子を見てから
  • 入れ替えによって勝ち得たもの 互いのシステムへの相互理解

AWS移行

  • オンプレの老朽化がガタが来始める
  • 一丸になってやればなんでもできる自身を得てから
  • AWS移行しつつ並行してPHP7への準備を進める
  • DirectConnectを使って事前にMySQLのレプリカをAWSに作る
  • 移行してよかったこと
    • サーバ費用40%減
    • ハードウェア性能向上による負荷軽減
  • わかったこと
    • 複数の移行を同時にやろうとするとこけやすい
    • PDCAをしっかり回して事前作業を見積もる
    • 前回の移行の経験を次に活かす
  • 技術負債は人的資源に変えるチャンス

片手間MySQLチューニング戦略

スローログ出しましょう

  • 実行に一定時間以上時間がかかったクエリを出力させる
  • デフォルトがoffなのでONにしよう(本番は0.2秒とかにしてね)
  • FILEに吐かせよう
  • generalログとは違うのか
    • クエリーをパースする時点を吐き出すログ
    • ロックがめちゃくちゃでかいので気をつけよう
  • 吐かせた後に見ていくポイント
    • Timeが短時間に集中している?
    • 慢性的に遅いのか、何かの要員があったのか
    • スロークエリを吐き出して時間分布を把握するためのツール
    • where句の値が特定のものに偏っていないか

InnoDBバッファプール

  • バッファプール
    • オンメモリに確保されるヒープ領域
    • 物理メモリの75%を割り当てろ←デカァァァい
    • 必ずここを経由するのでここが小さいと落ちる
  • ログファイル
    • 更新のログを保存しておく領域
  • テーブルスペースファイル
    • 実データの領域

インデックスを使いましょう

  • WHERE句のカラムを列挙してからORDER BY句のカラムを列挙する
  • ANDと=以外の演算子をORDER BYと混ぜて使わない
  • 値に対して演算を行わない
  • インデックスをきれいに使うと
    • バッファプールを大事に扱える
    • そもそもバッファページにのるメモリ量が減る
    • デフォルトのInnoDBのロックはネクストキーロック

劇薬には手を出さない

  • 今までやってきたのが何だったのかってくらい性能が上がる
    • 黙ってデータが抜け落ちてる可能性があるのでできる限り手を出さない

LT

MDD

  • ヒトです
  • プログラマは生活習慣が乱れやすい
    • 朝早く筋トレ
    • 睡眠時間を確保
  • まず近くのジムを検索だ!!! :muscle:

初めてPHP触った話

  • Laravelの認証・ユーザ登録周りが用意されてる
  • パスワードはハッシュしてくれてるがsecure属性がOFFなので変更しよう
  • CSRFプロテクションなど便利でセキュアなものがいっぱいあるので利用しよう
  • 徳丸本を読め

PHPでJavaScriptを書く話

  • babel-preset-phpのメリットはPHPでJSを書けること
  • phpのプロジェクトを読み込めないので実用性低い

結果にコミットするIoTデバイス

  • お腹を凹ませ続けて痩せて見えるデバイス
  • IFTTTからSlackに通知

いかにして若手PHPerはレガシーなWebサービスと向き合うようになったか

  • ユーザに提供できることがまだまだ大量に残されている

3年目エンジニアOSSをはじめる

  • Rubel
    • MS
    • Laravel+React
  • レビューしてもらえるので技術面の向上を図れるよ
  • 転職にも有利だよ

SwaggerでPHPとUnityエンジニアが仲良くなった話

  • アプリ・ゲームのAPIつなぎこみが難しい
  • Swagger Spec,UI,Codegen
    • YAMLで記述できるAPIの設計図
    • mastacheでコードが生成される
  • サーバエンジニアがSpecをかけばPHPのコードとC#コードが生成される
  • ドキュメントもコードも置き去りにならない
  • SwaggerでAPIつなぎ込みの辛さを軽減できたのでブログを参照

良いテストデータ、悪いテストデータ

  • 自動テストで使うテストデータの行けてない例
    • 本番DBをdumpしたテストデータ(要らないテストデータが多い)
    • 意味のない文字列のテストデータ(ああああああ とか、テストの意味がみえない)
    • 個人の主張がですぎているテストデータ(プリキュア あとで見た時に恥ずかしい)
    • 整合性が取れていないテストデータ(更新日時が作成日時より前とか)
    • 一枚岩の巨大なテストデータ
    • 一箇所でしか使わないのに他でも読み込まれるテストデータ
  • イケてるテストデータのポイント
    • 最小限
      • テストで検証する動作のために必要なものだけ
    • 意味のあるデータ
      • 汎用的なデータより実際のカラムと近いデータにする
    • 適切な分割
      • マスタテーブルと共通化するなど
    • Facrotyを使う
      • テストメソッドを使う

PHPでGoogle Cloud Spannerをつかってみる

  • CloudSpannerとはリレーショナルデータベースサービス
  • PHP対応状況 composerで入る
  • SpannerにAUTO_INCREMENTが無いので自作する必要がある

元記事はこちら

PHPカンファレンス2017に行ってきました