インラインコード
モジュラーモノリス戦略
いきなりのマイクロサービスではなく、過程としtモジュラーモノリス
コードが11万行
テーブル数 173
ストアドプロシージャ 208?
オンプレDBが2つでリンクなんちゃあで接続
保守性が低かった オンプレのため拡張性も低い
既存のリンクなんちゃらは廃止してサーガで
アプローチ1はDBから分解
アプローチ2はVBSのJava化
次の課題 :サービスベースアーキテクチャかモジュラーモノリス
モジュール間は連携がAPI呼び出しではなく、メソッド呼び出し:シンプル→徐々にAPI呼び出しに疎結合化
クラウドネイティブのセキュリティ戦略~~
すでにセキュリティモデルが大きく変わっている。従来は境界型。しかしこれがもう限界に。
ゼロトラストアーキテクチャが普及し始めている。 ネットワークの場所に関わらずすべてのリソースを保護。各国で対応を推奨されている。
セロトラスト思想の中でも「アクセスを許可する前にすべてのリソースの認証・認可を動的にかつ厳格に実施する」をメイントピック。
IDプロバイダIDaaSをアプリケーションサーバのセキュリティ機能と連携するのが1つの手法。(まるで、オーケストレーターのような構造)
セキュリティ標準のため、ドメイン駆動セキュリティでいう一般セキュリティの部分のことかと。
いくつかのコンポーネントが内包されている。認証メカニズムなど 内部のモジュール構成の図は資料にあるので参照
クラウドネイティブアプリへの適用の場合、分散システムではどのように保護したらいいか?
マイクロプロファイルJWTとの組み合わせで、分散システムを保護する。
デジタル署名を検証して、アクセス許可をしている。
ジャカルタセキュリティの方は、エンドユーザーからのアクセスを保護。
JWTは、マイクロサービスアーキテクチャでのサービス間の通信アクセスを保護を目的に作られている。
アクセストークンは短命にしておいて、定期的に取り寄せる。有効期限は短めに。
サービスメッシュで提供される相互TLSは、レイヤーが違う所の保護、ジャカルタセキュリティはアプリ層の保護のため、目的が異なる。
相互補完関係にある。
原則を適用する際に、既存のUDEの傾向を帰納法で読み解き、演繹法で原則適用後の効果を予測する。その想定通りかをデータで検証するために、
この演繹予測段階で、どのようなデータで検証できるか?をGQMや既存のメトリクスナレッジを再利用し、GQMストラクチャに書き起こす。
この内容をもとに、設計仮説適用後の効果を測定し、必ず可逆性を担保しておく。さらに細かい単一責務となるような変更の単位に切り分けて、小さく実行していく。
想定通りの効果が出なければ即座に元に戻す。
※汎用ドメインからコアドメインへと変わったシグナルの検知データおよびどう変えるのか(サーバーレスからコンテナ運用へ)
変える際に、既存のコアドメインとの境界があいまいになっているはず。その場合にどうする?ましてや、データの境界さえも曖昧になっているかも。
技術アーキと組織アーキ
最初はこじんまりしたチームから旧スピードで拡大
レガシーであった。ビジネスロジックは手を付けずに、アーキテクチャはインフラはインターフェイスは変えずに詳細は組み替えた、
などの大きなリアーキを実行。(え、でもビジネスロジックがわからずにリアーキってできるものか?)
JSUG勉強会2023 クレディセゾンでのSpring AWS活用事例
システム間結合テストまで行っている? (システムオブシステムズのテスト? パイプラインはE2Eのはず。)
ビジネスインパクトとして、コスト削減が大きなインパクト効果。
技術アーキテクチャは?
→技術選定は、統制していない。
直面している課題と展望>
インフラまで一貫して見られる人が不足
バージョンアップ脆弱性管理などの運用負荷が増大
大規模システムのマネジメント
セキュリティが不安 社内のセキュリティポリシーは一応ある。サービスメッシュでポリシーに準拠するようなガバナンス体制はなさそう?
次のステップ>>
時には、大規模システムの場合には、SI的管理が必要。
Q&A
・ビジネスロジックは見ていないとのことだが、そもそもシステム境界は、ビジネス境界がわからないと定義できない状態で、どのようにシステム境界やサービス境界を担保しているのか?
・セキュリティポリシーは存在するとのことだが、サービスメッシュの導入などにより、一定のポリシーに準拠していないと警告が出るような仕組みはないのか?
同じようなことを繰り返しやっている→再利用コンポーネントとしてまとめるか?
・チームごとにやっているとのことだが、チーム越境したギルド活動は? それにより、似ているものが、たまたま似ているのか、それとも概念としての重複なのかのコミュニケーションによる運用の仕組み
メッシュのような仕組みがないと、個別最適が進みに進み切って、解消できないほどの負債にならないのだろうか?
同じようなことやってるって、アーキテクチャスメルだと思うんだけど
>>セキュリティポリシーのチェックリストはある。仕組みはないぽい。
~~変更容易なテーブル設計
NewSQLは大量リクエスト処理が得意で、ACID特性の担保:TiDBもこれ
NoSQLは大量リクエスト得意だが、ACIDの担保はしていない。MongoDBとか
データベースは時代とともに進化している。
1テーブルに100以上のカラムがあるとか、
1カラム当たりの使用するデータバイトがでかすぎる
疎結合でいい所が、なぜか外部キーで密結合とか
テーブルの命名規則が適当
データ型がすべて文字列とか
不要な予備カラム(将来の拡張性という今不要なカラム)
動的に意味が変わるカラム名
論理削除のみで、物理削除されていないので、データ量増加でパフォーマンスが劣化
データ項目の追加時に影響範囲が読めない=カラム1個追加するだけでも調査工数が必要
そもそもレガシーなテーブル設計はなぜ起こるのか?
・フレームワークが勝手にやってくれるから関心がない
・謎の承認フローがある
・テーブル設計の方法は特に教わっていない
テーブル設計の方法とは?
・アプリケーションは設計方法が豊富
テーブル設計は抽象度が高すぎて、結局実用的ではない。
テーブルが格納するデータ特性や重要性
・データ:数年~数十年
・コード:数か月~数年()
データの方が圧倒的にライフサイクルが長い(k8s Podが分かれる理由でもある)
アプリコードの方は、年数経つと、コードは増加するけど初期コードは減少していく。
でもデータは、過去のものを容易には変更できない。そして変更しない方が良い。
テーブル設計の難しさ>>
未来を予測しすぎると、YAGNI違反になったりして、負債になる。
初期構築では良い設計になっているが、変更するといろいろ不具合が生じる。
テーブル設計を変更容易にするには?>> あまり世の一般的ではない
時間軸によるデータ構造の変化を意識した設計
過去に対する変更を行わない→Alter文を基本使わない。ALTER文を使うと、アプリケーションのロールバックしたいときに、データベースのロールバックも必要だったり。
あと、過去の設計に改編を加えてしまい、過去の設計に戻せない。可逆性がなくなる。
そして、Updateもしない。→いつ更新されたか不明だから、コンテキストを読み取れない。
両方とも、過去に対する変更をしてしまっている。だから使わない。
ALTERではなく、CREATE TABLE+INNER JOIN
UPDATEは、DELETE + INSERT文で対応
必ずビジネスロジック通るので、データの不整合も起きないようになっている。
つねに追加のみ。まるでイベントソーシング
変更履歴が必要な時には、logテーブルを定義。
必ず一緒になるデータは集約作業→全再利用の適用をテーブルに行っている。
P.38 ダブルライトのあとに1つ手順がスライドでは抜けている。(ここ追加してほしいと依頼)
ストラングラーパターンの適用をしている。
両方つくって、徐々に切り替えていく。このメカニズムは、段階的安全なCQRSの取入れと同じメカニズム。
この設計なら、安全にイベントソーシングに切り替えが容易そうだし、仮にイベントソーシングが不要でも、過剰エンジニアリングになりにくい。
ビジネスロジックのバリデーションを必ず通るようにしているので、不整合リスクを抑えている。変なデータはいらないように担保している。
どうしても外部キーしたいときには、~P.39
フラグカラムは、インデックスが機能しないので、フラグ専用のEnumとか、Stateパターンのように設計する。
Q&A
1つ1つのテーブルのインデックスサイズが小さくなり、ファイルアクセスがなくなるので、メモリに乗りやすくなり、早い
管理コストは肥大化する。
~~~~
意味的な結合 DRYに反して、各部分に散らばっている。散らばっているだけでなく、その事実を認知できていない。
解読不能な複雑さは、そもそものビジネス要件とかの仕様を再構築する。:要求からのトレーサビリティが欠如していたからと思われる。
ニューレガシーアンチパターン>>
アンチパターンの因果モデル図
・画面駆動設計 裏側ロジックが画面に依存しやすい。インサイドアウトと、アウトサイドインの一貫性が欠如しやすい。
・テーブル駆動設計 テーブルにデータをどう出し入れするかからアプリ使用を考えてしまう。 ドメインのエンティティがインフラに依存しやすい。
・早期サイロ化 チームトポロジーで考えられていない、職能分断型の設計
SIerの仕事の仕方は、人月の神話無視した、単純作業型のタスク設計で、ITパスポートに載っている、、、
え、仮説の濃度によって、不確実さが低いのなら、バッファを積まない。不確実さの高いものにのみバッファを積んで、それを共有する設計の方が良いのでは?CCPM的発想も
・配線プログラミング
配線プログラミングは一見綺麗に見えるが、コード変更により、ニューレガシー化しやすい。
偽事例レイヤリング
レイヤーありきで必要なロジックを振り分ける。
データの型などの関心事が異なるからこそ、レイヤーを分ける。
RESTで受け取るリクエストと、全く型が同じものがユースケース層に存在する、、、扱うデータに何の違いがあるのか不明。儀礼的にレイヤー化しているからこそ起きる問題。
画面側でバリデーションチェックしているからという理由で、そこから内部のレイヤーで事前条件チェックの保証をしない。(契約がない設計)
レイヤーが変わっているのに、何も防御してないプログラミング、、、
レイヤーできるからには、それぞれの不変条件や事前があるのに、それが繋がっておらず分散してしまう問題。
早期サイロにより、自分しか呼び出していないからと、バリデーションが実装されなくなり、再利用性の低下につながる。
入力と出力で同じ型を扱う、、、おそらく型定義が増えることを恐れて、共通の型を使っている。モデルオーバーローディング
仕様と実装が混在したドキュメント 業務要件を抽象的に捉えるフェーズがない。何が業務の関心なのか不明になりやすい。
ニューレガシーになる要因
・仕様モデルの不認知 →仕様モデル駆動設計 ドメインモデルにも概念、論理(仕様)、実装もでるがあるべき。
つまり、要件レベルのモデル。ぞくにいう、分析モデルというもの。
仕様モデルをどう描くべきか?
:閾値とかの設定など
LLM時代では、形式言語で書く必要がない。
ドメイン記述ミニ言語 システムが使うデータと、それを必要とするロジック。(情報エキスパート)
これだけで書けないビジネスルールは、コメントで定義。
仕様モデルの段階で、結合度を下げるとか、振る舞いの名前に着目し分解する。
ビジネス要件モデリングの段階で、設計原則を取り入れるってこと。不要なビジネス結合は、下位のフェーズの不要な結合になるから。
絶対に実装で疎の結合度を下げることは不可能。(リスコフ置換原則)
振る舞いの名前に着目し、PIE原則 振る舞いを分割する。振る舞いの単一責務原則
実装に依存しないレベルの仕様をモデリングすることで、単なる言語の定義を超えた真のユビキタス言語となる。
ぶっちゃけRDRAでやってることやろ。
仕様モデルと実装を一致させる。→AIに頼る スペックドリブン