2017-03-14 12 views
0

私のサーバーでは、すぐに50件のファイルダウンロード要求が発生する可能性があるため、1つのスレッドメインフレームが私のために動作しない可能性があります。このクラスを作成したハンドラはそれを拡張し、この並行処理がVertx

public abstract class DefaultFileHandler implements MyHttpHandler{ 

public abstract File getFile(String suffix); 

@Override 
public void Handle(RoutingContext ctx, VertxUtils utils, String suffix) { 
    new BackgroundExecutor<Void>(ctx) { 

     @Override 
     public Void onRun() throws Exception { 

      File file = getFile(URLDecoder.decode(suffix, "UTF-8")); 

      if(file == null || !file.exists()){ 
       utils.sendResponseAndEnd(ctx.response(),404); 
       return null; 
      }else{ 
       utils.sendFile(ctx, file); 
      } 
      return null; 
     } 

     @Override 
     public void onSuccess(Void result) {} 

     @Override 
     public void onException() { 
      utils.sendResponseAndEnd(ctx.response(),404); 
     } 
    }; 
} 

、ここのようにそれを使用することができ

public abstract T onRun() throws Exception; 
public abstract void onSuccess(T result); 
public abstract void onException(); 

private static final int poolSize = Runtime.getRuntime().availableProcessors(); 
private static final long maxExecuteTime = 120000; 

private static WorkerExecutor mExecutor; 

private static final String BG_THREAD_TAG = "BG_THREAD"; 

protected RoutingContext ctx; 

private boolean isThreadInBackground(){ 
    return Thread.currentThread().getName() != null && Thread.currentThread().getName().equals(BG_THREAD_TAG); 
} 

//on success will not be called if exception be thrown 
public BackgroundExecutor(RoutingContext ctx){ 

    this.ctx = ctx; 

    if(mExecutor == null){ 
     mExecutor = MyVertxServer.vertx.createSharedWorkerExecutor("my-worker-pool",poolSize,maxExecuteTime); 
    } 

    if(!isThreadInBackground()){ 

    /** we are unlocking the lock before res.succeeded , because it might take long and keeps any thread waiting */ 

    mExecutor.executeBlocking(future -> { 
     try{ 

       Thread.currentThread().setName(BG_THREAD_TAG); 

       T result = onRun(); 
       future.complete(result); 

     }catch (Exception e) { 
      GUI.display(e); 
      e.printStackTrace(); 
      onException(); 
      future.fail(e); 
     } 

       /** false here means they should not be parallel , and will run without order multiple times on same context*/ 
      },false, res -> { 

       if(res.succeeded()){ 
        onSuccess((T)res.result()); 
       } 

      }); 

    }else{ 


     GUI.display("AVOIDED DUPLICATE BACKGROUND THREADING"); 
     System.out.println("AVOIDED DUPLICATE BACKGROUND THREADING"); 

     try{ 

       T result = onRun(); 

       onSuccess((T)result); 

     }catch (Exception e) { 
      GUI.display(e); 
      e.printStackTrace(); 
      onException();   
     } 
    } 

} 

は私が

vertx.deployVerticle(MainDeployment.class.getCanonicalName(),res -> { 
      if (res.succeeded()) { 

       GUI.display("Deployed"); 

       } else { 
       res.cause().printStackTrace(); 
       } 
      }); 

    server.requestHandler(router::accept).listen(port); 
私VERTXサーバーを初期化する方法であります

、ここでは、いつ、どこで、私はそれを必要とし、これがうまく働いている

public class MainDeployment extends AbstractVerticle{ 

    @Override 
    public void start() throws Exception { 

    // Different ways of deploying verticles 

    // Deploy a verticle and don't wait for it to start 

    for(Entry<String, MyHttpHandler> entry : MyVertxServer.map.entrySet()){ 
     MyVertxServer.router.route(entry.getKey()).handler(new Handler<RoutingContext>() { 

      @Override 
      public void handle(RoutingContext ctx) { 

       String[] handlerID = ctx.request().uri().split(ctx.currentRoute().getPath()); 

       String suffix = handlerID.length > 1 ? handlerID[1] : null; 
       entry.getValue().Handle(ctx, new VertxUtils(), suffix); 

      } 
     }); 
    } 

    } 
} 

私MainDeploymentクラスですが、私はまだそうたとえば場合は、上のVERTXこのようなconcurenciesを処理するために、任意のより良い方法があるかどうか疑問に思います本当に感謝しています。おかげで多く

答えて

1

私はあなたの解決策の問題と理由を完全に理解していません。 httpアップロードを処理して複数回展開するために1つのverticleを実装してみませんか? 50同時アップロードを処理すると、vert.xのケーキになるはずです。垂直方向の名前を使用して垂直方向のを展開する場合、あなたはあなたが展開する垂直方向のインスタンスの数を指定することができます

DeploymentOptions options = new DeploymentOptions().setInstances(16); vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);

これは、複数のコア間で簡単にスケーリングするために有用です。たとえば、展開するWebサーバーのバーチクルとマシン上に複数のコアがある場合は、複数のインスタンスを展開してすべてのコアを利用することができます。

http://vertx.io/docs/vertx-core/java/#_specifying_number_of_verticle_instances

0

VERTXは、同時実行の問題が発生しないように、うまく設計されたモデルです。 一般的に、vertxはマルチスレッドモデルを推奨していません。 あなたはマルチスレッドモデルを選択した場合は、共有データについて考える必要が(取り扱いが容易ではない、ので。)

..

だけで、あなただけの唯一のイベントループエリアを分割したい場合は、の 最初のすべて、CPUコアの数を確認してください。 を入力し、インスタンスの数を設定します。

しかし、CPUが4つの場合、4つ以上のインスタンスを設定しないでください。 4つ以上の番号を設定すると、パフォーマンスは向上しません。

vertx concurrency reference

http://vertx.io/docs/vertx-core/java/