私はプログラミングが初めてで、ソフトウェアのパフォーマンスに問題があります。基本的に、データを取得して it( ) に対して 100 ループを実行しますi=0;i<100;i++
。そのループ中に、プログラムは 3 つの決定のうちの 1 つを行い、データを処理し続けるか、破棄するか、そのバージョンをキューに送り返して処理します。各スレッドが行う個々の作業は非常に小さいですが、かなりの量があります (これが、水平方向にスケーリングするためにキュー サーバーを使用している理由です)。
私の問題は、CPU全体に近づくことは決してなく、私のプログラムはコアあたり約40%で実行されます。プロファイリング後、ほとんどの時間はキューからのデータの送受信に費やされているようです ( com.rabbitmq.client.impl.Frame.readFrom(DataInputStream)
and と呼ばれる部分で約 64% com.rabbitmq.client.impl.SocketFrameHandler.readFrame()
、約 17% がキューの形式で取得されます (40% から減少しました)。前) 残りはプログラムのロジックに費やされます)。明らかに、私は自分の仕事をより速く完了させたいと思っており、キューであまり時間を費やさないようにしたいと考えています。使用できるより良い設計があるかどうか疑問に思っています。
私のコードは実際にはかなり大きいですが、これが何をするかの概要は次のとおりです。
- キュー サーバー (rabbitmq および Java) への接続を作成します。
- CPUコアと同じ数のスレッドをフォークします(同じ接続を使用)
- スレッドからのデータは
- 各スレッドは、共有接続を使用してキュー サーバーへの独自のチャネルを作成します。
- サーバーをプールし、確認応答なしで X 個のメッセージを取得する while ループがあります。
- メッセージを受け取ったら、スレッド エグゼキューターを使用して、ジョブの実行中に確認応答を送信します
- メッセージを解析し、ループを実行します
- データがキューに送り返された場合は、それをスレッド エグゼキュータに送信して送り返し、プログラムが次のデータ セットに進むことができるようにします。
私がした奇妙なことの1つは、承認とキューへの送信にスレッドエグゼキューターを使用していますが、public void run()
私のプログラムはこの単一のプロセスに専念しているため、メインのワーカースレッドはフォークされたスレッドです(を使用)動作する準備ができている X スレッドの数 (そして、それらのシャットダウン/再生成はありませんでした)。メインプログラムの実行中に残りが待機/キューに入れられる可能性があると考えたため、残りはスレッドにあります。
より良い設計方法がわからないため、データの収集/送信にかかる時間が短縮されます。私が支援できるデザイン、rabbitmq、Java のものはありますか?