大量の入力データが必要な場合にマイクロサービスアーキテクチャにルールエンジンを組み込む方法


12

現在の状況

私たちは、マイクロサービスアーキテクチャでオンラインショッピングWebアプリケーションを実装しています(そして現在保守しています)。

要件の1つは、エクスペリエンスと最終的な注文をカスタマイズするために、顧客がカートに追加するものにルールを適用できる必要があることです。明らかに、ビジネスルールエンジンを導入する必要があり、このために特定の「マイクロサービス」を実装しました(まだそう呼べる場合)。

1年の間に、このルールエンジンはますます複雑になり、より多くのデータ(カートのコンテンツだけでなく、ユーザー情報、役割、既存のサービス、請求情報など)が必要になりました。それらのルールを計算します。

現時点では、shopping-cartマイクロサービスは他のマイクロサービスからこのデータをすべて収集しています。このデータの一部はで使用されますがshopping-cart、ほとんどの場合、主にルールエンジンのフィードに使用されます。

新しい要件

これで、同様の要件にルールエンジンを再利用する他のアプリケーション/マイクロサービスが必要になりました。したがって、現在の状況では、ルールエンジンを呼び出すことができるように、同じ種類のデータを送信し、同じマイクロサービスを呼び出し、(ほぼ)同じリソースを構築する必要があります。

そのまま続行すると、いくつかの問題に直面します。

  • 誰もが(ルールエンジンを呼び出して)データのフェッチを再実装する必要があります(自分でデータを必要としない場合でも)。
  • ルールエンジンへの要求は複雑です。
  • この方向で続けると、多くの要求のためにこのデータをネットワーク全体に転送する必要があります(μsAがルールエンジンを呼び出すμsBを考えますが、Aはルールエンジンが必要とするデータの一部を既に持っています)。
  • shopping-cart すべてのデータ取得により巨大になりました。
  • おそらく多くのことを忘れてしまいます…

これらのトラブルを回避するために何ができますか?

理想的には、ルールエンジンの複雑さを増やさないようにします。また、ボトルネックにならないように確認する必要があります。たとえば、一部のデータはフェッチに時間がかかります(10秒以上)ためshopping-cart、ルールを呼び出す前にデータが存在する可能性が高くなるようにプリフェッチを実装しましたエンジン、および許容できるユーザーエクスペリエンスを維持します。

いくつかのアイデア

  1. ルールエンジンに必要なデータをフェッチさせます。これにより、さらに複雑さが増し、単一の責任原則に違反しますさらに…)。
  2. ルールエンジンがデータを取得する前にプロキシμsを実装します。
  3. ルールエンジンが必要なすべてのデータを一度にフェッチするために呼び出す「データフェッチャー」μsを実装します(複合照会)。

これを(質問を付けて)要約しましょう:ショップにいくつかのマイクロサービスを実装しています。それらの1つはショッピングカートです。カートに組み込まれているのは、ルールエンジン(自作または製品)です。ユーザーがカートにアイテムを追加すると、ルールエンジンがビジネスロジックの一部として起動し、カートを何らかの方法で変更します(割引やバンドル製品など)。今、別のマイクロサービスも同様の入力データに基づいている可能性のあるルールを使用したいと思っていますよね?そして、入力データは他のマイクロサービスによって提供されますよね?データの取得がなぜそれほど複雑なのですか?
アンディ

3
これらの問題を回避する最善の方法は、ルールエンジンを削除することです。
whatsisname

@Andyルールエンジンは独立したマイクロサービスです。APIはに合わせて少し調整shopping-cartされていますが、他のマイクロサービスのニーズに合わせて簡単に調整できます(これらはまだユーザー、製品、注文に関連しています)。ご覧のとおり、特にビジネスで適用する述語を選択できるため、同じ入力データ必要になります。カートの内容自体を除くすべてのデータは、他のマイクロサービスによって提供されます。データの取得自体は複雑ではありませんが、他の10個のマイクロサービスを呼び出して、ルールエンジンが期待する構造を維持する必要がある場合、複雑になります。
ディディエL

