Slide 1

Slide 1 text

歴史と現在から考えるスケーラブルなソフトウェア開発のプラクティス @Nikkei Tech Talk, Dec. 2024 1

Slide 2

Slide 2 text

日経のエンジニア組織について 日経には 80人以上のエンジニア・データサイエンティストが所属するエンジニア組織がある エンジニア組織は Engineering Vision で組織の指針を定めている (誤解を恐れず)簡潔にまとめると エンジニアリングによって事業やジャーナリズムに貢献すること それを支えるやりがいのある環境を自ら作ること が指針 Engineering Vision -- 日経のエンジニア組織がどのような開発組織を目指すかの指針 2

Slide 3

Slide 3 text

ビジョンと実際の乖離 ビジョンと実際には乖離がある 技術的な側面に限っても 古い基盤の影響範囲の大きさ 必ずしも理想的とはいえない設計・技術スタック 複雑性、開発リソースや技術のトレンドなどの観点 チームや部署を跨いだ意思決定のプロセス 乖離を埋めるため システムの長期的な健全性と事業成長の好循環 が欠かせない 原理・原則への準拠がその鍵 3

Slide 4

Slide 4 text

(このトークにおける)定義 システムの長期的な健全性 原理・原則 4

Slide 5

Slide 5 text

定義 : システムの長期的な健全性 サービスの質(※ )を保つため以下の要件が実現されている チーム内・サービス内での安全・迅速な変更・改善が可能 チーム間・サービス間での互換性の維持と変更の伝播が可能 ※ 標準・仕様への準拠、依存の更新や脆弱性対応、パフォーマンスやオブザーバビリティなど 5

Slide 6

Slide 6 text

長期的な健全性の大部分はソフトウェアの長期的な「構造の価値」 「変更容易性」ともいえる. ソフトウェアには2種類の価値がある。 「振る舞いの価値」と「構造の価値」だ。そし て、後者の方が価値が大きい。なぜなら、それがソフトウェアをソフトにする価値だか らだ。 「クリーンアーキテクチャ」15章 6

Slide 7

Slide 7 text

定義 : 原理・原則 我々はマイクロサービスを意識したアーキテクチャを選んでいるので、ここではマイクロサ ービスの原理・原則を扱う 自治(autonomy): クロスファンクショナルなチーム編成. チーム間の独立性. 疎結合(loose coupling): サービス間の独立性・実装詳細の隠蔽 分離(isolation): ストレージの分離 耐障害性(fault tolerant): 障害の局所性 横断的関心ごとの分離(offload cross cutting concerns) 参考 Microsoft: Microservice architecture style #Best practices SalesForce: 6 Fundamental Principles of Microservice Design 7

Slide 8

Slide 8 text

日経のアーキテクチャ・組織構成 マイクロサービスを意識したアーキテクチャ 職能単位のチーム分割(※ ) web チーム、モバイルチーム、バックエンド・API チーム・イノベーションラボ 一部ドメイン単位のチーム分割 SREチーム・認証基盤(NID)チーム ※ ドメイン単位でチームが組まれることもあるが、組織上のチームの分割単位は職能別 8

Slide 9

Slide 9 text

うまくいっている部分 横断的関心ごとの分離 オブザーバビリティ、メトリクスの収集、デプロイ基盤、認証認可、分析などは共通のログ 基盤、 Vessel(デプロイ基盤)、 NIDや行動ログ計測基盤(Atlas)が担っている スケールアウト マイクロサービスのコンポーネント単位でスケールアウトするので急なトラフィックの増大 に対処できる 耐障害性 個々のサービスは別々のウェブアプリケーションとしてデプロイされているため、一部のサ ービスが落ちても影響範囲は限定的で復帰可能 9

Slide 10

Slide 10 text

課題: 自治・疎結合・分離 多数の層から構成されているが内部の実装を隠蔽する層が少なく、各層が保証する仕様 も曖昧 (下流から見ると)自身の仕様を決めるには、利用する API だけでなくその上流のサ ービス群まで調査しなければならない (下流から見ると)重要なロジックが特定のアプリケーションに埋め込まれていて、 容易に検証できない (上流から見ると)上流の変更で下流のサービスが(予期しない)影響を受け、その影響 範囲が容易に特定できない (上流から見ると)下流に対して変更を伝播する仕組みがなく、古い API を互換性の ために残さないといけない (上流から見ると)さらに上流の一部のリソースはコントロールできない 10

Slide 11

Slide 11 text

マイクロサービス開発で直面する選択肢 1. サービスはそのサービスが保証できる最低限度を仕様として利用者に公開する 2. サービスはそのサービスが依存するものの機能を隠蔽せず利用者に公開する 11

Slide 12

Slide 12 text

