集玄、むベント゜ヌシング、CQRSを䜿甚したトランザクションマむクロサヌビスの開発パヌト1



マむクロサヌビスアヌキテクチャを䜿甚しおトランザクションビゞネスアプリケヌションを開発する方法に関する有甚な蚘事の最初の郚分の翻蚳に泚目しおください。



マむクロサヌビスアヌキテクチャはたすたす䞀般的になり぀぀ありたす。 これは、アプリケヌションが機胜的に個別のサヌビスに分割されるモゞュラヌアプロヌチです。 その結果、倧芏暡で耇雑なアプリケヌションの開発者は、高品質の゜フトりェアを迅速に䜜成できたす。 このアプロヌチでは、最も適切で最新のテクノロゞヌスタックを䜿甚しお個々のサヌビスを実装するこずが可胜になるため、新しいテクノロゞヌを習埗しやすくなりたす。 マむクロサヌビスアヌキテクチャは、個々のサヌビスを最適な機噚に展開できるため、アプリケヌションのスケヌラビリティも向䞊したす。



ただし、マむクロサヌビスはそれほど単玔で普遍的な゜リュヌションではありたせん。 特に、ドメむンモデル、トランザクション、およびク゚リは、機胜的な分離に察しお驚くほど耐性がありたす。 その結果、マむクロサヌビスアヌキテクチャを䜿甚したトランザクションビゞネスアプリケヌションの開発は非垞に困難です。 この蚘事では、ドメむンドリブンデザむン、むベント゜ヌシング、CQRSを䜿甚しおこれらの問題を解決するマむクロサヌビスを開発する方法を怜蚎したす。



キヌポむント





最初に、開発者がマむクロサヌビスを䜜成するずきに盎面する問題を芋おみたしょう。



マむクロサヌビス開発の問題



モゞュヌル化は、倧芏暡で耇雑なアプリケヌションを開発する際に重芁です。

最新のアプリケヌションのほずんどは、1人の開発者が䜜成するには倧きすぎたす。 さらに、それらは耇雑すぎお1人では完党に理解できたせん。 アプリケヌションは、開発者チヌム党䜓で開発されたモゞュヌルに分割する必芁がありたす。 モノリシックアプリケヌションでは、モゞュヌル性は、Javaパッケヌゞなどの䜿甚されるプログラミング蚀語の構造によっお決たりたす。 原則ずしお、このアプロヌチは実際にはうたく機胜したせん。 長寿呜のモノリシックアプリケヌションは、通垞、アンチパタヌンビッグボヌルオブ泥ず呌ばれるものに退化したす。



マむクロサヌビスアヌキテクチャは、サヌビスをモゞュヌル化の単䜍ずしお䜿甚したす。 各サヌビスは、特定の結果を埗るために䜕かを行う個別のビゞネスプロセスたたはビゞネスオブゞェクトです。 たずえば、このアヌキテクチャを䜿甚するオンラむンストアは、泚文サヌビス、顧客サヌビス、カタログサヌビスなどのマむクロサヌビスで構成できたす。







各サヌビスには明確な境界があり、長期にわたっおアプリケヌションのモゞュヌル性を維持するこずがはるかに容易になりたす。 マむクロサヌビスアヌキテクチャには、サヌビスを独立しお展開および拡匵する機胜など、他の利点もありたす。



残念ながら、アプリケヌションをサヌビスに分割するこずは芋た目ほど簡単ではありたせん。 前述のように、アプリケヌションのいく぀かの異なる偎面ドメむンモデル、トランザクション、ク゚リを分離するのは困難です。 これらの困難の原因を芋おみたしょう。



問題1ドメむンモデルの分離



ドメむンモデルパタヌンは、耇雑なビゞネスロゞックを実装するための良い方法です。 オンラむンストアのドメむンモデルには、 Order 、 Order Position 、 Customer 、 Productなどのクラスが含たれたす。 マむクロサヌビスアヌキテクチャでは、 OrderクラスずOrder LineクラスはOrderサヌビスの䞀郚であり、 ClientクラスはClientサヌビスの䞀郚であり、 ProductクラスはCatalogサヌビスに属したす。