@whatsisname私は一般的にルールエンジンを持つことの大ファンではありませんが、現時点ではそれに対処する必要があり、とにかくビジネスは日々その構成を変更しています。たとえそれを取り除いたとしても、同じ入力データを必要とする同じことをするためにいくつかの構成可能なコンポーネントが必要になります。
ディディエL

回答:


8

この新たな長さになる可能性のある答えを書き出す前に、少し前に戻り、出発点を評価しましょう。あなたが持っている:

  • 大きなモノリス(ルールエンジン)
  • 大量に送信される大量の非モジュール化データ
  • ルールエンジンとの間でデータを取得するのは難しい
  • ルールエンジンは削除できません

わかりました、これはマイクロサービスにはあまり適していません。すぐに明白な問題は、皆さんがマイクロサービスとは何かを誤解しているように見えることです。

誰もが(ルールエンジンを呼び出して)データのフェッチを再実装する必要があります(自分でデータを必要としない場合でも)。

マイクロサービスが使用する何らかのAPIまたは通信方法を定義し、それを一般的にする必要があります。これは、すべてがインポートできるライブラリかもしれません。メッセージプロトコルを定義している可能性があります。既存のツールを使用している可能性があります(適切な出発点としてマイクロサービスメッセージバス探してください)。

サービス間通信の問題自体は「解決された」問題ではありませんが、この時点では「自分で解決する」問題でもありません。既存のツールと戦略の多くは、あなたの人生を非常に楽にします。

何をするかに関係なく、単一のシステムを選択し、これを使用するように通信APIを調整してください。サービスが相互作用するための定義された方法がなければ、マイクロサービスとモノリシックサービスのすべての欠点があり、どちらの利点もありません。

あなたの問題のほとんどはこれに起因します。

ルールエンジンへの要求は複雑です。

複雑さを軽減します。

複雑さを軽減する方法を見つけてください。真剣に。一般的なデータモデル、単一のルールエンジンを小さなものなどに分割します。ルールエンジンの動作を改善します。「クエリにすべてを詰め込んで、単に複雑にし続ける」というアプローチをとらないでください。あなたがしていることとその理由を真剣に見てください。

データに何らかのプロトコルを定義します。私の推測では、皆さんは(上記のように)定義されたAPIプランを持たず、必要に応じてアドホックにRESTコールの作成を開始しました。これは、何かが更新されるたびにすべてのマイクロサービスを維持する必要があるため、ますます複雑になります。

さらに良いことに、あなたはオンラインショッピングツールを実装した最初の会社ではありません。他の会社を調べてください。

それで...

この後、少なくともいくつかの大きな問題をトリアージしました。

次の問題は、ルールエンジンに関するこの質問です。これが合理的にステートレスであり、スケーリングできることを願っています。もしそうであれば、少なくとも次善策ではありませんが、あなたは少なくとも栄光の炎の中で死ぬことも、非常識な回避策を構築することもありません。

ルールエンジンをステートレスにする必要があります。データのみを処理するようにします。ボトルネックとして見つかった場合は、プロキシ/ロードバランサーの背後で複数を実行できるようにします。理想的ではありませんが、まだ実行可能です。

マイクロサービスのいずれかを実際にルールエンジンに配置する必要があるかどうかを検討してください。「マイクロサービスアーキテクチャ」を実現するためだけにシステムのオーバーヘッドを大幅に増やす場合は、これを計画するのにより多くの時間を費やす必要があります。

または、ルールエンジンを複数の部分に分割できますか?ルールエンジン固有のサービスを作成するだけで利益が得られる場合があります。

また、ボトルネックにならないように注意する必要があります。たとえば、一部のデータの取得がかなり遅い(10秒以上)

上記の問題を解決した後にこの問題が存在すると仮定すると、なぜこれが起こっているのかを真剣に調査する必要があります。悪夢が展開しているのに、なぜ(10秒?ショッピングポータルデータを送信するために?冷笑的に言ってください、しかしこれは少しばかげているように)理由を理解するのではなく、最初の場所。

「データの取得」というフレーズを何度も使用しました。このデータはデータベースにありますか?そうでない場合は、これを行うことを検討してください-データを「手動で」フェッチするのに非常に多くの時間を費やしている場合は、実際のデータベースを使用することをお勧めします。

