マイクロサービスアーキテクチャでは、プロジェクトを多くの独立したモジュールに分割します。これは、リモートコールを介して連携します。ただし、同時性が高い場合、通信数の増加は合計通信時間の増加につながります。同時に、スレッドプールのリソースも限られています。並行性環境が高いと、多数のスレッドが待機状態になり、応答遅延につながります。これらの問題を解決するには、Hystrixの要求が合併することを理解する必要があります。
Hystrixでのマージのリクエストは、マージプロセッサを使用して、同じサービスによって開始された連続したリクエストを1つの処理のリクエストにマージすることです(これらの継続的な要求のタイムウィンドウはデフォルトでは10msです)。このプロセスに関与するコアクラスの1つは、HystrixCollapser、OKです。次に、Hystrixリクエストのマージを実装する方法を見てみましょう。
サービスプロバイダーインターフェイス
サービス消費者が次のように電話をかけるために、サービスプロバイダーに2つのインターフェイスを提供する必要があります。
@RequestMapping( "/getBook6")パブリックリスト<book> book6(string ids){ System.out.println("ids>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 33、「hu shi」、「none "))出版社2 "); return book;}最初のインターフェイスはバッチインターフェイスであり、2番目のインターフェイスは単一の要求を処理するインターフェイスです。バッチインターフェイスでは、サービスコンシューマーが送信したIDSパラメーター形式は1、2、3、4 ...この形式です。通常の状況では、IDに基づいて対応するデータを照会し、それをセットに組み立てて返す必要があります。簡単に処理するために、どんな種類のリクエストに関係なく同じデータセットを返します。単一のリクエストを処理するためのインターフェイスは比較的簡単なので、繰り返しません。
消費者にサービスを提供します
わかりました、サービスプロバイダーがそれを処理した後、サービス消費者がそれをどのように処理するかを見てみましょう。
Bookservice
まず、次のように、サービスプロバイダーが提供するインターフェイスを呼び出すために、Bookserviceに2つの方法を追加します。
Public Book test8(long id){return Resttemplate.getForObject( "http:// hello-service/getbook6/{1}"、book.class、id);} public list <book> test9(list <long> ids){system.out.println( "test9 ------------"+ids+"swrepl.current() thread.currentThread()。getName()); book [] books = retttemplate.getForObject( "http:// hello-service/getbook6?ids = {1}"、book []。class、stringutils.join(ids、 "、")); return arrays.aslist(books);}TEST8は、単一のIDを提供するインターフェイスを呼び出すために使用されます。TEST9は、バッチ処理のインターフェイスを呼び出すために使用されます。 TEST9では、実行結果を観察するように促進するためにTEST9が実行されるスレッドを印刷します。さらに、RESTTEMPLATEでは、返品値がコレクションである場合、最初に配列でそれを受け取り、次にコレクションに変換する必要があります(他の方法があり、友人はより良い提案をしているかもしれません)。
bookbatchcommand
OK、BookServiceのメソッドの準備ができたら、次のようにBookBatchCommandを作成できます。
Public Class BookBatchCommandはHystrixCommand <list <book >> {private list <long> ids;プライベートブックサービスブックサービス。 public BookBatchCommand(List <long> ids、bookservice bookservice){super(setter.withgroupkey(hystrixcommandgroupkey.factory.askey( "collapsinggroup"))。 this.ids = ids; this.bookservice = bookservice; } @Override Protected List <book> run()Throws Exception {return Bookservice.test9(ids); }}このクラスは、実際には前のブログで紹介したクラスに似ています。どちらもHystrixCommandから継承されており、マージされたリクエストを処理し、RUNメソッドのBookserviceでtest9メソッドを呼び出すために使用されます。
bookcollapsecommand
次に、リクエストマージを実装するために、HystrixCollapserから継承されたBookCollapseCommandを作成する必要があります。次のように:
Public Class BookCollapseCommandは、HystrixCollapser <List <book>、book、long> {private bookervice bookservice;プライベートロングID; Public BookCollapseCommand(Bookservice Bookservice、long ID){super(setter.withcollapserkey(hystrixcollapserkey.factory.askey( "bookcollapsecommand"))。 this.bookservice = bookservice; this.id = id; } @Override public long getRequestargument(){return id; } @Override Protected HyStrixCommand <list <book >> createcommand(collection <collupsedRequest <book、long >> collapsedrequests){list <long> ids = new arraylist <>(collapsedrequests.size()); ids.addall(collapsedRequests.stream()。マップ(collapsedRequest :: getArgument).collect(collectors.tolist())); bookbatchcommand bookbatchcommand = new bookbatchcommand(ids、bookervice); bookbatchcommandを返します。 } @Override Protected void mapResponsEtorequests(list <book> batchResponse、collection <collapsedrequest <book、long >> collapsedrequests){system.out.println( "mapResponsetorequests"); int count = 0; for(collapsedrequest <book、long> collapsedrequest:collapsedrequests){book book = batchResponse.get(count ++); collapsedRequest.setResponse(book); }}}このクラスについては、次の点を言います。
1.まず、建設方法では、リクエストタイムウィンドウを100msに設定します。つまり、100ms以内のリクエスト時間間隔のリクエストは1つの要求に統合されます。
2. CreateCommandメソッドは、主にリクエストをマージし、各単一の要求のIDをここで取得し、これらの単一のIDをコレクションに入れてからBookBatchCommandオブジェクトを作成し、このオブジェクトを使用してバッチリクエストを開始するために使用されます。
3. MapResponsEtoReQuestsメソッドは、主に各リクエストのリクエスト結果を設定するために使用されます。このメソッドの最初のパラメーターは、バッチリクエストの結果を表し、2番目のパラメーターが折りたたまれた再クエストは各マージされた要求を表します。次に、batchResponseを通過することにより、崩壊のリクエスト結果を設定します。
OK、これらすべての操作が完了した後、私たちはそれをテストすることができます。
テスト
サービスコンシューマー側にアクセスインターフェイスを作成して、マージリクエストをテストします。テストインターフェイスは次のとおりです。
@RequestMapping( "/test7")@responsebodic void test7()executionexception、arturtedexception {hystrixRequestContext context = hystrixRequestContext.initializeContext(); bookcollapsecommand bc1 = new bookcollapsecommand(Bookservice、1L); bookcollapsecommand bc2 = new bookcollapsecommand(bookservice、2l); bookcollapsecommand bc3 = new bookcollapsecommand(bookservice、3l); bookcollapsecommand bc4 = new bookcollapsecommand(bookservice、4l); Future <book> q1 = bc1.queue(); future <book> q2 = bc2.queue(); Future <book> q3 = bc3.queue(); bookbook1 = q1.get(); bookbook2 = q2.get(); book book3 = q3.get(); thread.sleep(3000); Future <book> Q4 = bc4.queue(); bookbook4 = q4.get(); System.out.println( "book1 >>>"+book1); System.out.println( "book2 >>>"+book2); System.out.println( "book3 >>>"+book3); System.out.println( "book4 >>>"+book4); context.close();}このテストインターフェースに関して、私は次の2つのポイントを言いました。
1.最初に、HystrixRequestContextを初期化する必要があります
2. bookCollapseCommandクラスのインスタンスを作成してリクエストを開始し、最初に3つのリクエストを送信してから3秒間スリープしてからリクエストを開始します。このようにして、最初の3つのリクエストは1つのリクエストにマージされます。 4番目の要求は、それらの間隔が比較的長いため、マージされませんが、個別に処理するスレッドを作成します。
わかりました、次のように、実行の結果を見てみましょう。
リクエストマージは、注釈を通じて実装されます
わかりました、上記のリクエストのマージ方法は書くのが少し面倒です。注釈を使用して、この機能をよりエレガントに実装できます。まず、次のように、Bookserviceに2つの方法を追加します。
@hystrixcollapser(batchmethod = "test11"、collapserproperties = {@hystrixproperty(name = "timerdelayinmilliseconds"、value = "100")})パブリックフューチャー<book> test10(long id){return null;}@hystrixcommandpublic ligh(< system.out.println( "test9 ----------"+ids+"thread.currentthread()。getname():"+swreet.currentthread()。getName()); book [] books = retttemplate.getForObject( "http:// hello-service/getbook6?ids = {1}"、book []。class、stringutils.join(ids、 "、")); return arrays.aslist(books);}@hystrixCollapserアノテーションを追加して、test10メソッドにリクエストマージを実装し、batchmethod属性を使用してリクエストマージ後に処理方法を示し、collapserproperties属性を他の属性を指定します。
OK、Bookserviceで書いた後、次のように直接電話してください。
@RequestMapping( "/test8")@responsebodic void test8()executionexception、arturtedexception {hystrixRequestContext context = hystrixRequestContext.initializeContext(); future <book> f1 = bookservice.test10(1L); future <book> f2 = bookservice.test10(2l); future <book> f3 = bookservice.test10(3l); Book B1 = f1.get(); Book B2 = f2.get();ブックB3 = f3.get(); thread.sleep(3000); Future <book> f4 = bookservice.test10(4l);ブックB4 = f4.get(); System.out.println( "b1 >>>"+b1); System.out.println( "b2 >>>"+b2); System.out.println( "b3 >>>"+b3); System.out.println( "b4 >>>"+b4); context.close();}前のものと同様に、最初の3つの要求がマージされ、4番目のリクエストが個別に実行されます。 OK、実行結果は次のとおりです。
要約します
リクエストの合併の利点では、友人が複数のリクエストが1回限りの処理のリクエストに統合されていることを確認しました。これにより、ネットワーク帯域幅とスレッドプールリソースを効果的に節約できます。ただし、利点と短所があります。リクエストマージを設定した後、5msでリクエストが完了した可能性がありますが、今度は他のリクエストが一緒にあるかどうかを確認するには、さらに10ミリ秒を待つ必要があります。このようにして、リクエストの時間消費は5msから15msに増加します。ただし、私たちが開始するコマンドが高遅延コマンドである場合、この時点では時間帯の時間消費が取るに足らないため、この時点でリクエストマージを使用できます。さらに、高い並行性は、リクエスト合併の非常に重要なシナリオでもあります。
OK、それは私たちのマージの要求のためです。ご質問がある場合は、メッセージを残して議論してください。私はそれがすべての人の学習に役立つことを願っています、そして、私は誰もがwulin.comをもっとサポートすることを願っています。