2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
まず、そもそもの大前提からです。不要なものは消そうって話です。
アプリケーションに1個、複雑な部分がある。その複雑さがそのままのうちは、まだなんとかなるかもしれない。でも、例えば機能の拡張、あるいはそれのスケーリング、あとは開発環境を用意しましょうというときに、その複雑さをさらになんとかしようと思うと、もっともっと複雑になっていく。
その複雑さの理由にはいろいろあると思うんですけど、少しでも、1ミリでもシンプルで複雑じゃないほうがいい。
できる方法としては、まず、いらないファイルやクラスやライブラリは消そう。もしかすると、あってもなくてもいいかという理由で残ってるのかもしれませんが、僕は経験上、そういうものは絶対にないほうがいいと思います。まずはそれを消そう、ということが最初にできる取り組みかなと。
たまに、消すなんてもったいないって気持ちも出てきます。でも、おおよそGitを使ってると思うので、GitHubでいつでも取り戻せます。そうでない方ももしかしたらいるかもしれないですが、そのときいらないようであれば、どんどん消したほうがいいと思います。
シンプルにしていく1つ目「隠蔽しない」。これも最近あった話なんですが、CircleCIって、並列実行の仕組みがありますよね。parallelismだったかな? インスタンスを分けて実行できるという。(それで)PHPUnitを並列実行したいなと思った。
テストファイルを分割するコマンドはCircleCIで用意されている。ただこれ、分割されたファイルのリストを出してくれるんですけど、phpunitのコマンドにはそのまま渡せない。phpunit.xmlとか、設定ファイルでこのテストを実行してくださいって指定する必要がある。
つまり並列実行に必要なこととして、まずcircleciのコマンドでテストファイルを得る。そこからそれ用の、例えばXMLを生成して、そのXMLをphpunitコマンドのconfigurationというオプションで渡してやって実行する、みたいな手順が必要になってくる。
これをやろうとしたとき、最初、一連のやらなきゃいけないことを一発でやってくれるスクリプトでも書こうかなと思ったんです。すごく簡単ですよね。
でもよくよく考えると、けっこう大変なことが出てくる。phpunitにはいろんなオプションがあります。カバレッジを出すかどうかとか。状況によって違ったりします。
あと、circleciのコマンドを含めてしまうと、ローカルで検証しにくい。CircleCIをローカルで動かすライブラリも提供されているんですが、完全に再現できるわけではないみたいなので、あまり良い方法ではないと思います。
またRich Hickeyのプレゼンテーションの引用ですが「抽象化とは隠蔽することではありません。ただ隠すだけでは、なんの役にも立ちません」とはっきり言っています。
じゃあどうしようかと思って、僕らは、PHPUnit用の、XMLを作るだけのスクリプトを書きました。
ほかの部分はそれぞれでちゃんと書いて、使い方としてCircleCIのテストのファイルを分割します。それを使ってXMLを作り、そのXMLを使ってPHPUnitを実行します。これはCircleCIに書いてあるものです。
何がいいかというと、(実際の)書く量は増えているんですけど、例えばリポジトリに全部のテストを実行するphpunit.xmlがあって、それをもとに生成するので、ほかの項目の環境変数とか、あとグローバル変数をどうするかなどを変更しても、差分が発生しないんです。
circleciのコマンドやphpunitのコマンドには、自由にオプションを渡せる。かつ、一番いいところは、ローカルでちゃんと検証ができる。このへんはQiitaに書いたので、詳しいことは見てみてください。これがまず1つ目です。
2つ目「まとめない」。
先ほど紹介した「北欧、暮らしの道具店」というECサイト、これはいくつかのアプリケーションから成り立っています。表側に2つと、裏側に管理用の画面のアプリケーションがあって、それらが組み合わさって動いているサービスです。
これらには共通する処理があるので、lumen-modulesという、共通の処理をまとめるライブラリを作っていました。この名前、スライドには歴史的経緯によるって書いたんですけど(笑)、正確にいえば、僕が入社する前からあったものなので由来はわからないです。なんとなくわかる気もしますけど。
これを1つ、独立したリポジトリに分けて、Composerでそれぞれのアプリケーションがそれに依存するというかたちで運用していました。確かに共通する処理がまとめられていれば、その部分に関する変更はlumen-modulesを変更するだけでよくなるので、楽というか、合理的な面もありました。
しかし、きれいに分割できてたらよかったんですが、共通化する部分だけを抽象化してきちんと分けられていたわけではなかった。
本当に共通する部分はあったとしても、共通していないところもlumen-modulesに入れなければいけない。クラスの依存関係とか、lumen-modules内でテストを実行しようとするときに必要になる部分が含まれている、という状態になっていたんですね。
こういうものを運用していくと、結局、(1つのアプリケーションで)ぜんぜん共通してないところだけど、このリポジトリを触らないといけない部分を変更する必要があるときに、各アプリケーションが依存しているせいで、最新版に保つために各アプリケーションでcomposer updateを実行するという手間があったり。
関係ないはずのアプリケーションのほうでなぜかテストが落ちることもあって、まあまあ開発の足を引っ張っている状況がありました。
『マイクロサービスアーキテクチャ』の本に「サービス間の結合が多すぎることによる害は、コードの重複が引き起こす問題よりもはるかに悪くなります」と書いてあって、あ、これのことや! ってすごく思いました。
結局どうしたかというと、分割することにしました。
さっきのlumen-modulesというモジュールに入っていたコードを、多少のコードの重複があったとしても、各アプリケーション内に含めるようにしました。
構成上どうしても共通にしておく必要があったmigrationsとseedsのところだけ残して。まあこれ自体もどうかなってところはあるんですけど、さっきよりはだいぶシンプルになりました。
かつ、さっきありました変更があるアプリケーションではうまくいくけど、ほかのアプリケーションではうまくいかないということを防ぐために、CircleCIでかなりがんばっているのですが、こいつに依存しているすべてのアプリケーションのコードを引っ張ってきて、それらのテストを実行して初めてマスターにマージできるみたいな仕組みにしました。
これが2つ目です。
シンプルにしていこうという話の3つ目、「作りすぎない」。さっき紹介したように、僕らのアプリケーションは複数に分かれています。
厳密にはマイクロサービスではないですが。
何が問題かって、開発環境の構築がすっごく面倒くさい。会社に入ったとき、途方に暮れるくらいびっくりしました。そんな状況でhokuoukurashi-dev-envというものを作って、最初は自分用だったんですけど、今は開発のチームみんなで使うようにしています。
これは、すべてのアプリケーションの開発環境を一度に立ち上げられるというもので、ただのdocker-compose.ymlとか、必要なDockerfileとかが入ってるだけです。とくにスクリプトとかを書いているわけではありません。僕はそれでいいと思ってたんです。
そしたら同僚が「一緒に立ち上げられるのは便利だから、各アプリケーションのセットアップや、アセットのビルドとか、ほかの大変なやつも一発でできるように作ろう」って言ってきたんです。でも僕は、それにすごく抵抗があった。
例えば、Aというアプリケーションのセットアップ手順が変わったら、そのスクリプトも追従するのか? アセットのビルドにも、ホットモジュールリプレイスメントとか、いろんなパターンがありますよね。それもオプションで渡すの? というようなことを考えると、なんだかなと思った。
そのへんをどうやって伝えようかと思ったときに、コレコレがなにかを複雑にすることを「〇〇をコンプレクトする」という言葉で説明するといいんじゃないかなと。(Rich Hickeyの)プレゼンテーションにあったんですけど。「それコンプレクトするんじゃないの?」って、便利ですよね。
今日の話を踏まえると「それ、創味のつゆになってるんじゃないですか?」って言い方が使えるかな。
(会場笑)
結局、どうしたか。スクリプトを書くのだけはどうしても嫌だったので、スクリプトよりはメンテが容易なREADMEを書きました。
容易というか、動作確認とかはそれぞれのアプリケーションの手順を書くだけだし、その手順自体はそれぞれのアプリケーションで確かめられるというイメージです。
READMEをとにかく書く。いいところとしては、いろんな手順が隠蔽されない。さっきの「隠蔽しない」ですね。そして、これだけダーって書いたら、そんなに複雑なセットアップ手順がそもそも問題だということに気づくわけです。じゃあそこを直していこうという気持ちにもなれる、と思います。
まとめです。
SimpleとEasyは違う。ちゃんと区別して考える。Easyを選ばなければいけないときはあるけれど、それはトレードオフであって、なにかを犠牲にしている。
そこをちゃんと認識したうえで、できればSimpleを選択したい。自動的にシンプルになるわけではないです。選びとっていきたい。できるところから、SimpleにしていけるところはSimpleにしていこう、というふうにやっていきたいと思っています。
僕らが作っている「北欧、暮らしの道具店」というサイトも、ECだと思っていたらいきなり短編ドラマを作り始めたり、どんどん変わっていくわけですね。
これに対して、僕らはどう対応していくか。
もちろん(新しいコンテンツは)楽しい話なので歓迎ではあるんですけど、システムを作る人間として、それに対応していかなければいけない。Simpleにしていくのも、なかなか終わらない道です。結局、Laravel MixはWebpackへ移行しようかなと考えています。
知ってる人、いますかね? 昔、日産MOCOというCMで「あなたはあなたが選んだものでできている」というコピーがありました。
言い替えるのであれば「あなたが作ったものは、あなたが選んだものでできている」。こういうふうにするかしないかはあなたの選択ですよ、ということを肝に銘じて、仕事していきたいと思います。
以上です。ご清聴ありがとうございました。
(会場拍手)
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.12
今までとこれからで、エンジニアに求められる「スキル」の違い AI時代のエンジニアの未来と生存戦略のカギとは
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05