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
780
はてなインターンシップ2024 ブログライティング講義資料
hatena
4
2.9k
はてなリモートインターンシップ2023 Web, HTTP 講義資料
hatena
1
490
Other Decks in Programming
See All in Programming
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
120
わたしの星のままで一番星になる ~ 出産を機にSIerからEC事業会社に転職した話 ~
kimura_m_29
0
180
テスト自動化失敗から再挑戦しチームにオーナーシップを委譲した話/STAC2024 macho
ma_cho29
1
1.3k
複雑な仕様に立ち向かうアーキテクチャ
myohei
0
170
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
1
120
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
110
生成AIでGitHubソースコード取得して仕様書を作成
shukob
0
310
MCP with Cloudflare Workers
yusukebe
2
220
プロダクトの品質に コミットする / Commit to Product Quality
pekepek
2
770
Итераторы в Go 1.23: зачем они нужны, как использовать, и насколько они быстрые?
lamodatech
0
710
急成長期の品質とスピードを両立するフロントエンド技術基盤
soarteclab
0
930
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
150
Featured
See All Featured
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.4k
A Modern Web Designer's Workflow
chriscoyier
693
190k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Site-Speed That Sticks
csswizardry
2
190
Practical Orchestrator
shlominoach
186
10k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.9k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5k
Automating Front-end Workflow
addyosmani
1366
200k
Adopting Sorbet at Scale
ufuk
73
9.1k
Unsuck your backbone
ammeep
669
57k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
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など • ビューまで考慮したレイヤー化アーキテクチャ • クリーンアーキテクチャなど !"
まとめ • アーキテクチャとは • 後戻りできない決定事項 • 優れたアーキテクチャ • 開発しやすい •
運⽤しやすい • アーキテクチャの選択 • マクロな視点とミクロな視点 • 規模や想定する運⽤年数に応じて決める !"