フェッチするデータのデータベース(これが何であるかに応じて何度も言及している)、いくつかのルールエンジン、およびクライアントを使用したデザインを作成できる場合があります。

最後に、APIとサービスの適切なバージョン管理を使用することを確認する必要があります。マイナーリリースは、後方互換性を損なうものではありません。すべてのサービスを同時にリリースして、それらが機能するようになった場合、マイクロサービスアーキテクチャはなく、分散モノリシックアーキテクチャになります。

そして最終的に、マイクロサービスは万能のソリューションではありません。聖なるもののために、新しいヒップなものだからとにかくやってはいけない。


答えてくれてありがとう、@ enderland。実際、マイクロサービスアーキテクチャはまだ比較的新しいため、この質問があります。このルールエンジンは、ここで私たちを導くために少し有機的に進化してきたので、今ではそれを修正するために運転指示が必要です。(残念ながら)完全にステートレスであるため、入力として受け取るデータの量です。そして、これを再利用可能なコンポーネントにするために最初に取り組むことです。しかし、利用可能な述語の数を減らすことなく、入力データの量を減らす方法はありますか?データを独自に取得できるAPIが必要だと思いますが、適切にアーキテクチャ化するにはどうすればよいですか?
ディディエL

パフォーマンスの問題に関して、それらは実際にバックエンドによって実装された遅いJMSおよびSOAPサービスを呼び出しているマイクロサービスから来ています。データベースには独自のデータベースがありますが、パフォーマンスは最初の目標ではありません(負荷を処理する限り)。また、データを複製して維持することを検討するにはあまりにも多くあります(ただし、一部のユーザーにとってはそうします)。したがって、できることはキャッシングとプリフェッチです。
ディディエL

あなたが「いくつかのルールエンジン」について言及するとき、私はあなたが1種類の入力でのみ述語を評価する特別なルールエンジンを意味すると理解していますか?必要なデータを取得することを提案しますか、それとも事前に取得する必要がありますか?述語の組み合わせを調整するためのコンポーネントも必要ですよね?また、このオーケストレーションによってネットワークのオーバーヘッドが大きくなりすぎないように注意してください。
ディディエL

1

ルールエンジンとその入力および出力について提示された情報の量で、あなたの提案はないと思います。2は正しい軌道に乗っています。

ルールエンジンの現在の利用者は、必要な情報を収集するプロセスをより特別な目的のコンポーネントに外部委託できます。

例:現在、ルールエンジンを使用して、ショッピングカートのコンテンツに適用する必要がある割引を計算しています。以前の購入、地理、および現在のオファーが考慮されます。

新しい要件は、これと同じ情報の多くを使用して、今後のスペシャルや以前の購入に基づいて以前の顧客へのオファーを電子メールで送信することです。以前の購入、現在および今後のオファーが考慮されます。

これには2つの個別のサービスが必要です。彼らはそれぞれ、その重荷の一部をルールエンジンサービスに依存しています。それぞれが、ルールエンジンへの要求に必要なデータを収集します。

ルールエンジンはルールを適用するだけで、消費者はルールエンジンが特定のコンテキストに必要な正確なデータを心配する必要はありません。これらの新しい仲介サービスはたった1つのことを行います。応答を変更せずに返します。


0

決定に必要なデータの集計は、ルールエンジンの外部で行う必要があります。これは、可能な限りステートレスサービスとして最適に設計されているためです。データの取得には必然的に非同期処理と状態保持が含まれます。フェッチが意思決定サービスの前にあるプロキシ、呼び出し元、またはビジネスプロセスのいずれで行われるかは重要ではありません。

実装の実際的な問題として、IBM Operational Decision Managerが文書化を開始し、既にdocker container内での製品の使用をサポートしていることに言及します。他の製品もこのサポートを提供し、主流になると確信しています。


0

私の簡単な考えでは、顧客がデータの購入とキャッシュを開始するとすぐに、データ取得サービスへの非同期呼び出しを行うことで、必要なすべてのデータをプリフェッチするのに役立つと思います。したがって、ルールサービスを呼び出す必要がある場合、データは既にそこにあります。セッション中も他のサービスで引き続き利用できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.