Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
はてなリモートインターンシップ2023 ソフトウェアアーキテクチャ講義資料
Search
Hatena
October 18, 2023
Programming
0
340
はてなリモートインターンシップ2023 ソフトウェアアーキテクチャ講義資料
https://hatena.co.jp/recruit/intern/2023
Hatena
October 18, 2023
Tweet
Share
More Decks by Hatena
See All by Hatena
はてなインターンシップ2024 HTTP, Web, API 講義資料
hatena
0
900
はてなインターンシップ2024 RDBMS ブートキャンプ講義資料
hatena
0
700
はてなインターンシップ2024 フロントエンドブートキャンプ講義資料
hatena
0
630
はてなインターンシップ2024 コンテナ講義資料
hatena
0
690
はてなインターンシップ2024 コンテナオーケストレーション講義資料
hatena
0
620
はてなインターンシップ2024 インフラ講義資料
hatena
0
640
はてなインターンシップ2024 AI 講義資料
hatena
0
620
はてなインターンシップ2024 ブログライティング講義資料
hatena
3
2.2k
はてなリモートインターンシップ2023 Web, HTTP 講義資料
hatena
1
480
Other Decks in Programming
See All in Programming
Arm移行タイムアタック
qnighy
0
310
TypeScript Graph でコードレビューの心理的障壁を乗り越える
ysk8hori
2
1.1k
C++でシェーダを書く
fadis
6
4.1k
ヤプリ新卒SREの オンボーディング
masaki12
0
130
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
170
現場で役立つモデリング 超入門
masuda220
PRO
15
3.2k
シールドクラスをはじめよう / Getting Started with Sealed Classes
mackey0225
4
640
ペアーズにおけるAmazon Bedrockを⽤いた障害対応⽀援 ⽣成AIツールの導⼊事例 @ 20241115配信AWSウェビナー登壇
fukubaka0825
6
1.9k
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
910
Snowflake x dbtで作るセキュアでアジャイルなデータ基盤
tsoshiro
2
520
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
100
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
1
100
Featured
See All Featured
Mobile First: as difficult as doing things right
swwweet
222
8.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
840
How To Stay Up To Date on Web Technology
chriscoyier
788
250k
Scaling GitHub
holman
458
140k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Making the Leap to Tech Lead
cromwellryan
133
8.9k
Happy Clients
brianwarren
98
6.7k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.2k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
93
16k
Why Our Code Smells
bkeepers
PRO
334
57k
Side Projects
sachag
452
42k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
410
Transcript
ιϑτΣΞΞʔΩςΫνϟ #hatenaintern)*)+ !
アーキテクチャとは • 構造? • ソフトウェアに物質的な構造はそもそもなくない? !
建築の場合: 構造設計 • そもそも建つために必要 • 物理的に⽴たないものは建たない • 施⼯性の確保 • 安全のため
• 建てたあと倒壊したら困る • 法令等で基準が定められている • コストのため • やり直しは⼤変 !
なぜ構造設計が必要か ミスったときのリスクが⼤きいから !
構造設計はいつ必要か 不要 個⼈で⽝⼩屋を建てる - そもそも作りが簡素で考えることが少ない - 壊れたらまた建てたらよい - ミスったら作り直せばよい 必要
⼤規模⼯事で⾼層ビルを建てる - 複雑だから闇雲には建たない - 壊れたら⼈命に関わる - 作り直すには莫⼤なコストがかかる - e.g. 耐震補強⼯事 - ⻑年耐えてほしい !
ソフトウェアでも同じ! !
ソフトウェアのアーキテクチャとは • 簡単には変更できない決定事項 • ⼈間が⾒出す抽象的なもの • フラクタルにどこまでもブレークダウン可能 • 開発者の共通理解として主観的に存在 !
ソフトウェアに求めること • 価値提供し続けるために開発‧運⽤コストを低くしたい • 機能追加に耐える • ハードウェアリソースの効率がよく可⽤性が⾼い • 環境変化に迅速に対応したい •
作って終わりではない !
優れたアーキテクチャのための指針 開発しやすい • 疎結合で凝集性が⾼い • 認知負荷が低い • 変更箇所が局所的 • ⼀度に関わる⼈数が少ない
• 開発からリリースまでが短い 運⽤しやすい • パフォーマンス‧スケーラビ リティ • 耐障害性 • 可観測性 !
Webサービスのアーキテクチャ !"
システムの外形的アーキテクチャ • モノリス • モジュラーモノリス • マイクロサービス !!
モノリス !"
モノリスの特徴 • プロダクト全体が1つのコードベース • 単⼀のWebアプリケーション‧単⼀のDB • シンプル • 開発時に触るリポジトリは1つだけ •
デプロイが必要なのは1つのアプリケーション !"
モノリスが複雑化すると - 技術⾯ 実はいろいろなコンポーネントがある !"
モノリスが複雑化すると - 機能⾯ いろいろな機能 !"
モノリスが複雑化 すると - 組織⾯ 1つのコードベースに複 数チームが関わる !"
複雑化したモノリスの課題 • 雰囲気の違ういろんなコードが混ざり合ってしまいがち • 「⼤きな泥だんご (big ball of mud)」 ['OP
Foote & Yoder] • チーム間のコンフリクト • 変更箇所のコンフリクト • リリースタイミングのコンフリクト • 技術スタックが1つに縛られる • e.g. 機械学習は適した⾔語でやりたい • デプロイパイプラインに無駄が多い • e.g. Webサーバとバッチは別でデプロイ • 不要なコンポーネントのテストも毎回必要になる !"
モジュラモノリス • 性質の異なる単位ごとにコンポーネントを分ける • コード上は最上位のディレクトリを分けるなどする • コンポーネント間は限られたインタフェースでのみやりとり !"
モジュラモノリスで課題は解決するか? • 雰囲気の違ういろんなコードが混ざり合ってしまいがち • コンポーネントごとに切り分ける • チーム間のコンフリクト • チームごとに担当コンポーネントを分ける •
技術スタックが1つに縛られる • コンポーネントごとに技術スタックも分けてしまう? • → もはやリポジトリが同じだけで単⼀のコードベースとは呼べなくなる • デプロイパイプラインに無駄が多い • コンポーネントごとにパイプラインを分ければ解決? • → もはやリポジトリが同じだけで(ry !"
マイクロサービス !"
マイクロサービスの特徴 • 1つのプロダクトを複数サービスの連携により実現 • 性質の異なるコンポーネントごとにサービスを分ける • 各サービスは独⽴して開発‧リリースできる !"
サービスの分け⽅の基準 • ドメインの境界で分ける • e.g. 課⾦機能と投稿画⾯と閲覧 機能 • 再利⽤性の⾼いものを分ける •
e.g. アカウント基盤 • 技術スタックで分ける • e.g. 機械学習 • 開発のライフサイクルの違いで分 ける • e.g. ネイティブアプリ向けAPI 層 • BFF (Backend For Frontend) • 組織構造に合わせて分ける • e.g. ユーザグロースチームと CMS基盤チーム !!
サービス間通信のパターン 同期的 • サブルーチン呼出しが別サービスへのリクエストになるだけ • リクエスト先のサービスが⽌まるとリクエスト元もエラーを返すしかなくなる !"
サービス間通信のパターン ⾮同期的 • 呼出し元はメッセージを送信 • レスポンスを待たない • 呼出し先はメッセージを受信したら処理する • サービス同⼠の独⽴性が⾼く⼀部の障害が全体に波及しにくい
!"
サービス間通信のパターン ⾮同期的: Pub/Subモデル • 送信元は誰が受信するか知らない !"
サービス間通信のプロトコル 同期的 • RPC • gRPCなど • サブルーチン呼出しに近い • REST
• GraphQL • etc. ⾮同期的 • AMQP • RabbitMQなど • 独⾃ • Apache Kafka • Amazon SQS • Google Cloud Pub/Sub • etc. !"
サービス間の整合性の取り⽅ CAP定理 分散システムにおいて以下の3つをすべて保証することはできない • Consistency (⼀貫性) • Availability (可⽤性) •
Partition-tolerance (分断耐性) !"
サービス間の整合性の取り⽅ 結果整合性 (eventual consistency) • ⼀時的に古いデータが参照されることを許容する • 最終的には不整合のない更新内容が反映される !"
サービス間の整合性の取 り⽅ Sagaパターン • ⻑⼤なトランザクションを分割するパターン • マイクロサービスではサービスごとのトランザクシ ョンに分解 • サービスA,
B, CのトランザクションTG, TH, TI • トランザクションには失敗時に元の状態に戻す補償 トランザクションを⽤意 • TG, TH, TIに対してCG, CH, CI • TIが失敗したらCHとCGを実⾏ !"
サービス間の整合性の取り⽅ TCCパターン (Try-Confirm-Cancel) • Tryフェーズ • 各サービスで仮登録状態にする • Confirm/Cancelフェーズ •
すべてのサービスでTryが成功したらConfirmリクエスト • いずれかのサービスでTryかConfirmが失敗したらCancelリクエスト !"
サービス間の整合性の取り⽅ 羃等性 (idempotency) • 同じ操作を何度やっても同じ結果になる性質 • サービス間のリクエストは羃等が望ましい • 失敗したらリトライしたい •
失敗と成功レスポンスの受け取り失敗は厳 密には区別できない • e.g. リクエストの処理中にネットワーク が切断した場合 ⽅法 • (a) リクエストする側が操作にIDを振っておく • 処理する側は処理済みのIDは覚えておく • 過去に処理済みのリクエストは無視する • (b) 差分ではなく最終状態にバージョンをつ けてリクエスト • 古いバージョンによる上書きは無視する !"
ここまでのまとめ • アーキテクチャとは • 後戻りできない決定事項 • 外形的に優れたアーキテクチャ • うまい分割 •
ドメインや技術スタックなど • リードタイム短縮 • ⼈と組織が重要 • 分散システムにすると考えることは増える • どこまで頑張るかは規模や想定する運⽤年数による !"
システムの内側のアーキテクチャ !!
よりミクロな視点 • うまい分割 • 認知負荷を下げる • 重要な箇所が些細な変更に影響されない • スピード •
テストしやすい → 変更しやすい !"
ビジネスロジックとビュ ーの分離 MVC • もともとはデスクトップGUIアプリのアーキテクチャ • M : モデル •
ビジネスロジックを表現する • データとその操作や永続化⽅法 • V : ビュー • モデルのデータをUIとして表⽰する • C : コントローラ • ⼊⼒イベントをモデルに渡す • モデルの変更がビューに反映されるように繋ぐ !"
ビジネスロジックとビューの分離 MとVが分離されていないと何が困るか • ビューの各所にロジックが偏在 • ロジック(仕様)を変えるにはビューのいろんな箇所の変更が必要 • ロジック(仕様)が正しいかテストするのにビューのテストが必 要 •
⾒せ⽅を変えただけでロジックが壊れる !"
ビジネスロジックのさら なる分解 レイヤー化アーキテクチャ • ビジネスロジック = ドメインモデル + ユースケース •
ドメインモデル • 登場⼈物とその関係 • e.g. 「著者」は「記事」を投稿できる • e.g. 「記事」には「カテゴリ」を設定できる • ユースケース • ユーザの体験としてどのようなドメインモデルの操作が可能か • e.g. ユーザは「著者」として「カテゴリ」設定した「記事」を投稿できる • 「カテゴリ」がまだ存在しなければ作成される • 永続化⽅法などは実装上の都合 (インフラ層) !"
依存関係逆転の原則 MVCの場合 • ビュー ← モデル ではない • モデルが⾃⾝の変更を能動的にビューに伝える =
モデ ルがビューに依存 • モデルのテストにビューが必要になってしまう • 依存を逆転する⽅法 • (a) モデルに変更があったらイベントを発⽕するだけ • フロントエンドで典型的なアプローチ • (b) 変更後のモデル状態をコントローラがビューに渡 す • バックエンドで典型的なアプローチ !"
依存関係逆転の原則 レイヤー化アーキテクチャの 場合 • ドメイン層 → インフラ層 ではない • ドメインロジックは永続化⽅法によらない
• e.g. データベースをMongoDBからMySQLに変えて もドメインロジックは不変 • 依存を逆転する⽅法: リポジトリインタフェース • モデルの変更の反映はリポジトリを介する • リポジトリのインタフェースはドメイン層に置く • リポジトリの実装はインフラ層に置く !"
もっと細かいアーキテクチャ • MVCのビューまわりの解像度を上げる • MVVMやMVPなど • ビューまで考慮したレイヤー化アーキテクチャ • クリーンアーキテクチャなど !"
まとめ • アーキテクチャとは • 後戻りできない決定事項 • 優れたアーキテクチャ • 開発しやすい •
運⽤しやすい • アーキテクチャの選択 • マクロな視点とミクロな視点 • 規模や想定する運⽤年数に応じて決める !"