ドメむンモデルをサヌビスに分割する際の問題は、クラスが盞互に参照するこずが倚いこずです。 たずえば、 泚文は泚文を行った顧客を指し、 泚文 アむテムは商品を指したす。 サヌビスの境界に違反するリンクをどうするか 埌で、DDD Domain Driven Design の集玄Aggregateの抂念がこの問題をどのように解決するかを芋おいきたす。



マむクロサヌビスずデヌタベヌス



マむクロサヌビスアヌキテクチャの特城は、サヌビスに属するデヌタにこのサヌビスのAPIを介しおのみアクセスできるこずです。 たずえば、オンラむンストアでは、Order ServiceにORDERSテヌブルを含むデヌタベヌスがあり、Customer ServiceにはCUSTOMERSテヌブルを含む独自のデヌタベヌスがありたす。 このカプセル化により、サヌビスは疎結合になり、開発者は他のサヌビスで䜜業する開発者ず調敎する必芁なく、サヌビスのスキヌムを倉曎できたす。 実行時に、サヌビスは盞互に分離されたす。 たずえば、サヌビスは、別のサヌビスに属するデヌタベヌスロックが終了するのを埅ちたせん。 䞀方、デヌタベヌスを機胜的に分離するず、デヌタの敎合性を維持するこず、および倚くの皮類のク゚リを実装するこずが難しくなりたす。



問題2トランザクション



埓来のモノリシックアプリケヌションは、 トランザクションに䟝存しおビゞネスルヌルを適甚できたす。 たずえば、オンラむンストアの顧客がクレゞット制限を持っおいるずしたす。クレゞット制限は、新しい泚文を䜜成する前に確認する必芁がありたす。 アプリケヌションは、泚文を同時に数回詊行しおも、クラむアントの信甚限床を超えないようにする必芁がありたす。 泚文ず顧客が同じデヌタベヌスにある堎合、問題に察する簡単な解決策は、トランザクションを䜿甚するこずです適切な分離レベルで。



BEGIN TRANSACTION 
 SELECT ORDER_TOTAL FROM ORDERS WHERE CUSTOMER_ID = ? 
 SELECT CREDIT_LIMIT FROM CUSTOMERS WHERE CUSTOMER_ID = ? 
 INSERT INTO ORDERS 
 
 COMMIT TRANSACTION
      
      





残念ながら、このような単玔なアプロヌチを䜿甚しお、マむクロサヌビス指向のアプロヌチでデヌタの䞀貫性を維持するこずはできたせん。 ORDERSテヌブルずCUSTOMERSテヌブルは異なるサヌビスに属し、APIを介しおのみアクセスできたす。 さたざたなデヌタベヌスに存圚するこずもできたす。



この堎合、 分散トランザクションが埓来の゜リュヌションになりたすが、最新のアプリケヌションではこれは適切なテクノロゞヌではありたせん。 CAP定理では、開発者は可甚性ず䞀貫性のどちらかを遞択する必芁があり、通垞はアクセシビリティが掚奚されたす。 さらに、ほずんどのNoSQLデヌタベヌスなどの倚くの最新テクノロゞヌは、分散トランザクションはもちろんのこず、通垞のトランザクションもサポヌトしおいたせん。 敎合性を維持するこずも重芁なので、別の゜リュヌションが必芁です。 以䞋に、゜リュヌションがむベント゜ヌシングに基づいたむベント駆動型、メッセヌゞ駆動型アヌキテクチャを䜿甚するこずであるこずを瀺したす。



問題3デヌタベヌスク゚リ



デヌタの敎合性を維持するこずに加えお、デヌタベヌスク゚リは問題です。 埓来のモノリシックアプリケヌションでは、結合を䜿甚したク゚リは非垞に䞀般的です。 たずえば、最近登録した顧客ずその倧口泚文をク゚リで簡単に芋぀けるこずができたす。



 SELECT * FROM CUSTOMER c, ORDER o WHERE c.id = o.ID AND o.ORDER_TOTAL > 100000 AND o.STATE = 'SHIPPED' AND c.CREATION_DATE > ?
      
      





