Rest Over JSON or plain old sockets for communication


August 31, 2014 . Comments
Tags: java REST SOA JSON XML

 
 
  

ReST - Representational State Transfer) over JSON (JavaScript Object Notation) is the 1st choice when we try to expose services to the outside world. Though in recent times Web Sockets are making developers think as a replacement as REST APIS are too chatty and increase the messages sent over the network.

The community choose ReST over SOAP as ReST is further light weight and doesnot need to adhere to a specific schema like SOAP. ReST is light weight built on top of the http stateless protocol where it supports the operations of CRUD. In short it is no way different from how we write a servlet or any other webpage, in short just a browser is enough to communicate with ReST. The framework is more fine tuned for services that can be represented in the form of resources ex:- product will be a resource and we would suppot the below 4 operations on product with rest.

Create, Read, Update, Delete operations can be used to access a resource using the html methods POST, GET, PUT and DELETE to do the respective operation.

MyKong has a simple example to show how the Get and POST are implemented and accessed with ReST service.

Some of the advantages of using ReST

Disadvantages of using ReST. I have to be clear when i say disadvantages of ReST, it is mostly the disadvantages of how the servers and the protocol is implemented using the ReSTFUL architecture.

HttpRequest

GET http://localhost:9998/helloworld HTTP/1.1\r\n
Accept-Encoding: gzip,deflate\r\n
Host: localhost:9998\r\n
Connection: Keep-Alive\r\n
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)\r\n

HttpResponse

HTTP/1.1 200 OK\r\n
Transfer-encoding: chunked\r\n
Content-type: text/json\r\n
Date: Wed, 20 Aug 2014 23:34:17 GMT\r\n
 \r\n
Hello World\r\n

A total of 285*2 (548) bytes transferred to and from the service. Considering SOAP the ReSTFul Services are less chatty. I used SOAP UI to get these headers and I used the browser it would result in more byte transfer.

In order to verify the above theory I tried to do performance tests and figure out the metrics

Code used to perf test using URLConnection

Code for client thread to execute multiple gets at a time

Test results : - total time spent for 2000000 calls - 24 mins 52 secs 177 ms 539 Us

Test results from JVM metrics :-

RestClient metrics

Metrics with the httpcomponents is way worse than using urlconnection so not showing that here.

WebSockets

Websockets are a viable alternative to ReST API. But they are very simillar in the sense each request has similar kind of headers transfered back and forth. A socket can be upgraded and used for full duplex communication which is a biggest advantage over ReST. This advantage makes it viable to be used for writing a driver API for database based solutions. The biggest disadvantage with websockets is it is a very basic infrastructure on which we will have to build everything. If I have to choose WebSockets I can choose Sockets.

Test results : - total time spent for 2000000 calls - 13 mins 45 secs 636 ms 583 Us

Test results from JVM metrics :-

RestClient metrics

Sockets

I thought about my first java class where we built a chat application using plain old sockets. When we want to support more than 50,000 requests per second per server, the biggest bottleneck is the size of the message sent back and forth over the network. A gigabit network can support a maximum number of bytes per second is ((10243)/8)*60% leaving 40% for other system monitoring overhead = 80,530,636 bytes. Any distributed No-SQL solution will have to deal with its own overhead if i assume we get 40% writes and 60% reads on a specific machine that means 40% of the requests have to have a hop to another machine to resolve conflict that leaves us with just 60% of the network of 80,530,636 = 48,318,381 bytes.

If we use 700 bytes for communication for each read/write we end up with 69,026 requests per second. I would say if the system keeps its data communication in this mark it should be ok in meeting the 50,000 to 70,000 requests per second per machine. If we assume that traces are run on the system we will be loosing a lot of bandwidth for that. It is safe to assume that by implementing using sockets and having very low overhead for point to point communication this system can support minimum 50,000 requests per second per node on a healthy state.

Picture below shows what the client server code does. Client server architecture for banyan

The code used to verify performance with client API calls.

Test results : - total time taken for completion of 2000000 calls - 8 mins 37 secs 780 ms 122 Us

Test results from JVM metrics :-

SocketClient metrics

Server side code for the socket

The class responsible for servicing simple requests

Test metrics from server side :-

SocketClient metrics

From this, More than 50,000 requests per second is defenitely acheivable on the right hardware.

Advantages:-

Disadvantages:-

The hardware used for the performance tests are below:

The total round trip time depends on the network and i have seen average network lag of 300 Us to 9 ms per request for a communication bytesize of less than 1k for any of the above technologies we choose. This network lag begs for the need for compression, when the message size increases which i shall discuss in my next blog.

The above tests are not a apple to apple comparison as the tests on websockets and Rest API i used hello world example and in the socket case I used actual data gets from Banyan with byte size varying from 500 bytes to 1200 bytes of actual data including serialization and deserialization.

For the reason of security and availability of admin operations it would not be a bad idea to implement a tomcat application on top of this framework. Just a thought for the future.



Comments Section

Feel free to comment on the post but keep it clean and on topic.