为java中的actorsystem禁用akka.jvm-exit-on-fatal-error

时间:2016-01-07 07:27:49

标签: java multithreading akka

我正在使用akka actor系统进行多线程处理。它在正常使用情况下工作正常。但是,Akka因致命错误而关闭了JVM。请告诉我如何配置Akka以禁用java中的“akka.jvm-exit-on-fatal-error”。下面是代码。

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();
        }

    }

}

2 个答案:

答案 0 :(得分:13)

在项目中创建application.conf文件(例如sr/main/resources)并添加以下内容:

akka {
  jvm-exit-on-fatal-error = false
}

如果您已经有一个配置文件,则无需创建新的配置文件,在这种情况下,它只是添加新条目:

jvm-exit-on-fatal-error = false

小心点。让JVM在OutOfMemory等致命错误之后运行通常不是一个好主意并导致严重问题。

答案 1 :(得分:1)

有关配置详细信息,请参阅here - 您可以提供单独的配置文件,但是我对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的配置。我没有测试过这个特定的配置,因此当您尝试使用它时,有50%的可能性会出现某种JSON解析错误;为了比较,我使用哪个DOES正确解析(但不覆盖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);
}

正如您所看到的,我主要是想调整调度员。