1 2 利用者の利便性 利用者は実装詳細の一部にしか にアクセスできない 利用者は実装詳細の(ほぼ)全て の機能にアクセスできる 提供者の(短期的な)工 数 多い. データのモデリング・バ リデーション・変換などが必要. 少ない. データをプロキシする だけ. (利用者が)機能開発で 検討すべき内容 提供側の API の仕様 提供者と、提供側が依存する サービス群の実装 (提供者が)機能の変 更・廃止で検討する内 容 自身が公開する仕様との互換性 利用側のサービス群(より下流 の依存も含む)の実装への影響 将来の変更の影響 小さい 大きい 12

Slide 13

Slide 13 text

チームを跨ぐとより問題が複雑になる 多くのチームが 2 を選ぶと 上流のサービスの変更はサービスを跨いで波及する可能性があり安易に変更できない 下流のチーム内でサービスが増えたら上流のチームの下流への責務は増える ※ 新しい開発者は自分たちのチームのサービスのデータの性質を知るために 他のチームの サービスの実装を遡らなければならない ※ 変更が(インターフェースの互換性ではなく)下流のサービス群を壊さないことを検証・保証 しなければならない 13

Slide 14

Slide 14 text

チーム内・チーム間の両方の生産性 以下の例では必ずしも生産性が上がったとはいえない 提供側は頻繁に破壊的変更を入れればリードタイムを短くできるが、利用側のキャッチ アップの負担は増える 提供側の非推奨の API を使えば利用側のリードタイムは短くなるが、提供側のメンテナ ンスの負担は増える 14

Slide 15

Slide 15 text

現在の問題(再掲): 自治・疎結合・分離 横断的関心ごとはうまく扱えているが、特にチームを跨ぐアプリケーションやサービスのコ ミュニケーションに課題がある 15

Slide 16

Slide 16 text

Why? 原理・原則(ベストプラクティス)からの逸脱 プロダクトの歴史 風土・文化 原理・原則への準拠を促す仕組みの不在 16

Slide 17

Slide 17 text

マイクロサービスの原理・原則(ベストプラクティス)からの逸脱 Model services around the business domain. ... Decentralize everything. Individual teams are responsible for designing and building services. Avoid sharing code or data schemas. ... Services communicate through well-designed APIs. Avoid leaking implementation details. APIs should model the domain, not the internal implementation of the service. https://learn.microsoft.com/en-us/azure/architecture/guide/architecture- styles/microservices#best-practices 17

Slide 18

Slide 18 text

歴史的に 上流のサービス(データソース)とバックエンド以下の組織は別のチーム 個々のマイクロサービスは必ずしもクロスファンクショナルなチームによって作られて いるわけではない サービスの API は自身が守る仕様を持たず内部の実装詳細を漏らしている マイクロサービス間のイベント通知の基盤は整備されていない データの整合性を担保するため、複数のチームが共通のデータソースの実装に(暗 に)依存している 18

Slide 19

Slide 19 text

プロダクトの歴史 2010: 日経電子版創刊 2015: 日経電子版アプリ 2016: 紙面ビューアー 2016: データ分析基盤 Atlas 2022: Nikkei Prime 2024: 日経空間版 日経電子版はウェブからはじまったが、異なるデバイス(モバイル・タブレット・Vision Pro)、異なる媒体(紙面ビュワー・Prime)、データ分析やデータベース事業などの用途が発生 未来を見通すことはできないので、特定のユースケースに特化した実装が漏洩してしまうの は仕方がないことも... 19

Slide 20

Slide 20 text

風土・文化 : 「〇〇」のデータが欲しいんだけど... : この API のこのフィールドのこの部分文字列をこのルールで計算すると手に入るよ : わあ、ありがとう 20

Slide 21

Slide 21 text

仕様?実装詳細? 例の場面で次の質問に答えられる人は少ない どのチームがその機能・挙動に責任を持つ? 機能・挙動の一覧や変更履歴はどこにある? どうやって同期される? 変更の意思決定はどうやって行われる? 21

Slide 22

Slide 22 text

風土・文化 : 実装に依存するべきではないのでサービス間で仕様を決めましょう : 仕様とかよくわからないので〇〇さんがいい感じにしておいてください : その API は上流の実装の影響を受けるので非推奨です : え、これ非推奨だったの? 時間がないからそのうち直します... 22

Slide 23

Slide 23 text

技術的負債の四象限の言葉を借りると、実装に依存する意思決定は無自覚に、あるいは自覚 しながらも無謀に行われる 仕様と実装を区別していない チーム間で仕様を作り守るインセンティブがない https://martinfowler.com/bliki/TechnicalDebtQuadrant.html 23

Slide 24

Slide 24 text

原理・原則への準拠を促す仕組みの不在 ボトムアップな取り組みが多く、局所最適になりがち 仕様変更を協議する標準的なプロセス・変更の影響範囲を(機械的に)検知する手段がない (最近まで)エンジニアの評価をするのはエンジニアではなかったため、将来の負担・チー ムを跨いだ負担を抑える施策の説明が難しい メンテナンスコストや発生した技術的負債は評価指標に含まれないことが多く、アドホ ックにやって片付けないのが最適解になる 24

Slide 25

Slide 25 text

