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
1.1k
はてなインターンシップ2024 RDBMS ブートキャンプ講義資料
hatena
0
860
はてなインターンシップ2024 フロントエンドブートキャンプ講義資料
hatena
0
790
はてなインターンシップ2024 コンテナ講義資料
hatena
0
870
はてなインターンシップ2024 コンテナオーケストレーション講義資料
hatena
0
780
はてなインターンシップ2024 インフラ講義資料
hatena
0
800
はてなインターンシップ2024 AI 講義資料
hatena
0
790
はてなインターンシップ2024 ブログライティング講義資料
hatena
4
2.9k
はてなリモートインターンシップ2023 Web, HTTP 講義資料
hatena
1
490
Other Decks in Programming
See All in Programming
From Translations to Multi Dimension Entities
alexanderschranz
2
130
わたしの星のままで一番星になる ~ 出産を機にSIerからEC事業会社に転職した話 ~
kimura_m_29
0
180
KMP와 kotlinx.rpc로 서버와 클라이언트 동기화
kwakeuijin
0
150
Recoilを剥がしている話
kirik
5
6.8k
Effective Signals in Angular 19+: Rules and Helpers @ngbe2024
manfredsteyer
PRO
0
140
Spatial Rendering for Apple Vision Pro
warrenm
0
110
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
5
660
create_tableをしただけなのに〜囚われのuuid編〜
daisukeshinoku
0
260
The Efficiency Paradox and How to Save Yourself and the World
hollycummins
1
450
Zoneless Testing
rainerhahnekamp
0
120
Security_for_introducing_eBPF
kentatada
0
110
今年一番支援させていただいたのは認証系サービスでした
satoshi256kbyte
1
260
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
520
For a Future-Friendly Web
brad_frost
175
9.4k
Into the Great Unknown - MozCon
thekraken
33
1.5k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
How to Think Like a Performance Engineer
csswizardry
22
1.2k
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Imperfection Machines: The Place of Print at Facebook
scottboms
266
13k
Building Applications with DynamoDB
mza
91
6.1k
Faster Mobile Websites
deanohume
305
30k
Done Done
chrislema
181
16k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
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など • ビューまで考慮したレイヤー化アーキテクチャ • クリーンアーキテクチャなど !"
まとめ • アーキテクチャとは • 後戻りできない決定事項 • 優れたアーキテクチャ • 開発しやすい •
運⽤しやすい • アーキテクチャの選択 • マクロな視点とミクロな視点 • 規模や想定する運⽤年数に応じて決める !"