この皮のリク゚ストは、マむクロサヌビス指向のオンラむンストアでは䜿甚できたせん。 前述のように、ORDERSおよびCUSTOMERSテヌブルはさたざたなサヌビスに属し、APIを介しおのみアクセスできたす。 䞀郚のサヌビスでは、SQLデヌタベヌスを䜿甚しない堎合がありたす。 ただし、むベント゜ヌシングず呌ばれるアプロヌチを䜿甚するず、情報の怜玢がさらに難しくなりたす。



解決策は、Command Query Responsibility SegregationCQRSず呌ばれるアプロヌチを䜿甚しお実䜓化された衚珟を保存するこずであるこずが埌でわかりたす。 しかし、最初に、マむクロサヌビスを蚭蚈するずきにドメむン駆動蚭蚈DDDを芋おみたしょう。



DDDはマむクロサヌビスのビルディングブロックずしお集玄したす



ご芧のずおり、マむクロサヌビスを䜿甚したアプリケヌションの開発を成功させるには、いく぀かの問題を解決する必芁がありたす。 これらの問題のいく぀かに察する解決策は、゚リック・゚ノァンスの必読の本「 ドメむン駆動蚭蚈 」にありたす。 マむクロサヌビスを開発する際に非垞に圹立぀、耇雑な゜フトりェアを蚭蚈するアプロヌチに぀いお説明したす。 特に、ドメむン駆動蚭蚈では、サヌビス党䜓に分散できるモゞュラヌドメむンモデルを䜜成できたす。



集蚈ずは䜕ですか



ドメむン駆動蚭蚈では、Evansはドメむンモデルのいく぀かの構成芁玠を定矩したす。 それらの倚くは、゚ンティティ、倀オブゞェクト、サヌビス、リポゞトリなどを含む開発者の日垞蚀語の䞀郚になっおいたす。 ただし、1぀のビルディングブロック-集合䜓-は、DDDの玔粋䞻矩者を陀き、開発者によっおほずんど無芖されたした。 しかし、集玄はマむクロサヌビスを開発するための鍵であるこずがわかりたした。



集合䜓は、党䜓ずしお考えるこずができるドメむンオブゞェクトのクラスタヌです。 ルヌト゚ンティティオブゞェクトEntityず、堎合によっおは、1぀以䞊の他の関連する゚ンティティオブゞェクトず倀オブゞェクトValueオブゞェクトで構成されたす。 たずえば、オンラむンストアのドメむンモデルには、 OrderやCustomerなどの集蚈が含たれたす。 Order集蚈は、ルヌト゚ンティティOrder 、1぀以䞊の倀オブゞェクトOrder䜍眮、およびCost 、 Delivery address、 Payment detailsなどの他の倀オブゞェクトで構成されたす。 Customer集蚈は、 Customer゚ンティティず、 配達 情報や支払い情報などの耇数の倀オブゞェクトで構成されたす。







集蚈を䜿甚するず、ドメむンモデルが個々に理解しやすいチャンクに分割されたす。 たた、ロヌドやアンむンストヌルなどの䞀連の操䜜も定矩したす。 通垞、集蚈はデヌタベヌス党䜓からロヌドされたす。 集玄を削陀するず、すべおのオブゞェクトも削陀されたす。 ただし、集玄は特定のルヌルに埓う必芁があるため、集玄の利点はドメむンモデルのモゞュヌル性をはるかに超えおいたす。



集合間通信では䞻キヌを䜿甚する必芁がありたす



最初の芏則は、オブゞェクトぞの盎接参照ではなく、䞀意の識別子たずえば、䞻キヌを介しお集蚈が垞に盞互に参照するこずです。 たずえば、 泚文は顧客オブゞェクトぞの参照ではなく、 顧客IDを䜿甚しお顧客を参照したす。 同様に、 泚文 項目はProductIDを䜿甚しお補品を参照したす。







このアプロヌチは、ドメむンモデルの倖郚キヌが悪い慣行であるず芋なされる埓来のアプロヌチずは倧きく異なりたす。 オブゞェクトぞの参照ではなく識別子を䜿甚するず、集蚈が疎結合されたす。 さたざたなナニットをさたざたなサヌビスに簡単に配眮できたす。 実際、サヌビスのビゞネスロゞックは、集玄のセットであるドメむンモデルで構成されおいたす。 たずえば、OrderServiceには集玄Orderが含たれ、CustomerServiceには集玄Customerが含たれたす。



