デブサミ2023夏②

# アーキテクチャの見直す兆候
・開発に異様に時間がかかる(これは1機能あたりのリードタイムなどを計測してチェック)
・構成管理に労力がかかる
・開発の１割以上、依存関係による影響範囲とかの調査に充てている
・障害の影響範囲が大きくて、１箇所間違うとシステム全体が止まってしまう
・うまく行かないってなった場合に前のverとかに容易にロールバックできない
・デプロイに時間がかかる(10分以上とか)

なんてことが起きだしていたら、アーキテクチャが腐り始めてるせいを疑った方がいい。
なんなら事前にこの値を超えたらアーキテクチャ再検討とかっていう指標を決めておく。
たとえば、
１つの機能あたりにかかる保守の時間(リードタイムとMTTR)の基準値を１日
バッファ持たせて1～1.2日とかっていう風に決めていた場合に、
ある時から徐々に日数が増加してきてたら、保守性という観点では構造の見直しが必要かもねっていう段階。

## 上記が起きやすいモノリシックアーキテクチャの問題点
ここでいうモノリシックは、
モジュラーモノリスとかではなくて、よくある密結合なモノリシックな場合のこと。

<img width="500" alt="スクリーンショット (192).png (1.0 MB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/02/135213/a117467f-0076-40a4-9425-bf5cd8eae4c9.png">

ただし、コンテキスト境界を最初に時間かけて明らかにした上で、
DBは共有しているものの構成要素同士は疎結合になっている
モジュラーモノリスを選定しておけば、この問題は緩和されやすいことが分かってる。
なぜならプロセス面においては、境界付けられた明確なコンテキストによって、
モジュール同士が疎結合になっているから。


## マイクロサービスアーキテクチャの特徴
<img width="500" alt="スクリーンショット (193).png (709.4 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/02/135213/2f0d3283-5cb1-4121-9e3b-514af9ccde12.png">

ver管理も１つ１つのサービスのとこで見ていけばいいってなるので、
ver管理もモノリシックよりは楽。
ただし、データのコンテキスト境界ってとこがこのアーキテクチャの悩ましいとこ。
データの整合性だの、所有権だの、サーガだの。

# アンチパターン

## 最初からフルフルでマイクロサービスアーキテクチャ
これは外部のワークショップなどでも聞いた話だが、
いま旬なアーキテクチャだからっていう理由でマイクロサービスアーキテクチャにして、
結局サービスを分割したがために、アジリティが低下してしまい、
２年かけてモノリシックに戻したという事例。こういった話はよく聞く。
その原因は、自分でインタビューした約30件のデータを集計すると、
すべて見事に以下のいずれかに分類された。

### プロセス面でのコンテキスト境界の見誤り
そもそも論、コンテキスト境界がまだ不確実であったにもかかわらず、
一気にマイクロサービスぽい量子としてに切り出して、
元に戻すことが求められるというリスクを考えての可逆性を全く考えていなかったこと。
適切な境界ではないがゆえに、分散モノリス化してしまう現象である。

これを回避するために、戦術的フォークを用いて無駄な機能を削り、
その上で、コンポーネントベース分割をすることで、
粒度を揃えながら疎に結合しあった境界付けられたコンテキストを探す。
それによってまずはモジュラーモノリスの構造を目指すことが最初の第一歩。

### データのコンテキスト境界の見誤り 
データ面の境界付けられたコンテキストを一般に【データドメイン】という。
このデータドメインごとにまずは安定した境界か確信することなく、
一気に物理的にも分割してしまったパターン。
こりゃ分割にも時間がかかるのに、元に戻すのには相当苦労する。

論理的だとしても、データ構造の間に境界を定義して分けると、
まずはキー制約を外したりなんだの苦労するし、
途端に外部キー制約などによる、リアルタイムなデータ整合性が困難になる。
基本は、データドメインごとに分けた場合には、データは結果整合性が基本になる。
これを踏まえてのビジネス要件の再検討をしていない状態で、
無理に境界を引いてしまったケースでは、うまく行っていない。

### 組織構造自体がマイクロサービスに対応できていない
仮に上記２つの問題を突破できていても、ここが問題なケースはよく目にする。
コンウェイの法則という力学によって、
システムアーキテクチャは組織構造の影響をもろに受けてしまう。
システムアーキテクチャは、マイクロサービスにしたけれども、
組織自体の構造を変えることなしに、システム内だけマイクロサービスにした場合には、
分散化されたことによって、逆にパフォーマンスが下がってとかっていう問題が起きる。
逆コンウェイ法則や、組織自体がマイクロサービスに対応できるほど、
エンジニアリングが成熟していない状態でマイクロサービスにしようとした結果、
恩恵よりもデメリットが上回って発生してしまう現象。


## プロジェクトという単位で区切ってしまう
プロジェクトは終わりのあるものなので、継続的な改善習慣ではなく、
非連続な一時的な改善イベントで終わってしまいがち。
なので、そもそもアーキテクチャ改善に終わりを作ってはいけない。

<img width="500" alt="スクリーンショット (194).png (176.8 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/02/135213/480b5a69-083c-4c21-b60e-a493f09fdff0.png">

