2

Just a review of what I'm planning and to see if it can work.

Im using a RDBMS and planning to use CQRS without event sourcing. I think event sourcing is a bit advanced for a first attempt and I'm forced to use an RDBMS.

The Task based UI is made up of many commands most of which do not need a response.

Architecture is basically

            /---- RDBMS ( EF ) 
     IO  ops                 \
            |                 \
  Single threaded Domains   Fascade(DTO) Queries
            |                /
  Event/Command Dispatcher  /
             \             /
                MVC client 

Single threaded domains don't talk to each other and they talk to the outside world via disruptors (basically ring buffers).

The Command dispatcher copies external events and commands to disk and reloads them in case of crash. Completion is explicitly marked (by IO Ops).

Commands will basically be persisted (with a transactional scope of the command), the IO Ops layer will grab all the events and process them and marks the command completion in 1 transaction. (note the command is persisted via a journal services not the domain but it talks to IO opps which matches it up with work for the command). If the command fails and its marked persist ( not all will be ) then it can be replayed. (It only persists the command when it has the command and has received a DoTransation Message.)

The Command dispatcher connects to the domains via a disruptor.

Questions

  1. Should I load the entire domain into memory (about 300 - 500 Meg) and run of that?Obviously domain would only update after the DB is updated.

  2. Is it OK to mix external events back into the command dispatcher (so it gets picked up by the single thread and processed) . eg the event becomes a command.

  3. It looks simple to code the domains and user code (and I get a nice rich domain), at least from a prototype I'm working on. Is it?

  4. When the domains do IO they send a message to a disruptor and can either

    • specify the command guid and the command gets matched up with a transaction
    • assume completion ( shoot and pray)
    • provide a call back command which is passed to the command dispatcher and then reappears in the domain. After an IO message is created the system can continue on the current command or complete it and receive the next command.
      Is this good enough?
  5. The system runs in one process and shared memory, but the domains resources are only accessed by themselves and 1 thread . Is this ok?

It's a bit of an experimental mish mesh. Any thoughts?

4

1 に答える 1

3

まず、このアーキテクチャは非常に複雑です。プロジェクトの予測される寿命が、アーキテクチャへの初期投資すべてに見合う価値があることを再確認してください。結論: このプロジェクトは 5 年または 10 年で請求書を支払うことができますか? 顧客は、ビジネス価値を提供せずにアーキテクチャに数か月を費やすことを許可しますか?

問題

コマンドディスパッチャーをホストするものについては言及していません。この部分が何であれ、アプリケーションのボトルネックになる可能性が最も高いでしょう。非常に高性能なキュー (ZeroMQ など) からメッセージを取得しない限り、Ring Buffer は必要ないと思います。Queue はほとんどのシナリオでうまく機能し、はるかに単純です。

あなたの質問

IO Ops はイベント/イベント ハンドラーを意味すると想定しています。私が聞き取れなかった他のニュアンスがあるかもしれません。

  1. これがWebアプリケーションにとって本当に意味があるとは思えません。データベースがパフォーマンスのボトルネックになっている場合は、メモリにドメインをロードすると効果的です。アプリケーションのパフォーマンス プロファイルによってはそうではない場合があり、それらすべてのスレッドを管理する作業は開発者の時間の無駄になる可能性があります。(主に、アプリのシャットダウン時にスレッドを確実に停止する必要があるため、またはアプリがシャットダウンしないためです。) DB が更新された後にドメインを更新することに関する部分は、私には意味がありません。起動時にドメインをロードするだけです。ドメインの状態の変更を保存するのは、次の起動時に再び再読み込みできるようにするためだけです。ドメインを永続化する前に、ドメインの状態を変更する必要があると思います。また、DB がそれほどボトルネックである場合は、おそらく非同期で状態を保存します。

  2. ここでいくつかの手順が欠落していると思います。イベントを取得してコマンドとして送信する場所は、プロセス マネージャー (または必要に応じて Saga) が移動する場所のように聞こえます。イベントを常にコマンドに変換するような単純なビジネス プロセスはめったにありません。たとえば、後続のコマンドが完了できない場合はどうなりますか? または、コマンドを発行する前に複数のイベントが発生する必要がある場合。(例: OrderPlaced と PaymentReceived は、ShipOrder が送信される前に発生する必要があります)

  3. 通常、ドメインの難しい部分は、ドメインをモデル化するための最も適切な方法を見つけ出すことです。ドメイン モデルが実際のドメインに適合しない場合、コードはより厄介で複雑になります。それとは別に、それは本当にあなたのドメインに依存します. 微積分ソルバーをプログラミングしている場合は、おそらくそれに適しています。しかし、多くの場合、ビジネス ロジックは一度理解すれば、適切に体系化できます。

  4. トランザクションビットで何をしようとしているのか本当にわかりません。複数のコマンドをトランザクションにラップしようとしていますか? これはおそらく、ドメインをより適切にモデル化できる場所、またはバッチ処理を行っている場所を表しています。うまくいけば、多くのコマンドがバッチ処理されるわけではないので、常に 1 つを使用するのはもったいないようです。すべての操作がバッチ処理され、バッチ内の各操作が個々のフィールドを設定するだけの場合、DDD とタスクベースの UI を使用するポイントが本当に失われています。

  5. #1も参照してください。このレベルのパフォーマンスが必要な場合は、これで問題ありません。ドメインは、コマンドを受け取る MVC アプリケーションのシングルトンとしてメモリ内でホストされる可能性が高くなります。共有メモリにアクセスするときに適切なロック手法を使用していると思います。このサイトは、そのようなトピックの優れたリソースであることに注意してください。volatile特に、キーワードに惑わされないでください!

すべてがトレードオフであることを覚えておいてください。アプリにあまりメリットのないアーキテクチャの開発に多くの時間を無駄にしないでください。

于 2013-01-08T00:51:34.410 に答える