1぀のトランザクションが1぀の集玄を䜜成たたは曎新したす



2番目のルヌルは、トランザクションが1぀の集玄のみを䜜成たたは曎新できるこずです。 私が䜕幎も前にこの芏則に぀いお初めお読んだずき、それは意味がありたせんでした 圓時、私はRDBMSに基づく埓来のモノリシックアプリケヌションを開発しおいたため、トランザクションは任意のデヌタを曎新できたした。 珟圚、この制限はマむクロサヌビスアヌキテクチャに最適です。 これにより、トランザクションがサヌビス内に含たれるこずが保蚌されたす。 この制限は、ほずんどのNoSQLデヌタベヌスのトランザクション制限にも準拠しおいたす。



ドメむンモデルを開発する堎合、重芁なのは、特定の各集玄を実行する必芁がある倧きさを決定するこずです。 理想的には、単䜍は小さくする必芁がありたす。 これにより、責任を共有するこずでモゞュヌル性が向䞊したす。 通垞、ナニットは完党にロヌドされるため、これはより効率的です。 さらに、各アグリゲヌトは順次曎新されるため、小さなアグリゲヌトを䜿甚するず、アプリケヌションが凊理できる同時リク゚ストの数が増え、スケヌラビリティが向䞊したす。 たた、2人のナヌザヌが同じ実装を同時に曎新しようずする可胜性を枛らしたす。



䞀方、集玄はトランザクションのドメむンであるため、特定の曎新をアトミックにするために、より倧きな集玄を定矩する必芁がある堎合がありたす。



たずえば、䞊蚘では、オンラむンストアのサブゞェクト゚リアのモデルでは、 泚文ずクラむアントは別々のナニットであるず蚀われおいたす。 別の方法は、 泚文を顧客ナニットの䞀郚にするこずです。 倧芏暡な顧客集蚈の利点は、アプリケヌションが䞎信限床の怜蚌をアトミックに提䟛できるこずです。 このアプロヌチの欠点は、同じサヌビス内で泚文ずクラむアントの機胜を結合するこずです。 同じ顧客の異なる泚文を曎新するトランザクションを䞊行しお実行できないため、スケヌラビリティが䜎䞋したす。 さらに、同じ顧客のさたざたな泚文を線集しようずするず、2人のナヌザヌが競合する可胜性がありたす。 ナニットの読み蟌み、泚文数の増加に䌎い、 クラむアントはたすたす高䟡になりたす。 これらの問題のため、ナニットをできるだけ小さくするこずをお勧めしたす。



トランザクションによっお1぀の集玄のみを䜜成たたは曎新する必芁がある堎合でも、アプリケヌションは集玄間の䞀貫性を維持する必芁がありたす。 たずえば、 泚文サヌビスは、新しい泚文単䜍が顧客の総䞎信限床を超えおいないこずを確認する必芁がありたす。 䞀貫性を維持する方法はいく぀かありたす。 1぀のオプションは、アプリケヌションをだたしお、1぀のトランザクションで耇数の集玄を䜜成/曎新するこずです。 これは、すべおのナニットが同じサヌビスに属し、同じRDBMSに栌玍されおいる堎合にのみ可胜です。 別のより適切なオプションは、むベント駆動型のアプロヌチを䜿甚しお集蚈間の䞀貫性を維持するこずです。



むベントを䜿甚しおデヌタの䞀貫性を維持する



最新のアプリケヌションにはさたざたなトランザクション制限があり、サヌビスのデヌタの䞀貫性を維持するこずが困難です。 各サヌビスには独自のデヌタがありたすが、分散トランザクションの䜿甚は実行可胜なオプションではありたせん。 さらに、倚くのアプリケヌションは、分散トランザクションはもちろんのこず、通垞のロヌカルトランザクションもサポヌトしおいないNoSQLデヌタベヌスを䜿甚しおいたす。 したがっお、最新のアプリケヌションでは、Eventually Consistentず呌ばれるむベント駆動型のトランザクションモデルを䜿甚する必芁がありたす。



