Monday, July 9, 2018

Java WebSocket on distributed system

Let say you have a Server Java application that sometime needs to send message to client which is a smart device or a mobile app using Websocket.
Also assuming that your server application is designed to run with multiple instances for High Availability supporting.

And below is the scenario that we usually face (reference above figure):
Device/ Mobile app (1) opens a websocket connection to the server. The websocket request arrives the load balancer (LB)  first and then the LB forwards it to the Server app instance 1. So a websocket instance is created on the Server app instance 1 (3).
Next, user via a web browser accesses to the server, so there is a HTTP request (2) to be sent to the LB. The LB in turn will dispatch the HTTP request to either one of two Server app instances depending on the work load of each app instance. This HTTP request causes the server to send a message, for example, to the device/mobile app using websocket.
The actions flow should be fine if the LB forwards the HTTP request to the Server app instance 1 (3). 

However what happens if the LB forwards the HTTP request to the Server app instance 2 (4) ?.

Because the Server app instance 2 doesn’t have the websocket instance which is created previously by the Server app instance 1 so the server cannot send message to device/mobile app. Clearly, this is an issue.

In order to overcome this issue, you may find a way to pass the websocket instance to the Server app instance 2 so the Server app instance 2 can use this websocket instance to send message to device/mobile app. Unfortunately, this solution will not work because the websocket instance is not a Serializable object so it is impossible to Serialize and send it over the network. Even you use other programming language then this is also true because the websocket instance is an object that its status changes by time. So you cannot simple to package and send it somewhere.

So a good solution here is to send the message to the server app instance which is holding the websocket instance. In this solution, you need to do two things: First, to find which Server app instance is holding the websocket instance and the second is to send the message to that found server app instance.

In this example, the server app instance 2 needs send the message to the server app instance 1 because the websocket instance locates on the server app instance 1.

Usually, we need a message queue service provider as RabbitMQ (AMQP implementer) or ActiveMQ (JMS implementer) to exchange messages between these Server app instances (5). Also the message should be designed to be able to serialize, usually it is a POJO class.

Note: if you design a micro-service to only take care for all websocket connections. Then the issue is still same if this micro-service runs with multiple instances. Micro-services vs multiple app instances.

No comments:

Post a Comment