JVMの実際のチューニング(スペースが原因のサービス例外)

JVMの実際のチューニング

問題の説明

特定のプロジェクトには、3者間サービスを必要とするHKUSTiFLYTEKの音声変換サービスを使用するテキストから音声へのサービスがあります。その変換サービスは時間のかかる操作であるため、公式デモではデータ変換操作にWebSocketを使用します。スレッドプールは、プロジェクトで呼び出しを行うために使用されます。同時に、iFLYTEKの音声合成には長さ制限があります。公式の音声合成は[8000バイト、約2000漢字]であるため、セグメントで合成する必要があります。

ある日、音声が再生できないとの回答がありましたが、サービスログを確認したところ、購入したサービスの有効期限が切れ、残りのサービスを買い戻し、パラメータを変更し、以前のパラメータを使用できなかったためです。 。パラメータを変更してデプロイメントを更新した後、サービスは通常に戻ります。数日後、お客様から音声を再生できないとの回答があり、ログを確認したところ、ほとんどが成功し、一部は失敗したことがわかりました。

チューニングプロセス

ログを見ると、一部の障害は接続障害が原因であることがわかり、対応するアプリケーションプロセス番号はjpsから見つかりました。

次に、上位の-Hp PIDを使用してCPUとメモリの占有率を確認します。これらは、すべて通常の占有率です。

スレッドプールを使用しているため、スレッドプールがいっぱいであると思われます。スタックpidでスレッドプールを確認したところ、いっぱいであることがわかりました。

"OkHttp ConnectionPool"#48デーモンprio = 5 os_prio = 0 tid = 0x00007f8d90002800 nid = 0x2a7a in Object.wait()[0x00007f8dea5a5000]
   java.lang.Thread.State:TIMED_WAITING(オブジェクトモニター上)
	java.lang.Object.wait(ネイティブメソッド)で
	java.lang.Object.wait(Object.java:460)で
	okhttp3.internal.Util.waitMillis(Util.kt:536)で
	okhttp3.internal.Util.lockAndWaitNanos(Util.kt:522)
	-ロックされた<0x000000076e9394f8>(okhttp3.internal.connection.RealConnectionPool)
	okhttp3.internal.connection.RealConnectionPool $ cleanupRunnable $ 1.run(RealConnectionPool.kt:49)で
	java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)で
	java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624)で
	at java.lang.Thread.run(Thread.java:748) "pool-1-thread-3"#46 prio = 5 os_prio = 0 tid = 0x00007f8dd4013000 nid = 0x2a78条件[0x00007f8deaaa8000]で待機
   java.lang.Thread.State:WAITING(パーキング)
	sun.misc.Unsafe.park(ネイティブメソッド)で
	-<0x000000076ea3d738>を待機するためのパーキング(java.util.concurrent.CountDownLatch $ Sync)
	java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)で
	java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)で
	java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)で
	java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)で
	java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)で
	com.baiying.trstts.factory.XfTts.getPcm(XfTts.java:206)で
	com.baiying.trstts.factory.XfTts.text2speechV3(XfTts.java:236)で
	com.baiying.trstts.controller.TextToSpeechControllerV3.lambda $ text2Speech $ 0(TextToSpeechControllerV3.java:56)で
	com.baiying.trstts.controller.TextToSpeechControllerV3 $$ Lambda $ 426 / 909090985.run(不明なソース)で
	java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)で
	java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624)で
	java.lang.Thread.run(Thread.java:748)で

例外情報から、CountDownLatchがスレッド全体をブロックし、スレッドの終了に失敗したことがわかります。コードのウォークスルーを通じて、countDown()は、プログラムが正常に終了したときにのみスレッドをウェイクアップし、続行することがわかりました。スレッドはウェイクアップされないため、countDown()がプログラムに追加され、失敗したときにスレッドがウェイクアップされます。プログラムが再デプロイされた後、プログラムは正常です。

問題を防ぐために、今回はプログラムログを監視し、失敗した記事を再変換しました。スレッドは正常に終了できますが、変換は失敗します。テキストの厳密な分析と複数の変換テストの後、テキストが傍受されました。しばらく観察したところ、異常はありませんでした。16進ソフトウェアで確認したところ、2文字が違うことがわかりました。どちらもスペースですが、最初のスペースは半幅入力方式です。 16進法でのスペースは20、全幅入力方式でのスペースはE38080です。次に、全幅入力方式でのスペースを削除するようにプログラムを変更し、変換をやり直してください。サービスは正常です。


おすすめ

転載: blog.51cto.com/15114835/2656975