This presentation on building servers explains what is Netty, why choosing it and shows how with very little code you can build an asynchronous app server.
2. What is Netty?
Asynchronous event-driven network
application framework for rapid development
of maintainable high performance protocol
servers & clients
3. Meaning...
● A set of abstractions to build your server with:
– Good performance
– Low resource consumption
– Unified API for various transport types
– Customizable thread model
– Good documentation and examples!
4. When to use it?
● Good choice to build an application server
– Allows to implement custom protocols
– Don't need to worry (too much) about concurrency
– Layered architecture allows to reuse code
● And not so good for building a web application
– Little support for web technologies
– There are much better tools out there
5. The basic API
● Channel: think of it as a connection
● MessageEvent: represents the transmission or
reception of a message
● ChannelHandler: reacts to events that happen in
a Channel & contains the app logic
● ChannelPipeline: is an ordered list of
ChannelHandlers
6. Socket.read()
Socket.write()
Upstream Handler
Upstream / Downstream
Handler
Downstream Handler
The basic API
Upstream Handler
ChannelPipeline
7. Example: echo server
public class EchoServer {
public static void main(String[] args) {
// ChannelFactory manages the creation/removal of Channels
ChannelFactory factory = new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
// Using helper class to boostrap...
ServerBootstrap bootstrap = new ServerBootstrap(factory);
// Define our ChannelPipelines
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
ChannelPipeline pipeline = getPipeline();
pipeline.addLast("echoHandler", new EchoHandler());
return pipeline;
}
});
bootstrap.bind(new InetSocketAddress(8080)); // That's all!
}
8. Example: echo server
public class EchoHandler extends SimpleChannelUpstreamHandler {
@Override
public void messageReceived(ChannelHandlerContext ctx,
MessageEvent e) throws Exception {
// ctx allows to access to the Channel and ChannelPipeline
Channel ch = ctx.getChannel();
// In Netty3.6 Messages are of class Object
// This is improved in Netty 4 where ChannelHandlers are
// typed with the message they handle
ch.write(e.getMessage());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx,
ExceptionEvent e) {
// Something unexpected: closed connection, timeout?
e.getCause().printStackTrace();
Channel ch = e.getChannel();
ch.close();
}
9. Thread model
● One boss thread for each socket. Accepts
connections and passes them to the workers
● A worker thread performs non-blocking logic
for one or multiple Channels
● If some blocking operations are needed (e.g.
access to DB or files), those ChannelHandlers
must be moved to another executor
10. Example: webservice
public class WebServicePipelineFactory implements
ChannelPipelineFactory {
private static final ExecutionHandler executionHandler =
new ExecutionHandler(
new OrderedMemoryAwareThreadPoolExecutor(
16, 1048576, 1048576));
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline p = pipeline();
p.addLast("decoder", new HttpRequestDecoder());
p.addLast("aggregator", new HttpChunkAggregator(65536));
p.addLast("encoder", new HttpResponseEncoder());
p.addLast("deflater", new HttpContentCompressor());
// The executor is shared among pipelines. All handlers
// added after will be executed in another thread pool
p.addLast("executor", executionHandler);
p.addLast("myHandler", new MyBlockingHandler());
return p;
}