図で言うとアーキテクチャを更新した直後は、
初期不具合直したり、新しいアーキテクチャになれるのに時間かかるから
最初は少し効果が下がる。
そこから徐々に改善した効果が実感され始めていって、
効果体験フェーズにおいてもうプロジェクトが終了してしまってると、
外部要因の変化とかに取り残されてる状態だからどんどん劣化の引力に引きずられ効果が減少していくっていう曲線を辿りがち。

結果、うまくいった点だけをステークホルダーやユーザい主張することに時間取られて、
新しいアーキテクチャの改善できる問題部分に目を向けられなくなりやすい。

### 失敗させづらい
プロジェクトは成功させないといけないっていう制約から、失敗を許されない。
理想のアーキテクチャは創っては検証して、小さな失敗から沢山学んで
また仮説検証サイクルっていう繰り返しなのに、その知見もたまりにくい。
失敗の原因追及は、成功した際の原因追求よりもしやすいのに、
なぜ失敗したのかというアンチパターンの知見がたまらないから、
また同じような失敗をしやすいし、結果的に大きな失敗を生む原因にも繋がる。
【目の前の小さな失敗を許容して、大きなリスクを避けるのか？
それとも目の前の小さな失敗を許さずに、大きなリスクにぶつかるか】

### 学習知見がたまりにくい
プロジェクトの成功＞＞学習になってしまい、知見が溜まりにくい。
さらに挑戦がなくて、無難に成功できそうな道を選びがちだから、
DXプロジェクトとかだと、特になにも革新的なものが生まれず、
ありきたりなものしか出てこないみたいな現象に繋がる。

### 根本原因の追究ができない
作業効率低下させてる直接原因はたしかにアーキテクチャであるが、
そのアーキテクチャを劣化させてる要因は何なのか？
て話には、なかなか議論されない。
結果、この根本原因がうやむやにされたまま、
何をどうつくるかばかりにフォーカスが当てられてしまい、
短期的な視点では「嬉しい」ていう効果が出ても、徐々に悪化していく現象が止められない。

一旦の区切りっていう意味でゴールを設けても、連続的に設定すべき。

## 一度に沢山盛り込みすぎるんはNG
あれもこれもやりたいっていうステークホルダーの要求に明確に優先順位つけて
時にはリスクの説明すること。
予算はギリギリまで使い込むんでなく、リアーキテクティングなどのバッファも盛り込む。
ステークホルダーマネジメントによって、
優先順位の低いステークホルダーの要求はいっそのこと考えない。

# 登壇者の主張
改善活動は、プロジェクトのような非連続の一過性イベントではなくて、日常の風景にしていく。
これはアーキテクチャだけではなく、報告会などのイベントでも然り。

あと、やることとやらないことを明確にパレート法則に従って、
「この２割が大半の価値を生む、あとはやらない」と無駄な開発を避ける。
なんでもOKとしていくと、タスクもただ増えて負債がどんどん増えていく。

しかもこれを意識してないと、特に価値も生んでいないものの発生させるリスクなどに
向き合う無駄なコストまでどんどん増えていきがち。

受託現場では、モノリス構造に進む引力が働きがち　と主張されていた。
これは今まで体験した案件ですでに重々納得できる。

# 良い開発地盤の構築
・開発者と発注者の距離を密に近づける
・日常に改善活動を取り入れる
この前者はすでにAtlaにて実体験済。

・(発注者も巻き込んでの振り返りサイクルはなかなか難しいので)自分たちの
小さな振り返りサイクルを行う(KPT、5回なぜetc)
・そもそもの課題意識やモチベーション

## ドメイン知識の獲得
・ベターなアーキテクチャ設計にはドメイン知識が不可欠
・現状のビジネス状況と今後の予定ビジョンを聞き出す
これらはアーキテクチャ特性などの優先順位の重要なインプットになるからである。


## よりよいチームにする
実際にシステムを使う人の存在と、そいつの声を聞く。
共通の目標をもったチームは強い。(スクラム)
１年後にこうなっていたいから、そのためには半年後にこうなっているべきだよねっていう
バックキャスト思考が必要。

# アーキテクチャでも小さくサイクル
<img width="500" alt="スクリーンショット (195).png (384.3 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/02/135213/41cc8950-9426-4d66-b540-a825cc8f690b.png">

もっとも分離しやすく、かつリスクの少ない箇所からまずは分割してみる。
その際に「分割することでこのくらいのコストがかかるが、それを上回るだけのこのくらいのリターンが得られる」
というリターンを推論した定量的にでも出しておく。(800～1200程度みたいに)
さらに分割したことによる効果検証を必ず行うこと。
そして、この800～1200に収まってたら自分たちの立てた仮説はいったん正しいものとし前に進む。
もしも収まってなかったら、なんで誤差が出たのだろうかという原因探索を事実データをもとに必ず行う。
これも１回で原因追及ができるわけではなく、あくまでも仮説なので、継続して回数重ねて改善していくことになる。
これをやっていくとどんどん成果の質も向上していくし、
メカニズムも明らかになっていくので、結果的にアーキテクチャもチームも並行して進化しやすい。
(※　この原因探索含めた仮説検証には、推論技法、因果関係モデルの考え方がマスト)