Sunday, October 11, 2015

Introduction to Netty


What is Netty ?

Netty is an open source Java NIO framework which can be used to develop network related applications.In this tutuorial I am going to exaplain basic architecture of the netty and how it is used to develop basic appilcations.  

Netty Concepts

  • Bootstraps
                  Bootstrapping is used to create netty channels which is  used to handle incoming  and outgoing connections and events through it. Basically inbound side consists of ServerBootstrap. ServerBootstrap is used to configure and create channels (TCP , HTTP .. etc)  for incoming client connections.  ServerBootstrap is extended from Bootstrap which can be used to configure client Bootstrap as well.  Client Bootstrap is used to  make connections  with backend servers.
example :-
// Configure the server.
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(4);
try {
  ServerBootstrap b = new ServerBootstrap();
  b.option(ChannelOption.SO_BACKLOG, 1024);
  b.group(bossGroup, workerGroup)
   .channel(NioServerSocketChannel.class)
   .handler(new LoggingHandler(LogLevel.INFO))
   .childHandler(new ServerInitializer());

  Channel ch = b.bind(PORT).sync().channel();

  System.err.println("Open your web browser and navigate to " +
          (SSL? "https" : "http") + "://127.0.0.1:" + PORT + '/');

  ch.closeFuture().sync();
} finally {
  bossGroup.shutdownGracefully();
  workerGroup.shutdownGracefully();
}

Here we are creating ServerBootstrap and configure with transport level parameters. You can see that it has given with two eventloop groups called master and worker. It is explained in the following sections. Basically it used for handle incoming connections.

  • EventLoop and EventLoopGroup

EventLoop is like a Java thread which is used to handle connections. There are varoiuse EventLoop implementations in netty such NioEventLoop , UDPDatagramEventLoop .. etc. EventLoopGroup is a collection of Event Loops. Basically we can define how many Event Loops should be included in the EventLoopGroup when it is creating.  When creating ServerBootstrap we have given that Master and Worker EventLoopGroups. Master EventLoopGroup is responsible for accepting incoming connections and Worker EventLoopGroup is responsible for handling IO operations of the accepted connections.Each accepted connection is bound to particular Worker EventLoop for its life time.

  • Channel and ChannelHandlerContext
 Netty channel is a  representation of an accepted connection.Netty channel is bound to a one particular  EventLoop for it is life time.  For each channel netty creates a channel pipeline and I will discuss it in the following sections. we can save attributes in channel  which can be retrieved in later calls of the channel. ChannelHandlerContext is unique for each handler in the pipeline. handler concept also describes in later part of this tutorial.  

  • Channel Handlers

Basically netty has Inbound and Outbound handlers.   Inbound handlers are executed when IO events are read from socket to application and Outbound handlers are executed when IO events are written from application to socket. Netty Handlers can be shared with netty pipelines but the recommended approach is not share handlers .Handler  has a specific logic to do some applications specific logic with incoming messages it can be a byte to message conversion , message to message conversion or message to byte conversion. There can be multiple handlers executed inside a netty pipeline.


  • Netty Pipeline
              Pipeline is a representation of a message flow of particular accepted connection. Handlers can be  integrated into pipeline and for each connection it creates a pipeline.  All the handlers in pipeline are thread safe instead if  handler is shared. Following is the sample code for pipeline creation.

public class ServerInitializer extends ChannelInitializer<SocketChannel> {

  
   @Override
  public void initChannel(SocketChannel ch) {
      ChannelPipeline p = ch.pipeline();
            p.addLast(new HttpServerCodec());
      p.addLast(new ServerHandler());
  }
}


Handlers in the pipeline are executed according to the integrated positions in the pipeline. But in Inbound path Inbound Handlers are only executed accordingly and in Outbound direction Outbound Handlers are executed.

  • Important Facts

   Do not block the handler execution throughout the handler implementation code. If handler is got blocked,  the underlying Event Loop which is executing that pipeline will be blocked. So it will affect the IO WorkerPool of netty to be get  overloaded and ultimate connection processing will be delayed.

You can execute Netty Handler in a separate WorkerPool  by providing executorservice when adding it to the channel pipeline as follows.

p.addLast(“executorservice” ,new ServerHandler());




       










Tuesday, October 6, 2015

Introduction to Java NIO

                              

           IO Operations plays an important role when it comes to integrate network level operations into software applications.Assume you are going to develop an application which analysis some incoming event stream and output important relationship between the events in the event stream and generate new events send them as separate event streams to different applications which are decoupled through network level or hardware level.


Definitely your application should listen for incoming events from the network level and write to network. So before developing the application developer should have a basic understanding of the network level operations. So in this post I would like to introduce some JAVA related IO Operation handling strategies .

Socket

A socket is one endpoint of a two-way communication link between two programs running on the network. Socket classes are used to represent the connection between a client program and a server program. The java.net package provides two classes--Socket and ServerSocket--that implement the client side of the connection and the server side of the connection, respectively.

Socket Channel

A Java NIO SocketChannel is a channel that is connected to a TCP network socket. There can be more than one SocketChannel connected to a Socket which means there can be many open connections  in one endpoint.


Blocking IO

At the beginning  of  network programming this model is used. Separate connection need to be handle by separate thread . So this method is not scalable with high number of connections for a socket.

blocking.png

Non Blocking IO

With the introduction of Java 1.4  they have introduced Non-Blocking IO which means connection processing threads are not wait for a socketchannel. so we can processed IO events in Asynchronous manner .

nonblocking.png




Reactor Pattern

Reactor pattern in the domain of Java NIO is used  to handle incoming connections and their  related operations in more scalable and accepted manner with high concurrency scenarios. Basically there is manager thread which manage connections and handover connections to worker threads carefully.  Thereafter worker threads are responsible for handling IO events for connections lifetime.

Selector
Selector is the way to  make system calls to the operating system for detect events through OS. Instead of using multiple threads , using selector which is one thread responsible for  handling multiple concurrent channels is minimized thread switching overhead and increase scalability with increasing connections. Channels are registered to selector based on operations which called Selection Keys. There are four operations where channel can fire event to Selector They are as

  • Connect
  • Accept
  • Read
  • Write
while registering a channel to selector you can specify I am interesting in this  kind of event of the channel and  as well as you can attached an object to the selector for identify the channel uniquely.

Byte Buffers
Another  interesting component in the IO Operations is Byte Buffers. Basically we have
  • Direct Byte Buffers
  • Heap Byte Buffers

Direct Byte Buffers are the  Byte Buffers which are allocated inside the memory .So allocation and deallocation has  high cost  and need to re use. But if using direct byte buffers zero copy capability can be enabled.

Heap byte buffers can be fastly allocate and deallocate in JVM heap space.

There are common Bytebuffer operations that are heavily used with Byte Buffers.ByteBuffer has index  , limit and capacity.  index is the current position of read or write. limit is the position of new data written in read mode . capacity is the maximum size  that data can be written.

  • Flip ()
                  Calling this method will be caused to switch to read mode of the byte buffer. then index will be came to lastest  read position and limit is set to maximum index of newly written data.

  • Compact()
         Enables write mode and move data to beginning of the buffer.   and update index latest value of the read position and limit to capacity.           

  • Clear()
   Enables write mode and move index to beginning of the buffer and limit to capacity.

  • hasRemaining()
before calling this buffer need to be  flip and then this will written difference between  index and limit.

Sample Http Reverse Proxy Written Using HttpCore

For better understanding and investigation of the Java NIO implementations and how to use it actually for read and write data can be seen at  [1] . This basically read the data from socket and write data to socket using Java NIO library called Http Core.