序文
この記事では、主に春に@scheduledとhttpclientの落とし穴を紹介します。私たちはあなたの参照と学習のためにそれらを共有します。以下ではあまり言いません。詳細な紹介を一緒に見てみましょう。
私はかつて大きな穴に足を踏み入れました:
ビジネスの特殊性により、多くのタイミングのタスクが定期的に実行され、ビジネスデータを補償されます。
春の使用中に、@scheduled Annotationを使用してタイミングタスクを簡単に実装できます。
ある朝、私は突然、前夜の特定の瞬間から、すべてのタイミングされたタスクが立ち往生し、走りを停止したことに気付きました。
@scheduleddefaultシングルスレッド
調査後、@scheduled Annotationを使用してデフォルトの構成を説明すると、すべてのタスクが単一のスレッドで実行されることがわかりました。睡眠のテストタスクを作成した後、他のすべてのタスクが時が来たときにトリガーされていないことを簡単に見つけることができます。
マルチスレッドを有効にする必要がある場合は、次の構成を実行し、スレッドの数を設定する必要があります。
@configurationpublic class scheduleconfig ScheduleingConfigurer {@Override public void configureTasks(ScheduleDtaskRegistrar taskRegistrar){taskregistrar.setscheduler(executors.newscheduledthreadpool(5)); }}これにより、タスクが立ち往生している場合、すべてのタスクが遅くなるという問題が解決します。
しかし、なぜタスクが立ち往生しているのですか?
httpclientデフォルトパラメーター構成
一部のタスクでは、外部サービスのRESTFULインターフェイスを定期的に要求し、HTTPClientの構成は次のとおりです。
poolinghttpclientConnectionManager connmanager = new PoolingHttpClientConnectionManager(); connmanager.setmaxtotal(maxconnection); httpclient = httpclients.custom().setConnectionManager(connmanager).build();
私が最初にHTTPCLIENTを使用したとき、私はそれについてあまり考えず、基本的にデフォルトの構成を使用しました。
ソースコードを追跡すると、上記の方法を使用して構成する場合、HTTPClientのタイムアウト時間は実際には-1であることがわかります。つまり、相手のサービスに問題がある場合、HTTPClientの要求はタイムアウトすることはなく、待機します。ソースコードは次のとおりです。
builder(){super(); this.staleconnectionCheckEnabled = false; this.redirectsenabled = true; this.maxredirects = 50; this.relativeredirectsallowed = true; this.authenticationEnabled = true; this.connectionRequestTimeout = -1; this.connecttimeout = -1; this.sockettimeout = -1; this.contentCompressionEnabled = true;}したがって、この時点でタイムアウト時間を手動で指定する必要があり、問題は解決します。例えば:
poolinghttpclientConnectionManager connmanager = new PoolingHttpClientConnectionManager(); connmanager.setmaxtotal(maxconnection); requestConfig defaultrequestconfig = requestConfig.custom().Setsockettimeout(3000).setConnectTimeout(3000).setConnectionRequestTimeout(3000).Build(); httpclient = httpclient.custom().setDefaultrEquestConfig(defaultrequestConfig).setConnectionManager(connmanager).build();
別の問題を思い出させてください
実際、defaultmaxperrouteパラメーターであるHTTPClientの使用中に遭遇した別の構成問題。
最初に使用したときにこのパラメーターに注意を払っていませんでしたが、接続プールMaxtotalに接続の最大数を設定しました。
defaultmaxperrouteパラメーターは、実際にはルートごとの接続の最大数を表します。たとえば、システムは、Google.comとBing.comの2つの他のサービスにアクセスする必要があります。 Maxtotalが100に設定され、DefaultMaxperrouteが50に設定されている場合、各サービスのリクエストの最大数は50になります。
したがって、DefaultMaxperrouteが設定されていない場合は、ソースコードを追跡します。
public PoolinghttpclientConnectionManager(final httpclientConnectionOperator httpclientConnectionOperator、final httpconnectionFactory <httpclientConnection> connefactory、final long timetolive、final timeunit tunit){super(); this.configdata = new ConfigData(); //ここで使用されるCPOOLコンストラクターメソッド2番目のパラメーターはDefaultMaxperrouteです。デフォルトは2です。This.Pool= new CPool(new InternationalConnectionFactory(this.configdata、connfactory)、2、20、Timetolive、Tunit); this.pool.setvalidatefterinActivity(2000); this.connectionOperator = args.notnull(httpclientConnectionOperator、 "httpclientConnectionOperator"); this.isshutdown = new Atomicboolean(false);}ここでは、デフォルト値がわずか2であることがわかりました。当時、並行性の高い状況で常にタイムアウトがあったのも不思議ではありません。
したがって、サービスに多くの異なる外部サービスにアクセスし、大きな並行性がある場合は、2つのパラメーターMaxtotalとdefaultmaxperrouteを構成する必要があります。
したがって、後で新しいものを使用すると、どの構成があるかをよく見ることができます。ご質問がある場合は、最初に確認する必要があります。オンラインでコードをコピーして直接使用しないでください。当時は大丈夫かもしれませんが、将来私はだまされるかもしれません。
要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。