Hameeでは"ネクストエンジン"というプロダクトをPHPを使って開発・運用をしています。
ネクストエンジンは13年の開発・運用を重ねて成長してきた一方でたくさんの課題も抱えており、その課題を解決するため日々改善活動を行っています。今回は監視の観点から弊社アプリケーションエンジニアとSREエンジニアの二名が現場から生の声をお届けします。
対象
Twitter:
日野陽平 (https://twitter.com/money166)
大嶋淳司 (https://twitter.com/atsusics)
Discord Channel: #track1-1-b-hamee
Yappliのサービスの一部は独自フレームワークなPHPで実装されています。この独自フレームワークはトランザクションスクリプトかつinclude Orientedで、重複コードが多くテストコードも無いなど様々な課題を抱えていました。その結果、開発や運用の心理的な障壁となっており、不具合が発生しやすく保守性の低いシステムとなっていました。また、当システムに対する機能追加・改善要望も多数ありました。
そこで、サーバを立ち上げて行う自動テストや静的解析により、既存コードを修正せずに品質を担保し、
autoload化、ライブラリの導入、リファクタリングによる既存コードを修正する改善で、開発・運用効率を上げていきました。
本セッションではヤプリが取り組んできた改善を例として、独自フレームワークPHPアプリケーションを安全に確実に改善していく方法をご紹介します。また、各改善のタイミングや改善を続けるためのメンタル的なTIPSも併せてご紹介できればと思います。
Discord Channel: #track2-1-b-framework-kaizen
私たちのサービスはローンチから20年を超え、現在も積極的に開発中です。幸いにも今まで多くの方に使われるサービスとなっています。しかし、これだけの年数を経て多くの機能を追加しているため、典型的な「レガシーシステム」となっているのが現状です。
もちろん、開発時にはさまざまな課題があり、完全に解消することは難しいです。それでも、大規模なサービスを維持していくためには開発を継続することが重要です。
本セッションでは、大規模なレガシーシステムを継続して開発していくために取っている戦略の中で、ミドルウェアのバージョンアップに関する戦略を中心にお話します。
ミドルウェアのバージョンアップは、通常の機能開発とは大きく異なります。たとえば、サービス提供を続ける限り避けて通れないものですが、新たな価値を発生する者ではありません。そのため小さな機能追加などで積極的にバージョンアップをすることは難しく、EOLに合わせると、PHPの場合は2年に1度のバージョンアップになります。
そして、広い範囲の既存コードに手を加える可能性があります。バージョンの間が開くと修正箇所も当然増えます。いわゆるレガシーシステムであれば、影響範囲はアプリケーションすべてといっても過言ではないですし。修正が重複する個所すらあるかもしれません。
この影響範囲の広さが、レガシーシステムのミドルウェアバージョンアップを難しいものにしています。
それを考えずに、通常の開発と同じようにミドルウェアのバージョンアップをすることは困難で、正面から挑むだけでは無限の時間とコストがかかります。
現実世界には時間、コストなど、さまざまな制約があります。これはビジネスでサービス提供をしている以上当然避けられず、その中で戦わなければいけません。
となると作り直すのも現実的ではないすし、だからといって場当たり的な対応だけでは、技術的負債を抱え込んで開発の継続が困難になるかもしれません。
広範囲で複雑な問題には、取捨選択が必要です。いまある複雑な問題は、今この場面で対応すべきことではないかもしれません。
このように、普通の機能開発とは異なる困難さ、複雑さをもっています。これに立ち向かうためには、戦略をもって挑まなければなりません。
本セッションは、ミドルウェアのバージョンアップ事例の紹介とそのプロジェクトで採用した戦略についてお話します。
事例紹介では、直近実施した2件のバージョンアップ(PHP,PostgreSQL)の事例を紹介します。その中では現実の制約に沿った形でプロジェクトを推進するためのゴールの設定、事前準備、実際の作業プロセスについてお話します。
そして紹介した事例をより一般化し、レガシーシステムの開発を継続していくための戦略を紹介します。
Discord Channel: #track3-1-b-middleware-up
オブジェクト指向プログラミングがどういったもので、どういうときに役に立つのかについて解説します。
多くの初学者はプログラミングを始めて手続き型の記述に慣れた頃、オブジェクト指向プログラミングに出会います。
クラスやオブジェクトといった用語を学び、オブジェクト指向プログラミングの機能を実際に記述して体感します。
そして、混乱に陥ります。
なぜなら、オブジェクト指向プログラミングを活用することで何が嬉しいのか、機能を体験しただけでは理解できないからです。
道具を使いこなすには、それがなんであるかを学ぶと同時に、その目的を知らねばなりません。
目的を知らずに道具を扱えば、よく切れる包丁で紙を切るといったおかしな事態が起きてしまいます。
本トークでは、オブジェクト指向プログラミングがどういったもので何ができるかを解説するのと同時に、どうしてそれが必要なのかについてを解説します。
※本トークがカバーする範囲はクラスによるカプセル化とサブタイプポリモーフィズムまでです
■トーク対象
Discord Channel: #track1-2-oop
ORM が高性能になり、SQL (クエリ) を意識の外に置くことも増えてきました
おかげでより開発効率も向上し、スピーディ・高品質なコードが書ける率も上がっています
しかし…アラートは突然やってきます
落ちるページ表示速度、上がる DB サーバー の Load Average
そして大量のスロークエリ
もちろん原因はこれだけではありませんが、僕らの日常では、1つのスロークエリが DB サーバーを停止させることも少なくありません
SQL は書き方次第で簡単に障害に繋がります
また、障害発生時、プログラムがどんな SQL を実行しているのか
実装した SQL は速いのか、遅いのか
それがわからないと、障害解析で困る場面も多いです
障害などの緊急事態を回避する以前に、品質の観点でエンジニアには日常的に以下が求められると考えています。
本セッションは、実例をベースに上記を説明しつつ「現場で使えるスロークエリの倒し方」を持ち帰っていただき、クエリ (SQL) チューニングへの敷居を低くすることが目的です
SQL 見よう!
障害の完全な予測は難しいです
だからこそ打てる手は多く持ち、できれば早めに打っておきたい
その手の1つとして、実際に行っているスロークエリの見方・倒し方・予防方法をお話しします
SQL はチューニングすることで品質の向上が可能です
PHPer であっても、SQL を日頃からチューニングしていきましょう!
開発当初は快適に動いていても、スロークエリは突然やってきます
では見える化はどうしたら良いのか、を
の 2 パターンで解説します
スロークエリが見つかった場合に実行する主な内容を、項目別に解説します
普段の実装時・レビュー時にも実行することでパフォーマンス劣化の予防もできます
要求仕様、設計から立ち帰り、そもそもこれ必要なんだっけ?を徹底的に疑ってみることも重要です
では何を追求すれば良いのか?を実例をもとにお話します
まずいスロークエリを見つけ、解決していくまでの流れを、2つの事例から解説します
普段から予防のために実践していることをお話します
Discord Channel: #track2-2-mysql-tune
みなさんの運用しているアプリケーションはモニタリング(監視)されていますか?
サイボウズのGaroonではサーバーレベルのモニタリングはされていましたが、アプリケーションレベルのモニタリングは今まで十分には行われていませんでした。
そのため、お客様からのお問い合わせがあって初めて障害に気がつくことが多くなっていました。
また、発生している問題の重大さもうまく把握できていないため、どれくらい優先して障害対応をすべきなのか、本当に障害として対応するべきなのかといったコミュニケーションを、SRE・ビジネスメンバー・サポートメンバーなどの社内の他のメンバーとうまく取れていない、という問題もありました。
そういった状況から脱却すべく、昨年からアクセスログの集計やメトリクスの収集を行い、必要に応じてアラートを飛ばすモニタリングの仕組みを導入しました。
このセッションでは、モニタリングをどのように導入したのか、モニタリングで得られた数値とお客様に与えている不便さをどう結びつけたか、モニタリングによって開発チームと社内の他のメンバーとのコミュニケーションにどのような変化があったか、いまモニタリングで苦労していることをお話しします。
Discord Channel: #track3-2-a-php-monitor
皆さん、PHPのDockerイメージは使ってますか?
開発手法は人や組織によって様々ですが、ローカルでの環境構築や本番環境へのデプロイにDockerイメージを使うことは一般化しつつあります。ですが、普段使っているイメージの中身をきちんと把握していると言い切れる人は意外といないかもしれません。そこで今回は「PHPのDockerイメージの深堀り」をテーマにお話をしたいと考えました。
・「何のために使ってるか分かってないけど、依存関係の都合でとりあえず入れてる。」
・「イメージのサイズが大きくなってきたから軽量化をしたいけど、パッケージの役割がよく分からなくて触りにくい。」
このセッションでは、自信と確信をもってDockerイメージの運用をしたい方へ向けた掘り下げを話していきたいと思います。細かい構成は決まっていませんが、軽量化の話を交えた構成にするつもりです。
※特定のフレームワークを深堀りする話はしませんが、リアルなDockerイメージを作るためにLaravelやCakePHPを使用する可能性はあります。
Discord Channel: #track4-2-a-php-docker
トーク概要
PHPそのものにバグがあるということがあります。仕様が変更されたために起こったバグだったり、PHPほどの歴史があるオープンソースソフトウェアだと皆に知られないまま十何年も潜ってしまったバグもあったりしたりします。
バグ報告を行おうとすると、PHPの側がおかしいのか、自分のPHPコードがおかしいのかで切り分けないといけませんし、仮にPHPそのもののバグだとすると、PHPのソースコードの莫大さと、PHPや使用しているライブラリの歴史の厚み、マニュアルにない仕様の変更、頻繁かつ大規模なリファクタリングなどが壁になりがちで意外と大変です。
私が間違っているのか、PHPが間違っているのか。大体は前者です(そして、そうあってほしいのです)が、後者だったときの切り分けの仕方を考えてみませんか。
トーク対象
PHPのバグを見つけてみたい人や、PHPのみならず規模が大きいソフトウェアのバグとどう見つければいいかの参考になれれば嬉しいです。
Discord Channel: #track3-2-b-php-src-bug
新規のプロジェクトが始動して開発を始めるとなったら、まず何を行うでしょうか?
GitHubにリポジトリを用意して、Laravelの環境を用意して、すぐに各チケットの本開発に入るのでしょうか?
新規プロジェクトは最初は純粋無垢の綺麗な状態ですが、雑に開発を始めてしまうと、ある瞬間に何かしらのやばい匂いが漂っていることに気づくことがあります。
スピードだけでなく開発のしやすさなども考慮しつつ、レガシープロジェクトにならないように意気揚々と始めたにも関わらず、なんかおかしいぞ?となる瞬間があります。
そこで、本セッションでは、新規プロジェクトにおいて、少しでも長いスパンで本開発をスムーズに進めるためにまず最初にやるべきことを紹介します。
特に、以下のような内容を話します。
・コーディング規約チェック機構、静的解析、テストなどの用意
・CI/CD
・Xdebug
・サンプル構築
・チーム内コミュニケーション
・READMEやドキュメントの整備
Discord Channel: #track4-2-b-env-setting
近年、PHP コミュニティでも DDD が大きく脚光を浴びるようになりました。その考え方に触れることで設計手法や実装パターンに興味を持つようになった人も多いでしょう。
DDD に限らず、多くの書籍では様々なパターンが紹介されています。
こうしたパターンは有用なのですが、特に設計パターンにおいては性質上、抽象的な内容となり、それ自体は理解できても自分が日頃おこなっているアプリケーション開発ではどのように適用すれば良いかがイメージできないことがあります。
本セッションでは、あるドメインを題材にして、モデリングから設計、そして最終的に PHP で実装するという一連の流れをご紹介することで、ドメインを中心に開発するイメージを持っていただければと考えています。
実際は、ドメインをモデリングして PHP コードに落とし込むという行為は誰もが日常的に行っているものです。
その手法や視点が異なるだけとも言えるので、こうしたやり方もあるのだなという気軽な気持ちでご参加ください。
Discord Channel: #track1-3-domain-modeling
速いは正義、アプリケーションは速くあるべきです。
なんとなくやってるパフォーマンスチューニング、
チューニングを行うとPHPWebアプリケーションはなぜ速くなるのでしょうか。
意識的に作った遅いアプリケーションを使い
OS、Webサーバー、PHP、RDBMSが遅い原因を知ることで、
遅くなった原因を一つ一つ分解して解説します。
パフォーマンスチューニングを行うに当たり必要な基礎理論を見直し、
なぜ遅いのかを知り、どうすれば速くなるのかを知ることで、
具体的なチューニングをなんとなくではなく、意志を持って選択出来るようにしましょう。
■想定する聴講者
- PHPWebアプリケーションのパフォーマンスに興味がある方
- PHPのインフラを整備するエンジニア
- なんとなくオススメのチューニング設定を貼り付けてる方
■お話しないこと
- パフォーマンス以外の話
- アプリケーションコードによる改善
- 劇的なパフォーマンス改善策
Discord Channel: track2-3-a-php-performance
みなさんのチームでは日頃からコードレビューはされてますか?
弊社でもリリースするコードに対して2人以上のコードレビューを必須にしたりと活発に取り組んでいます。
コードレビューには以下のような効果が期待できます
・ソフトウェア品質の向上とアーキテクチャの統一
・スキルの向上とナレッジの共有
いかに効果的にコードレビューを実施するかによって、チームの成熟度やプロダクトの品質に影響すると言っても過言では無いかもしれませんね。
しかし、正直なところ自分はコードレビューに苦手意識がありました。
一度のレビューに時間がかかったり、他のメンバーと比較してコードの改善提案をする回数が少ないのです。。。
そんな私が苦手意識のあるコードレビューをどの様に克服していくのか、体験談を踏まえてお話しできればと思います!(現在進行形)
▼お話しする内容
・コードレビューの概要
・弊社で取り組んでいるコードレビューの仕組み
・良いコードレビューするためのTips
・苦手意識のあるコードレビューをどのように克服していったのか(体験談)
・チームの過去1年分のコードレビューを分析してみる
・ペアプロならぬペアレビューをしてみる
・とにかくレビューしてみる
などなど
Discord Channel: #track3-3-a-code-review
SPA開発においてこんな課題ありませんか?
・フロントエンドとバックエンドで型の整合性を担保したい。
・SPAのディレクトリ構成ってベストプラクティスを見つけるのが難しい。
そんな人の為に、ディレクトリ構成や静的解析、型チェックで工夫している点をお話します。
具体的には静的解析ではphpcs、phpmd、eslint、stylelintなどを導入。APIのリクエストレスポンスでは、厳密な型チェックを行っています。
Discord Channel: #track4-3-a-laravel-nuxt
バージョン 8 にしてとうとう僕らの PHP にも JIT がやってきました!
が、PHP 8 の JIT は生まれたてで、同じ 8 でも JavaScript の V8 にはまだまだ速度的な面で追いつかない部分があります。
PHP と JavaScript のそれぞれについて、おおむね同等の処理を行うマイクロベンチマークのコードを用い、プロファイルをとりながらああだこうだ言いつつ速さの特性差や PHP の現状の限界、得意な点や不得意な点を探っていきます。
■ 想定する聴講者
・典型的な Web アプリケーションは主に I/O バウンドとかそういう現実の話は脇に置いておいて、PHP スクリプトの性能や測定方法が気になる人
・今後の PHP の性能の伸びしろに思いを馳せたい人
・しょうもないマイクロベンチマークが好きな人
■ お話しないこと
・明日から業務に使える役立つ知識
Discord Channel: #track2-3-b-php8-vs-v8
社内勉強会を開催したい!でも運営を続けられるか不安... という方は多いのではないでしょうか?
コロナ以前の2019年から毎月開催しているコミュニティイベント "PHP TechCafe" は、Web や PHP に関わる IT エンジニアがスキルアップを目指して意見交換を行うことを目的としています。
私が運営に参加することを決めたときには、自身の学習モチベーション向上にもつながるだろうと、軽い気持ちで活動を始めました。
しかし、実際に運営を続けると、コンテンツのネタ切れや集客不足、自身の知識の限界による不安など、想像以上に問題点が多く、今も試行錯誤している状態です。
本セッションでは、これから社内で技術系勉強会を開いて盛り上げようとしている方を応援すべく、月一でPHPのイベントを開催するにあたって心がけている、勉強会を継続させるためのポイントやノウハウ、今後考えていくべき課題を紹介します。
Discord Channel: #track3-3-b-community-operation
Laravel7系から導入されたBlade Componentsと近年注目されているUtility FirstをコンセプトとしたTailwindCSSを利用して再利用性の高いコンポーネントの作り方を紹介します。
Blade ComponentsはVue.jsのSFC(Single File Component)のような使い方をBladeで実装できる機能です。
対象者はこれからLaravelを触る方やまだLaravel7系以前の@extend,@yield,@sectionを利用してレイアウトを作ってる方となります。
Discord Channel: #track4-3-b-laravel-tailwind
目標は、「クエリーレビューで怪しげなSQLを先回りして直す」!
Discord Channel: #track1-4-mysql-index
近年、PHPの機能強化により型宣言だけで安全に書ける範囲が広まっています。
その一方でPHPStanやPsalmといった静的解析ツールはPHPでは表現できない強力な型を提供することでコード品質向上の価値を高めることが可能です。PhpStormはPHPプログラマに静的型の恩恵をもたらした一方、先述のツールと比べサポートする型について見劣りする点がありました。
ところが最近リリースされた待望の新バージョンである2021.2はこれまで静的解析ツールの専売特許だった型のいくつかがサポートされるようになり、型検査だけでなく入力補完などの恩恵を受けられるようになりました。そこで追加された型のひとつがジェネリクス(総称型)です。
本発表では、PHPの型についての基礎知識(今日からできる安心型付け入門)があることを前提として、PHPにジェネリクスは入るのか?の内容を軸に、PHPの型宣言では現時点で賄えない部分、特に配列の型およびジェネリクスの概念、class-string型の概念、そしてジェネリクスを実際に活用するためのテクニックを説明します。
Discord Channel: #track2-4-php-type
会員登録を求めるWebアプリでの初期アバター、ECサイトに商品を登録したときの初期画像。
こういった画像は固定のものを1つ用意しておいても良いのですが、Webアプリケーションの実行時つまりHTTPリクエストを受けたタイミング等で生成することができれば、そのWebアプリはもっとリッチなものになることでしょう。
SVG画像はXMLつまりテキストで書かれるものであるため、生成のために必要な特殊技術は少なく、また現代ではほとんどのブラウザで表示可能であることから、アプリケーション実行時の生成に大変適しています。
このセッションでは、PHPでSVG画像を生成する手法について解説します。以下のものの一部または全部を含む予定です。
Have you still not upgraded to PHP 8? We will learn all the great features PHP 8 has to offer. Let's dive into all the details on PHP 8 and 8.1 features. We will also talk about what is deprecated so you can upgrade your code. Let us upgrade to the best version of PHP yet.
Discord Channel: #track4-4-a-php8
Joind.in: https://joind.in/event/php-conference-japan-2021/what-is-new-in-php-8