Проблема с производительностью VertX и Jetty

Я провожу эталонное тестирование для Jetty и VertX.3 для поддержки асинхронного режима. ниже мой пример кода VertX.

public class VertXSampleServer extends AbstractVerticle{
    @Override
    public void start(){
        HttpServer server=vertx.createHttpServer();
        server.requestHandler(new Handler<HttpServerRequest>() {

    @Override
    public void handle(HttpServerRequest request) {
        HttpServerResponse response=request.response();
        response.setStatusCode(HttpStatus.SC_OK);
        System.out.println("re received");
        response.putHeader("Content-Length", Integer.toString(5));
        response.write("Hello");
    }
    }).listen(9091);
  }
}

Пример сервера Jetty:

public class JettySampleAsyncServer
{
public static class EmbeddedAsyncServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
final AsyncContext ctxt = req.startAsync();

ctxt.start(new Runnable()
{
@Override
public void run()
{
System.out.println("In AsyncContext / Start / Runnable / run");
ServletResponse response=ctxt.getResponse();
byte[] result="<h1>Hello World</h1>".getBytes();
try {
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
response.setContentLength(result.length);
response.getOutputStream().write(result);

} catch (IOException e) {
e.printStackTrace();
}
ctxt.setTimeout(new Long(1000));
ctxt.complete();
}
});
}
}
public static void main(String[] args) throws Exception
{
Server server = new Server();
QueuedThreadPool queuedThreadPool=(QueuedThreadPool) server.getThreadPool();
queuedThreadPool.setMaxThreads(8);
ServerConnector serverConnector=new ServerConnector(server,1,4);
serverConnector.setHost("localhost");
serverConnector.setPort(9090);
//   serverConnector.setAcceptQueueSize(100);
server.addConnector(serverConnector);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
ServletHolder asyncHolder = context.addServlet(EmbeddedAsyncServlet.class,"/*");
asyncHolder.setAsyncSupported(true);
server.setHandler(context);
server.start();
server.join();
}
}

при тестировании VertX я получаю пропускную способность 31 запрос/мин. Но при тестировании Jetty я получаю 310 запросов/секунд. Может ли кто-нибудь объяснить мне причину такого большого разрыва в производительности. Кроме того, просто к вашему сведению, я использую Apache Jmeter для сравнительного тестирования.


person Community    schedule 03.05.2016    source источник
comment
Если для вас важна производительность, я предлагаю использовать веб-сокеты с постоянным подключением. Вы можете получить до 30 000 запросов в секунду с одним подключением. Если вы используете протокол более низкого уровня, вы можете достичь нескольких 100 000/msg в секунду.   -  person Peter Lawrey    schedule 03.05.2016
comment
Мы находимся на начальном этапе проектирования и должны решить, какой из них выбрать: причал или VertX. Поэтому я провожу для них тестовое тестирование с помощью примера реализации. Пожалуйста, дайте мне знать, если я что-то пропустил   -  person    schedule 03.05.2016
comment
30 000 сообщений в секунду, которые я получил, используя Jetty. Я подозреваю, что проблема в том, как вы тестируете. например если вы создаете соединение и разрываете его, это может быть на несколько порядков дороже, чем работа, которую выполняет сервер.   -  person Peter Lawrey    schedule 03.05.2016
comment
Ваш сервлет не использует асинхронный ввод-вывод Servlet, здесь вы не сравниваете яблоки с апельсинами. Вы все еще используете блокирующий ввод-вывод в своем примере.   -  person Joakim Erdfelt    schedule 03.05.2016
comment
Откровенно говоря, с этим простым тестовым случаем вы получите лучшую производительность от Jetty, удалив AsyncContext и используя простые/скучные сервлеты. (Вы бы использовали меньше потоков, и весь ответ помещается в один буфер, что также делает асинхронный ввод-вывод не очень полезным)   -  person Joakim Erdfelt    schedule 03.05.2016
comment
Я не понял тебя, Йоаким. Не могли бы вы исправить, если это возможно?   -  person    schedule 03.05.2016
comment
Также обратите внимание, что эталонные тесты, сообщающие о запросах в секунду, на самом деле измеряют задержку. Если вы хотите узнать сквозной путь, вам нужно указать конкретный сквозной путь и сообщить о задержке. Если задержка соответствует требуемому качеству обслуживания, ваш сервер может поддерживать эту пропускную способность.   -  person gregw    schedule 04.05.2016
comment
Чтобы ответить на ваш вопрос, я не понял вас, joakim, он указывает, что нет особых причин для перехода на асинхронный режим, если все, что вы делаете, это запускаете другой поток, который блокирует ввод-вывод. Когда дело доходит до асинхронных проблем, всегда есть два, т.е. единственная точка использования асинхронных сервлетов - это если у вас есть что-то еще асинхронное, с чем вам нужно взаимодействовать (асинхронный ввод-вывод, асинхронный клиент REST и т. д.).   -  person gregw    schedule 04.05.2016
comment
Я понимаю тебя сейчас. Кроме того, VertX ведет себя так же? Когда я пробую VertX с большим количеством одновременных подключений, скажем, 150, я вижу постоянную ошибку 50%. Любая идея о том, что будет идти не так? У меня есть рабочая станция с 4 ядрами процессора и 8 логическими процессорами.   -  person    schedule 04.05.2016
comment
Вы убиваете производительность, используя System.out.println при обработке запросов.   -  person Jonas    schedule 04.05.2016


Ответы (1)


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

public class VertXSampleServer extends AbstractVerticle {
  @Override
  public void start() {
    HttpServer server=vertx.createHttpServer();
    server.requestHandler(new Handler<HttpServerRequest>() {
      @Override
      public void handle(HttpServerRequest request) {
        HttpServerResponse response=request.response();
        // by default it is 200 so this is optional
        response.setStatusCode(HttpStatus.SC_OK);
        System.out.println("re received");
        response.putHeader("Content-Length", Integer.toString(5));
        // what you're doing here is wrong you should end the response
        // response.write("Hello");
        response.end("Hello");
        // You should use write if you are going to use chunked responses
        // and the last one should be a end to notify that the request
        // is finished
      }
    }).listen(9091);
  }
}

Полная документация по обработке http-ответа находится здесь.

Это объяснит разницу между фрагментированной записью (что вы сделали) и окончанием ответа.

person Paulo Lopes    schedule 04.05.2016
comment
спасибо... теперь я не вижу тайм-ауты, и производительность также улучшилась. - person ; 04.05.2016