はじめに
ITエンジニアとして次のレベルアップのために「ソフトウェアアーキテクチャ」を勉強しようと思ってオライリー・ジャパンから出版されているソフトウェアアーキテクチャの基礎を購入しました。
自分的に重要そうな部分を忘れないように記事にしようと思います。
9章までのソフトウェアアーキテクチャの基礎知識をこの記事にまとめて、10章以降の各アーキテクチャはそれぞれの記事でまとめようと思います。
散文乱文かつ間違ったことを書いているかもしれないので、ご指摘いただければ幸いです。
ソフトウェアアーキテクトの責務
アプリケーションアーキテクチャ、ソフトスキルだけではなく、CI/CD、メトリクスなど様々な責務がある
アーキテクチャについて説明するときはシステム構造だけでは説明不足であり、以下の項目を説明しなければならない
- システム構造(モノリシックやマイクロサービスなど)
- アーキテクチャ特性(後述)
- アーキテクチャ決定
- 設計指針
アーキテクチャ決定
システムをどのように構築すべきかのルールを定める
システムの制約を形作り、何が許されて何が許さないかに関する開発チームの指針となる
設計指針
堅苦しいルールではなくガイドライン的な立ち位置
アーキテクチャ決定で全てをルールとして洗い出すのは不可能なので、設計/実装時にルール化されていない部分に適用される
アーキテクトへの期待
- アーキテクチャ決定を下す
- アーキテクチャを継続的に分析する
- 最新のトレンドを把握し続ける
- 決定の遵守を徹底する
- 様々なものに触れ、経験している
- 事業ドメインの知識を持っている
- 対人スキルを持ち合わせている
- 政治を理解し、かじ取りする
アーキテクチャ思考
個人の中にある知識は以下の3分類ができる
- 分かっていること
- 分かっていないを分かっていること
- 分かっていないことを分かっていないこと
上記はピラミッド型になっている
分かっていることの中には専門領域に区分出来て、理解の深さが別のベクトルにある
分かっていることは最新の技術も含めて維持しつつ、「分かっていないことを分かっていること」を広げて術的な幅を広げていくことが重要である
開発者との違いは1つの分野だけでなく、複数の分野を浅く広く知っておく必要がある
アーキテクチャ特性はトレードオフの関係であり、事業ドメインやアプリケーション特性を考慮しながら、どの特性を重要視するかを決める必要がある
モジュール性
一般的には「より複雑な構造を構築するために使用できる標準化された部品または独立した単位の各集合」と定義される
モジュール性を把握するためには以下の要点がある
アーキテクチャ特性
以下のような特性がある
- 監査容易性
- パフォーマンス
- セキュリティ
- 要件
- データ
- 合法性
- スケーラビリティ
上記は非機能要件を呼ばれることもおおい
また、アーキテクチャ特性とは以下の3つの基準を満たすものである
- ドメインに依らない、設計に関する考慮事項を明らかにするもの
- 設計の構造的な側面に影響を与えるもの
- アプリケーションの成功に不可欠か重要なもの
アーキテクチャの運用特性
用語 | 定義 |
---|---|
可用性 | システムがどれぐらいの期間利用できるか |
継続性 | 障害復旧能力 |
パフォーマンス | ストレステスト、ピーク分析、使われる機能の使用頻度、必要なる容量、応答時間の分析 |
回復性 | 処理の持続性要件(災害発生時の復旧までの時間) |
信頼性/安全性 | システムがフェイルセーフである必要があるのか、人命に影響を与えるようなミッションクリティカルなものであるかを評価する |
堅牢性 | 実行中にハード側の問題が発生した時にエラーや境界条件を処理できるか |
スケーラビリティ | ユーザー数やリクエスト数が増えても問題なく動作するか |
アーキテクチャの構造特性
コードの構造にも注目しなければならない
用語 | 定義 |
---|---|
構成容易性 | エンドユーザーがソフトウェアの設定を簡単に変更できる |
拡張性 | 新しい機能をプラグインで追加可能にすることをどれだけ重視しているか |
インストール簡易性 | 必要なすべてのプラットフォームへのインストールの容易さ |
活性性/再利用性 | 複数の製品で共通のコンポーネントを利用できること |
ローカライゼーション | 言語、マルチバイト、通貨などの各国に対応できる |
メンテナンス容易性 | 変更の適用やシステムの拡張がどれだけ簡単に行えるか |
可搬性 | 複数のプラットフォームで動作する必要があるか? |
アップグレード容易性 | 新バージョンに簡単かつ迅速にアップグレードできるか |
アーキテクチャの横断的特性
分類できないが重要な特性
用語 | 定義 |
---|---|
アクセスビリティ | ユニバーサルデザインになっているか(ちょっと違うかも) |
長期保存性 | データは一定期間後にアーカイブまたは削除する必要があるか |
認証 | ユーザーが何者か |
認可 | ユーザーがアプリケーションの機能を使用する権限があるか |
合法性 | システムはどのような法的制約の中で運用されるか(国や組織ごとの決まり) |
プライバシー | 従業員から取引を隠せるか |
セキュリティ | データベース内を暗号化する必要があるか |
サポート容易性 | どのレベルで技術サポートが必要か(トラブル解析しやすいようにログレベルはどうするか) |
ユーザビリティ/達成容易性 | アプリケーションがどれぐらい使いやすいか |
ISOを定義されている特性
ISOで定義されている特性の一部
- パフォーマンス効率
- 互換性
- ユーザビリティ
- 信頼性
- セキュリティ
- 保守容易性
- 可搬性
- 機能適合性
- 機能的完全性
- 機能的正確性
- 機能的妥当性
アーキテクチャ特性を明らかにする
全てのアーキテクチャ特性をサポートするような汎用アーキテクチャはアンチパターンである
ドメインの関心ごとや要件からアーキテクチャ特性を導き出す必要がある
ドメインの関心ごとからアーキテクチャ特性をとらえる
サポートするアーキテクチャ特性は可能な限り絞る
サポートするアーキテクチャ特性が多いほどシステム全体の設計は複雑になってしまう
アーキテクチャ特性の優先順位をつけるのではなく、優先順位なく重要な特性を3個ほど選定する方がよい
意味的には同じだが、ステークホルダーが使用する言葉は違うため、アーキテクチャ特性に翻訳する必要があるか
以下が翻訳例
ドメインの関心ごと | アーキテクチャ特性 |
---|---|
市場投入までの時間 | アジリティ、テスト容易性、デプロイ容易性 |
ユーザー満足度 | パフォーマンス、可用性、耐障害性、テスト容易性、デプロイ容易性、アジリティ、セキュリティ |
合併・買収 | 相互運用性、スケーラビリティ、適応性、拡張性 |
関心ごとをアーキテクチャ特性に翻訳する際に1つの要素だけに焦点を当てるのは間違いである
「〇〇処理は毎日AM02:00までに終了させる必要がある」というドメインの関心ごとから、パフォーマンスだけをアーキテクチャ特性にしてはいけない
以下の4のアーキテクチャが含まれることを忘れてはいけない(暗黙的なアーキテクチャ特性)
- 可用性(必要なときに〇〇処理が使用できる必要性)
- 拡張性(将来的に〇〇処理が多くの処理をさばくけるようにする)
- 信頼性(〇〇処理が途中でクラッシュしたら意味がない)
- 回復性(〇〇処理が途中でクラッシュした場合に復帰できる時間)
アーキテクチャ・カタで練習することができる
最も重要でないアーキテクチャ特性を明らかにするのも重要である
コンポーネントベース思考
システムアーキテクトは「何に関心を置いて」システムを分割するかを考えないといけない
ドメインによる分割なのか、技術領域による分割なのか etc...
これに正解不正解はない
もちろん、それぞれにメリット/デメリットが存在する
最近はドメインによって分割する傾向がある(マイクロサービス、モジュラーモノリス)
機能的には同じでも使用するケースが異なれば、必要となるアーキテクチャ特性も変化する(管理者しか使用しない設定画面と一般ユーザーが使用する設定画面では、同時使用数という観点では異なる)
アーキテクチャスタイル(アーキテクチャパターン)
様々なアーキテクチャ特性をカバーする、コンポーネント同士の名付けられた関係を説明するもの
アーキテクチャスタイルは以下のスタイルで大別することができる
- モノリシック
- 分散型
分散アーキテクチャの誤信
今流行のマイクロサービスを始めとする分散アーキテクチャであるが、決してすべての問題を解決することができる一番優れたアーキテクチャではない。モノリシックとトレードオフの関係であることを忘れないようにしたい
1.ネットワークは信頼できる
他サービスへ到達できないorレスポンスが返ってこないことがありえる
2. レイテンシーがゼロ
ローカルメモリないであればナノ、マイクロ秒オーダーであるが、他サービスへの接続などでミリ秒オーダーになる
3. 帯域幅は無限
1回のやり取りのデータ量は少なくても頻繁に他サービスを呼び出すと帯域幅は大きくなる
スタンプ結合が問題
4. ネットワークは安全
悪質なリクエストは弾くようにサービスごとにセキュリティ対応する必要がある
5. トポロジー(ネットワークの接続形態)は決して変化しない
ネットワークで使用されているルータ、ハブ、スイッチ、ファイアフォールのアップデートによってサービスか運用できなくなる可能性もある
6.管理者は1人だけ
数十人のネットワーク管理者がいるため、1人の管理者だけとコミュニケーションを取れば言い訳ではない
7. 転送コストはゼロ
サービス間でデータのやり取りが発生しているためインバウンド、アウトバウンドの金銭的なコストが発生する
それ以外にもゲートウェイ、サーバー、サブネット、プロキシ等もサービス分必要となる
8. ネットワークは統一
サービス間をつなぐネットワーク機器はハードウェアベンダーのすべてがうまく連携できるわけではない
9. 分散ロギング
アプリケーションやシステムログもサービスごとにログが取られるため、不具合が起きた時のトラブル解析が難しくなる
10. 分散トランザクション
分散アーキテクチャは結果整合性によってデータが正しいこと(完全性)を保証する
モノリシックであればACIDトランザクションを利用して完全性を保証する
分散アーキテクチャはデータの整合性や完全性を犠牲にすることで高いスケーラビリティ、パフォーマンス、可用性を実現している
11. コントラスト(契約)のメンテナンスとバージョン管理
各サービスが独自でアップデート可能であることから、I/Fが変わっていることもある
まとめ
基礎知識ということもあり、理解ができない部分もありましたが、分からない部分はおいおいやっていこうと思います。
次はレイヤードアーキテクチャ編です