netty: asynchronous data transfer

31
Netty List("Asynchronous", "data", "transfer") ::: List("practical", "aspects") Victor Cherkassky "vcherkassky@gmail\.com"

Upload: victor-cherkassky

Post on 20-Aug-2015

5.947 views

Category:

Technology


3 download

TRANSCRIPT

NettyList("Asynchronous", "data", "transfer")

::: List("practical", "aspects")

Victor Cherkassky

"vcherkassky@gmail\.com"

What is NettyIO library

IOcat Files > Networking

What is NettyIO libraryasynchronous

ChannelFuture future = channel.write(message) future.addListener(WRITE_COMPLETE_LISTENER)

What is NettyIO libraryasynchronousnon-blocking

      /**        * This method blocks until input data is available        */

InputStream.read()

What is NettyIO libraryasynchronousnon-blockingmulti-protocol

HTTP | WebSocket | Protobuf| Binary

TCP | UDP

blocking vs non-blockingblocking (OIO)

non-blocking (NIO)

InputStream is = new FileInputStream("input.bin");int byte = is.read(); // current thread waits for result or error

while (true) { selector.select(); // requesting events from multiple channels Iterator it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectorKey key = (SelectionKey) it.next(); handleKey(key); it.remove(); }}

blocking vs non-blockingHardware blocking write

blocking vs non-blockingHardware non-blocking write: DMA

blocking vs non-blocking

OSselect()/poll() - traditional POSIX polling O(n)epoll() - event-based polling O(1), Linux 2.5.44+ kqueue - FreeBSD, Mac OS XI/O Completion Ports - Windows NT 3.5+, Solaris 10+

blocking vs non-blocking

JavaSelectableChannel.register(selector) - blocking operation,registers an "interest" for IO eventsSelector.select - non-blocking operation, checks foroccurred events

blocking vs non-blocking

Java OSChannel.register & Selector.select

select() / poll() / kqueueI/O Completion Portsepoll() - Java 1.6+

Thread model

Tomcat1 request = 1 thread

fast for ~1000 clientstoo much memory

Thread model

Node.jsall requests = 1 thread

super scalablelimited error handling

Thread model

Nettymany requests = 1 thread

flexible model

Netty web Server

Netty web Client

Channel Pipeline

All terms togetherChannel (socket read/write)channel Buffer (byte array)channel Event (message)channel Pipeline (message bus)channel Handler (message handler)

Upstream Event (from socket)Downstream Event (to socket)

Creating an HTTP serverSet up thread pools

boss pool for handling incoming connectionsworker pool for processing IO

private final Executor bossPool = Executors.newCachedThreadPool();private final Executor workerPool = Executors.newCachedThreadPool();

Creating an HTTP serverProvide ChannelFactory

private final ChannelFactory channelFactory = new NioServerSocketChannelFactory(bossPool, workerPool);

Creating an HTTP serverSet up PipelineFactory

private final ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline p = Channels.pipeline(); p.addLast("httpServerCodec", new HttpServerCodec()); p.addLast("handler", new CustomRequestHandler(allChannels)); return p; }};

Creating an HTTP serverPut all together with Bootstrap

private final ServerBootstrap bootstrap = new ServerBootstrap(channelFactory);

. . .

bootstrap.setPipelineFactory(pipelineFactory); // Options for a parent channel - it accepts connectionsbootstrap.setOption("localAddress", new InetSocketAddress(port));bootstrap.setOption("reuseAddress", true);

// Options for its children - they process IObootstrap.setOption("child.tcpNoDelay", true);bootstrap.setOption("child.keepAlive", false);

Creating an HTTP serverWriting a custom handler

class CustomHandler extends SimpleChannelUpstreamHandler { . . . @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { HttpRequest req = (HttpRequest) e.getMessage(); // produce response and write it to a channel HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK); ChannelFuture future = Channels.write(ctx.getChannel(), res); future.addListener(ChannelFutureListener.CLOSE); }}

Creating an HTTP serverGather channels for future closingprivate final ChannelGroup allChannels = new DefaultChannelGroup() . . .// again inside our custom handlerclass CustomHandler extends SimpleChannelUpstreamHandler { . . . @Override public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { Channel channel = e.getChannel(); allChannels.add(channel); }}

Creating an HTTP serverRelease resources

close gathered channelsrelease external resources

allChannels.close().awaitUninterruptibly();bootstrap.releaseExternalResources();

TCPnodelay, TCPkeepaliveRemember that bootstrap code?

What do these options mean?

// Options for its children - they process IObootstrap.setOption("child.tcpNoDelay", true);bootstrap.setOption("child.keepAlive", false);

TCP keepAlive

prolongs each TCP connectionmakes NAT router happy

TCP noDelayNagle's algorithm

glues up small TCP packetstries to reduce bandwidthincreases latency

TCPnodelay, TCPkeepalive

To use, or not to use?

Don't ask,

measure!