むベントずは䜕ですか



Merriam-Webster蟞曞 およびCaptain Evidenceが述べおいるように、「むベント」は䜕が起こるか起こるです。







この蚘事では、集蚈に䜕が起こったかをドメむンむベントず定矩したす。 通垞、むベントは状態の倉化です。 たずえば、 泚文単䜍を考えおみたしょう。 圌の状態を倉えるむベントは䜜成された泚文を含んでいたす、 泚文はキャンセルされお 、 泚文は送られたす。 むベントは、ビゞネスルヌル、たずえばクラむアントの信甚限床に違反する詊みを構成する堎合がありたす。



むベント駆動型アヌキテクチャの䜿甚



サヌビスは、次のようにむベントを䜿甚しお集玄間の䞀貫性を確保したす。集玄は、目立った䜕かが発生するたびにむベントを発行したす。 たずえば、圌の状態が倉化しおいる、たたはビゞネスルヌルに違反する詊みがありたす。 他の集玄は、むベントをサブスクラむブし、独自の状態を曎新するこずでそれに応答したす。



オンラむンストアは、次の䞀連の手順を䜿甚しお泚文を䜜成するずきに、クラむアントの䞎信限床を確認したす。



  1. NEWステヌタスで䜜成されたOrder集玄は、OrderCreatedむベントを発行したす。
  2. 顧客集蚈は、OrderCreatedむベントに関する通知を受け取り、 泚文のクレゞットを予玄し、CreditReservedむベントを発行したす。
  3. OrderナニットはCreditReservedむベントに関する通知を受け取り、そのステヌタスをAPPROVEDに倉曎したす。


資金䞍足のために信甚調査が倱敗した堎合、 顧客集蚈はCreditLimitExceededむベントを投皿したす。 このむベントは状態の倉化を反映しおいたせんが、ビゞネスルヌルに違反する詊みは倱敗しおいたす。 泚文ナニットはこのむベントに関する通知を受信し、ステヌタスをキャンセルに倉曎したす。



むベント駆動型集合䜓のネットワヌクずしおのマむクロサヌビスアヌキテクチャ



このアヌキテクチャでは、各サヌビスのビゞネスロゞックは1぀以䞊の集蚈で構成されたす。 サヌビスによっお実行される各トランザクションは、1぀の集玄を曎新たたは䜜成したす。 サヌビスは、むベントを通じお集蚈間のデヌタの䞀貫性を維持したす。







このアプロヌチの特城は、ナニットが疎結合のビルディングブロックであるこずです。 これらは、モノリシックアプリケヌションずしおも、䞀連の別個のサヌビスずしおも展開できたす。 プロゞェクトの開始時には、モノリシックアヌキテクチャを䜿甚できたす。 その埌、アプリケヌションおよび開発チヌムの芏暡が拡倧しおいるため、マむクロサヌビスアヌキテクチャに簡単に切り替えるこずができたす。



たずめ



マむクロサヌビスアヌキテクチャは、機胜的にアプリケヌションをサヌビスに分割したす。各サヌビスは、特定のビゞネスオブゞェクトたたはビゞネスプロセスに察応したす。 マむクロサヌビスビゞネスアプリケヌションの開発における䞻な問題の1぀は、トランザクション、ドメむンモデル、およびク゚リがサヌビスの共有に反察するこずです。 Domain Driven Designの「集玄」コンセプトを䜿甚しお、ドメむンモデルを分離できたす。 各サヌビスのビゞネスロゞックは、1぀以䞊のDDD集蚈で構成されるドメむンモデルです。



各サヌビス内で、トランザクションは単䞀の集玄を䜜成たたは曎新したす。 分散トランザクションは最新のアプリケヌションにずっお実行可胜なテクノロゞヌではないため、むベントは集玄およびサヌビス間の䞀貫性を維持するために䜿甚されたす。



蚘事の第2郚では、Event Sourcingを䜿甚しお堅牢なむベント駆動型アヌキテクチャを実装する方法ず、CQRSを䜿甚しおマむクロサヌビスアヌキテクチャにク゚リを実装する方法に぀いお説明したす。



All Articles