2016-09-25 6 views
2

Я пытаюсь масштабировать приложение, которое делает вызов блокировки для внешнего применения для извлечения некоторых данных (запрос и порядок ответа не имеет значения)работник verticles не обрабатывает запросы параллельно

Так, его блокирующий вызов, как описанных в документах vertx, я использую вертикальную рабочую станцию ​​с пулом работников, установленным в 5, и я развернул 5 экземпляров рабочей вертикали

Когда я отправляю несколько запросов (когда я тестировал, я просто уволил 3 запроса), хотя моя вертикаль определяемый как рабочий с несколькими экземплярами с достаточными рабочими потоками для параллельной обработки моих запросов, они не обрабатываются одновременно, похоже, что они обрабатываются последовательно (см. журналы belo w)

Я также попытался создать одну главную вершину и 4 рабочих вертикальных элемента (ручка блокировки вызова), где начальный запрос от клиента получен на главной вершине, мастер отправляет запрос работнику по шине событий, и он отвечает обратно но даже таким образом я вижу такое же поведение, как описано выше.

Пожалуйста, предложите, если я что-то неправильно понял и если я пытаюсь достичь параллелизма неправильным образом. Если это так, пожалуйста, предложить то, что лучший способ достижения параллелизма для этого случая использования

VertxMain.java 

public class VertxMain { 
public static final Logger LOG =Logger.getLogger(VertxMain.class.getName()); 
public static void main(String[] args) {  
MyFirstVerticle mfv = new MyFirstVerticle(); 
DeploymentOptions deploymentOptions = new DeploymentOptions().setWorker(true).setInstances(5); 
    Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(5)); 
    vertx.deployVerticle(MyFirstVerticle.class.getName(), deploymentOptions, res ->{ 
     if(res.succeeded()) { 
      LOG.info("first verticle deployed"); 
     } else{ 
      LOG.info("first verticle failed to deployed" + res.cause()); 
     } 
    }); 

MyFirstVerticle.java 

public class MyFirstVerticle extends AbstractVerticle { 
public static final Logger LOG = Logger.getLogger(MyFirstVerticle.class.getName()); 
Integer requestCount = 0; 

@Override 
public void start(Future<Void> fut) { 
    InputStream is = this.getClass().getClassLoader().getResourceAsStream("qa.properties"); 
    Scanner sc = new Scanner(is); 
    String line = sc.nextLine(); 

    Router router = Router.router(vertx); 

    router.route("/qa").handler(routingContext -> { 
     requestCount++; 
     Date d = new Date(); 

     System.out.println("Received request #" + requestCount.toString() + " on " +d.toString()); 
     try { 
       LOG.info("Processing request"); 
       Thread.sleep(20000); 
       d.setTime(System.currentTimeMillis()); 
       System.out.println("Responding to request #" + requestCount.toString() + " on " +d.toString()); 
      } catch (Exception e) { 
      } 

     routingContext.response().end("<h1>Hello from my first " + 
       " Vert.x 3 application using " + Thread.currentThread().getName() + line + "</h1>"); 
    }); 

    vertx 
    .createHttpServer() 
    .requestHandler(router::accept) 
    .listen(8081, result -> { 
     if (result.succeeded()) { 
      LOG.info("Webserver started to serve requests!!"); 
      fut.complete(); 
     } else { 
      fut.fail(result.cause()); 
     } 
    }); 
} 

Журналы:

INFO: first verticle deployed 
Received request #1 on Sun Sep 25 11:06:10 EDT 2016 
Sep 25, 2016 11:06:10 AM com.myvertx.MyFirstVerticle lambda$0 
INFO: Processing request 
Responding to request #1 on Sun Sep 25 11:06:30 EDT 2016 
Received request #2 on Sun Sep 25 11:06:30 EDT 2016 
Sep 25, 2016 11:06:30 AM com.myvertx.MyFirstVerticle lambda$0 
INFO: Processing request 
Received request #1 on Sun Sep 25 11:06:36 EDT 2016 ->(*Looks like request is routed to a different instance of the verticle*) 
Sep 25, 2016 11:06:36 AM com.myvertx.MyFirstVerticle lambda$0 
INFO: Processing request 
Responding to request #2 on Sun Sep 25 11:06:50 EDT 2016 
Responding to request #1 on Sun Sep 25 11:06:56 EDT 2016 
+1

Не конечно, что не так в вашем тестировании. Просто попробовал свой пример с 'parallel -j 10 sh -c 'curl http: // localhost: 8081/qa 2>/dev/null; echo '- 1 2 3 4 5 6 7 8 9 10' и запросы выполняются 5 на 5, как и ожидалось. – tsegismont

+0

@ tsegismont да вы правы - я только что отправил свой ответ. Я был связан с моим методом тестирования – Laavaa

ответ

2

Проблемы был частично с моим тестированием подхода - я выпустил несколько запросов от различных вкладок & браузера становился обрабатываемыми последовательно, как говорят выше журналы (я гавань узнал ответ, почему) поэтому я написал простой клиент асинхронного и выпустил несколько запросов одновременно, и они становились обрабатываться параллельно из разного работника verticles

я сторона отслеживается моим тестированием, и я думаю, что я говорил немного слишком рано, следовательно, разместить свои выводы

3

В VertX нормальный Verticle связан с циклом обработки событий. Поэтому любой запрос на эту вертикулу должен ждать, пока цикл события не станет свободным; даже если другой экземпляр одной и той же вершины не запущен. Рабочая вертикаль расслабляет это, разрешая запуск вертиляции в любом рабочем потоке, но экземпляр рабочей вертикали не может обрабатывать два запроса одновременно. Чтобы идти еще дальше, вы можете использовать многопоточные рабочие вертикали, которые могут выполнять несколько запросов одновременно.

Чтобы ответить на ваш вопрос, вы можете либо создать несколько экземпляров рабочих вертикалей, либо создать многопоточную рабочую вершину.

вы можете найти более подробную информацию на http://vertx.io/docs/vertx-core/java/#_verticle_types

+0

Но если есть несколько экземпляров рабочих вертикалей и достаточных рабочих потоков, он должен обрабатывать несколько запросов параллельно. Не нужно иметь многопоточную рабочую вершину – Laavaa

+0

Многопоточный работник здесь не нужен. Если развертывается несколько экземпляров вертиляции, веб-запросы могут обрабатываться параллельно. – tsegismont