マイクロサービスに限らず、何らかの規約に従うには信頼や善意だけでは現実的ではない 「枠組み・道具」で解決すべき問題 例えば マイクロサービスを作るならスキーマレジストリ + コード生成 モバイル開発なら、マルチモジュールやレイヤードアーキテクチャ もう少し一般的にするとプラットフォームやツーリングの活用が重要 25

Slide 26

Slide 26 text

例: スキーマレジストリ + コード生成 スキーマ(仕様)が実装に先立つ 仕様を決める具体的な場所と方法が提供される 仕様の策定・変更・伝播・文書化のツールチェーンが存在する コード生成によって(企業内独自の)横断的関心ごとをカバーできる 実装に利用する技術はチーム・サービスに委ねられる 26

Slide 27

Slide 27 text

スキーマレジストリ + コード生成 大規模なスキーマレジストリ + コード生成の例 AWS: 200+ services v1: templating: https://github.com/aws/aws-sdk-java/tree/master/aws-java-sdk-code- generator/src/main/resources/templates v2: IDL + Codegen: https://smithy.io/2.0/aws/protocols/index.html GCP: 150+ services googleapis protobuf schema: https://github.com/googleapis/googleapis Discovery API: https://cloud.google.com/docs/discovery 27

Slide 28

Slide 28 text

理想的な世界 ライブラリを作るようにアプリケーションを作る 我々が普段利用するライブラリは、以下の理想的な性質を満たしている 自治 疎結合 単一責任の原則 不特定の利用者を想定した変更の意思決定 互換性維持と変更の伝播 ドキュメンテーション 28

Slide 29

Slide 29 text

理想的な世界 コード生成・配布のツーリングに投資する スキーマを管理する中央レポジトリ スキーマから生成されたコード 生成されたコードをライブラリとして配布する仕組み チーム間で仕様やプロトコルを協議し、それを実装する枠組みを作ることができる 29

Slide 30

Slide 30 text

実現可能? 「後知恵ではないか? 」といわれそうだが、 "オールドメディア" 業界でも早い段階から仕様やスキーマを決めている事例はある Guardian https://github.com/guardian/content-api-models https://github.com/guardian/tags-thrift-schema https://github.com/guardian/content-api- models/commit/161af115a65d83c6f59fb465f31334eb4083f6c9 First Commit: Apr. 1, 2016 30

Slide 31

Slide 31 text

Washington Post ANS ("Arc Native Specification") is the collection of schema documents that comprise the Washington Post's definition of "content", in so far as content is passed back and forth between systems in the Arc ecosystem of applications. https://github.com/washingtonpost/ans- schema/commit/bb0ea89b21faac45660e180af9f4f813983c28bb First Commit: Jun. 24, 2015 31

Slide 32

Slide 32 text

一方で... 仕様(≒スキーマ)がないところにあとから仕様を決めて持ち込むのは難しい. 仕様を決めるのは、提供側が利用者に対して約束をしそれにコミットすることだが、 チームを跨いだ実装への依存は守れない約束と同じ. 後付けで仕様を決めるなら、チーム間・サービス間で現実的に守れる約束を結び直すため今 まで提供していたものから細部を捨象せざるを得ない. 特に上流の一部はコントロールできないため、チーム内のリソースで代替手段は提供できな いことが多い. 漏洩していた実装に依存する利用者から見ればデグレ・破壊的変更になる. 32

Slide 33

Slide 33 text

現実的にできるアプローチは...? より上流の仕様(スキーマ)やドキュメントの整備 上流の実装とサービスが保証する責務の線引き 保証できる仕様をAPIのサブセットのスキーマとして整備する スキーマによるコード生成とライブラリ配布・普及 上流の実装を安易に漏洩しない&上流の実装に意図せず依存しない文化の醸成 33

Slide 34

Slide 34 text

日経の制度・取り組み 長期的な目標を支援・評価する制度 エンジニアリングビジョン賞 20% ルール EM による評価 34

Slide 35

Slide 35 text

日経の制度・取り組み 技術的な取り組み コードの自動生成ツールやワークフローの検証(by @me) protobuf からコード生成・ライブラリとして配布・self-host renovate で更新伝播 smithy スキーマから API クライアントや型定義の自動生成 モノレポ統合により複雑なマイクロサービスの開発を単純化するアプローチ 草の根スキーマ改善活動 35

Slide 36

Slide 36 text

まとめ 一般的なソフトウェア開発や採用したパラダイムの原理・原則を守り、チーム内・チー ム間での高い生産性を保つことが長期的なシステムの健全性維持や事業成長につながる 原理・原則からの逸脱は生産性、ひいてはシステムの長期的な健全性と事業成長を損な うが、無自覚・無計画に起こりがち 36

Slide 37

Slide 37 text

原理・原則からの逸脱を防ぐ仕組みを作ることが標題の「プラクティス」であり、その ための手段としてツーリングやプラットフォームがある 初期の労力・時間の投資が複利で効いてくるが逆もまた然り 37