Wednesday, October 15, 2014

Let's do our own full blown HTTP server with Undertow

In Let's do our own full blown HTTP server with Netty 4 we've spent a lot of man-hours to build our light embeddable web server and later in the article Performance analysis of our own full blown HTTP server with Netty 4 it was compared to Glassfish (powered by Grizzly). Lets try out Undertow from JBoss that powers Wildfly.
Undertow is
a flexible performant web server written in java, providing both blocking and non-blocking API’s based on NIO.
and even more
Undertow has a composition based architecture that allows you to build a web server by combining small single purpose handlers. This gives you the flexibility to choose between a full Java EE servlet 3.1 container, or a low level non-blocking handler, to anything in between.
So one can Combine Undertow Handlers and Servlet.
The implementation will take 5 mins and take a few lines:
Undertow server = Undertow.builder()
        .addHttpListener(conf.getPort(), conf.getHost())
        .setWorkerOption(org.xnio.Options.WORKER_TASK_CORE_THREADS, conf.getTaskThreadPoolSize())
        .setHandler(new HttpHandler() {
            @Override
            public void handleRequest(final HttpServerExchange exchange) throws Exception {
                if (exchange.isInIoThread()) {
                    exchange.dispatch(this);
                    return;
                }
                exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
                exchange.getResponseSender().send("Ok");
            }
        }).build();
server.start();
See the UndertowBackend source.
Despite there is no blocking calls we send response from worker thread pool and not from IO thread pool. This is for testing purposes to determine thread switching overhead. The same was done in NettyBackend. On the ordinary machine
cat /proc/cpuinfo | grep model\ name
model name      : Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
model name      : Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
model name      : Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
model name      : Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
model name      : Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
model name      : Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
model name      : Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
model name      : Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
cat /proc/meminfo | grep MemTotal
MemTotal:       16359820 kB
One has following numbers
weighttp$ build/default/weighttp -n 1000000 -k -c 100 http://localhost:9999/
weighttp - a lightweight and simple webserver benchmarking tool

starting benchmark...
spawning thread #1: 100 concurrent requests, 1000000 total requests
progress:  10% done
progress:  20% done
progress:  30% done
progress:  40% done
progress:  50% done
progress:  60% done
progress:  70% done
progress:  80% done
progress:  90% done
progress: 100% done

finished in 4 sec, 358 millisec and 479 microsec, 229437 req/s, 28455 kbyte/s
requests: 1000000 total, 1000000 started, 1000000 done, 1000000 succeeded, 0 failed, 0 errored
status codes: 1000000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 127000000 bytes total, 125000000 bytes http, 2000000 bytes data
On the same host for NettyBackend
weighttp$ build/default/weighttp -n 1000000 -k -c 100 http://localhost:9999/
weighttp - a lightweight and simple webserver benchmarking tool

starting benchmark...
spawning thread #1: 100 concurrent requests, 1000000 total requests
progress:  10% done
progress:  20% done
progress:  30% done
progress:  40% done
progress:  50% done
progress:  60% done
progress:  70% done
progress:  80% done
progress:  90% done
progress: 100% done

finished in 5 sec, 521 millisec and 608 microsec, 181106 req/s, 17332 kbyte/s
requests: 1000000 total, 1000000 started, 1000000 done, 1000000 succeeded, 0 failed, 0 errored
status codes: 1000000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 98000000 bytes total, 94000000 bytes http, 4000000 bytes data
Note, test design is a complex task, numbers above are too rough and just for your consideration.

Conclusion. Undertow is strong and versatile overall, one can build something low-level and mix it with Servlets 3.1, thus a good choice for many tasks that require embeddable and/or high load and/or Servlet 3.1 standard compliant HTTP server.

No comments:

Post a Comment