マルチスレッドにakkaアクターシステムを使用しています。通常のユースケースでは正常に機能しています。ただし、Akkaは致命的なエラーでJVMを閉じています。 Javaで「akka.jvm-exit-on-fatal-error」を無効にするようにAkkaを構成する方法を教えてください。以下はコードです。
public class QueueListener implements MessageListener {
private String _queueName=null;
public static boolean isActorinit=false;
public static ActorSystem system=null;
private ActorRef myActor;
public QueueListener(String actorId, String qName){
this._queueName = qName;
if(!isActorinit){
system=ActorSystem.create(actorId);
isActorinit=true;
}
myActor=system.actorOf( Props.create(MessageExecutor.class, qName),qName+"id");
}
/*
* (non-Javadoc)
* @see javax.jms.MessageListener#onMessage(javax.jms.Message)
*/
@Override
public void onMessage(Message msg) {
executeRequest(msg);
}
/** This method will process the message fetch by the listener.
*
* @param msg - javax.jms.Messages parameter get queue message
*/
private void executeRequest(Message msg){
String requestData=null;
try {
if(msg instanceof TextMessage){
TextMessage textMessage= (TextMessage) msg;
requestData = textMessage.getText().toString();
}else if(msg instanceof ObjectMessage){
ObjectMessage objMsg = (ObjectMessage) msg;
requestData = objMsg.getObject().toString();
}
myActor.tell(requestData, ActorRef.noSender());
} catch (JMSException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
プロジェクトにapplication.conf
ファイル(たとえばsr/main/resources
)を作成し、次のコンテンツを追加します。
akka {
jvm-exit-on-fatal-error = false
}
もちろん、すでに設定ファイルがある場合は、新しい設定ファイルを作成する必要はありません。その場合は、新しいエントリを追加するだけです。
jvm-exit-on-fatal-error = false
注意してください。OutOfMemory
のような致命的なエラーの後にJVMを実行させることは、通常は良い考えではなく、深刻な問題につながります。
構成の詳細については ここ を参照してください-個別の構成ファイルを提供できますが、akka構成に加えた変更の数が少ない場合(また、すでにいくつかのSpring構成ファイルを使用していたことを前提としています)プログラムで構成を作成してロードする方が簡単であることがわかりました。構成は次のようになります。
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
StringBuilder configBuilder = new StringBuilder();
configBuilder.append("{\"akka\" : { \"jvm-exit-on-fatal-error\" : \"off\"}}");
Config mergedConfig = ConfigFactory.load(ConfigFactory.parseString(configBuilder.toString()).withFallback(ConfigFactory.load()));
system = ActorSystem.create(actorId, mergedConfig);
これは、デフォルトのConfig
をロードし、そのjvm-exit-on-fatal-error
エントリをオーバーライドし、この新しいConfig
をActorSystem
の設定として使用します。私はこの特定の構成をテストしていないので、使用しようとすると、ある種のJSON解析エラーが発生する可能性が50%あります。比較のために、私が使用する実際の構成は正しく解析されます(ただし、jvm-exit-on-fatal-error
をオーバーライドしません)。
private ActorSystem createActorSystem(int batchManagerCount) {
int maxActorCount = batchManagerCount * 5 + 1;
StringBuilder configBuilder = new StringBuilder();
configBuilder.append("{\"akka\" : { \"actor\" : { \"default-dispatcher\" : {");
configBuilder.append("\"type\" : \"Dispatcher\",");
configBuilder.append("\"executor\" : \"default-executor\",");
configBuilder.append("\"throughput\" : \"1\",");
configBuilder.append("\"default-executor\" : { \"fallback\" : \"thread-pool-executor\" },");
StringBuilder executorConfigBuilder = new StringBuilder();
executorConfigBuilder.append("\"thread-pool-executor\" : {");
executorConfigBuilder.append("\"keep-alive-time\" : \"60s\",");
executorConfigBuilder.append(String.format("\"core-pool-size-min\" : \"%d\",", maxActorCount));
executorConfigBuilder.append(String.format("\"core-pool-size-max\" : \"%d\",", maxActorCount));
executorConfigBuilder.append(String.format("\"max-pool-size-min\" : \"%d\",", maxActorCount));
executorConfigBuilder.append(String.format("\"max-pool-size-max\" : \"%d\",", maxActorCount));
executorConfigBuilder.append("\"task-queue-size\" : \"-1\",");
executorConfigBuilder.append("\"task-queue-type\" : \"linked\",");
executorConfigBuilder.append("\"allow-core-timeout\" : \"on\"");
executorConfigBuilder.append("}");
configBuilder.append(executorConfigBuilder.toString());
configBuilder.append("}}}}");
Config mergedConfig = ConfigFactory.load(ConfigFactory.parseString(configBuilder.toString()).withFallback(ConfigFactory.load()));
return ActorSystem.create(String.format("PerformanceAsync%s", systemId), mergedConfig);
}
ご覧のとおり、私は主にディスパッチャの調整に興味がありました。