私たちは、受注管理システムと在庫管理システム(WMS)を統合したクラウドアプリケーション「ロジレス」の提供を行っています。
ロジレスの利用者は、ECサイトを運営する事業者さんと、その事業者さんの商品在庫を管理し、出荷する業務を請け負う物流倉庫さんに大別されます。
サービスの開始から3年ほどが経ち、いまでは日々たくさんの方々にご利用いただいていて、私もとても嬉しいのですが、
弊社も多くのスタートアップと同様、めちゃくちゃ少人数でこのプロダクトを運用しています。
しかも、受注処理から出荷までの一連の流れをすべて一元的に処理するシステムである特性上、なんらかの理由でサービスが提供できなくなった場合の影響範囲がめちゃくちゃデカいという特徴もあります。EC事業者さんはお客様に納期をお約束しており、一方でヤマト運輸などの配送会社さんには締め時間(当日出荷可能な最後の時間)があるからです。
幸い、サービス開始からこれまで大規模な障害は発生していませんが、少ない人数で、プロダクトの開発、運用、保守を行うにあたって気を付けていることをまとめてみようと思いました。
(1) リスクを評価する
少人数のチームでシステムを開発/運用するうえで、私が最も大事だと考えることは致命的な障害を起こさないことです。
当たり前といえば当たり前なのですが、私のなかでは次のように分類しています。
- 致命的なトラブル - システムが完全に使えない/データを復元できない
- それ以外のトラブル - 一部の機能は使える/データはあとから復元できる
少人数で開発する以上、トラブルをすぐに検知し、修正できる体制を維持できるのであれば、ある程度のトラブルは覚悟してリリースしています。
一方で、ひとたび暫定的な対応で追いつけないような致命的なトラブルを起こしてしまうと、ただでさえ少ない人的リソースを莫大に消費し、開発計画を壊滅させます。もちろん、利用者の方に大変なご迷惑をおかけしてしまいます。
トラブルはないことに越したことはないですし、「軽微なバグなら利用者に迷惑をかけてもいい」と思っているわけでは決してないのですが、発生する可能性があるトラブルの規模によってリスクを正しく評価し、
リスクが高いところは手厚く、リスクが低いところはそれなりに、といったメリハリをつけた開発/運用の体制が重要だと思います。
(2) 技術的に"攻めない"
昨今のスタートアップのトレンドとは逆行するのですが、メインとなる機能には基本的に、「枯れた」技術をなるべく使用するようにしています。
枯れた、と聞くとネガティブに聞こえますが、技術の世界ではどちらかというと「古くからある技術なので不具合が出尽くしており、またその解決も終わっている」ことを指すことが多いです。つまり、ものすごい勢いで進化するこのWebの世界で、比較的安定した技術のことなのです。
最新の技術は、劇的な効果をもたらすこともある半面、問題が起きやすく、また問題が起きた時の解決策も発見されていないこともあります。
人的リソースに余裕がない時は、なるべく新しい技術に飛びつかず、使い古されたベストプラクティスがあればそちらを使うように心がけたほうが、安定した運用につながると考えています。
(3) 考えることを手放す
ロジレスはすべてのシステムインフラをAWS(Amazon Web Services)に統一しています。
また、UIはBootstrapを全面的に使用し、手を加える箇所は最小限に留めています。(意外と気付かれないです。)
ほかにもすでにプロダクトとして存在し、自社で開発する必要性が薄いもの機能は、可能な限り既存のシステムを組み合わせて使用しています。
Webサービスの開発/運用は、技術の範囲が非常に広範で、考えるべきことが膨大にあります。
そのすべてを細かに検証する時間は少人数チームにはありません。
サービスを提供するうえで、考えるべき内容をなるべく大きなブロックに切り出して、外注したり、既存のプロダクトを使ったり、あるいは外部のシステムとつなぎ合わせるなどして、自分たちはプロダクトのコアとなるロジックや、UI/UXに集中するようにしています。
(4) シンプルにする
これは、プログラムもそうですし、UIもそうなのですが、一目で構造を見通することができるシンプルなものであることにこだわりを持っています。
複雑性は悪です。明日の自分は、今日の自分よりも頭が悪い前提で、究極はなんのドキュメントも残さなくても、機能の改修や改善に、誰でも着手できることを目指したいと考えています。
とはいえ、特定の利用者からの要求や、プロジェクトを完遂するために不可欠な暫定対応で、シンプルではないものを作らざるを得ないときもあります。
そのときは、シンプルではない領域を可能な限り狭い範囲に閉じ込めるよう努力します。
複雑性は、そのまわりをどんどん浸潤します。
狭い範囲に複雑性を閉じ込め、余裕があるときにきちんと除去しておかないとプロダクト全体に悪影響が及びます。
(5) 復元できるようにする
ロジレスには在庫管理の仕組みが備わっていますが、ある商品の在庫数を正しい状態で常に表示することは、非常に難易度が高いです。
在庫はデータ上だけのものではなく物理的に移動しますし、その状態の変化を、たとえば購入者の注文などのデジタルなデータと常に関連付けておく必要があります。
在庫数が増減する要因は非常に幅広く、そのすべてをトラッキングしながら正しい在庫数を表示を維持しなければなりません。
私たちのプロダクトでは、すべての在庫数が変動するイベントをログテーブルに保存し、またほか様々なテーブルにも在庫数の断面を保管しています。
たとえ、なんらかの理由で在庫数が一時的にずれてしまったとしても、ほかのログや、在庫情報をもとに整合性を自動的に維持する仕組みがあります。
少人数のチームでは、難易度の高い機能であったとしても時間をかけて十分満足なテストを行うことが難しいケースがあります。
その場合は、ログなどの単純なデータを蓄積し、そのデータから正しい値を自動的に復元できる仕組みを用意することで、複雑な計算や出力を伴う処理を、ある程度ストレスなく開発/運用することができます。
リリースした後に、ズレを検知し、そのズレの原因を確認し、修正していけば、自然とアプリケーションの品質は上がっていきます。
(まとめ)考えることを少なく、シンプルに
私は大変遺憾ながら天才的な頭脳は持ち合わせていなかったため、
自分のような凡人でも、Webサービスを開発し、運用するための方法を模索してきました。
そのなかで得た大事なノウハウは、「とにかくシンプルに」でした。
シンプルにできない問題に直面したときは、まずはシンプルに考えられる大きさまで問題を分解し、解決できるものから順番に解決していくことが大事なのです。
(少しずつ、この記事は書き足していきたいと思います。まずは暫定。)