DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Popular
  3. Open Source
  4. Open Source Messaging Queue for Lightning-Fast Client Server Comms

Open Source Messaging Queue for Lightning-Fast Client Server Comms

Take a look at how this team found better performance of their client-server application communication through open source framework ZMQ.

Łukasz Mądrzak user avatar by
Łukasz Mądrzak
CORE ·
Sep. 30, 18 · Presentation
Like (9)
Save
Tweet
Share
6.46K Views

Join the DZone community and get the full member experience.

Join For Free

In the recent past, I’ve been working on a big IoT project that has taught me an invaluable lesson about transferring data from client to server. And how to do it fast. Extremely fast. I thought I’d share what I’ve learned with you good people and maybe you can benefit, too.

I will give you some context first without revealing any trade secrets. All you need to know is that we were working with a device (Client) that gathered a lot of data. The device wasn’t stationary, so access to the internet couldn’t be taken for granted. An important requirement was that we needed the data to be transferred to the Server as quickly as possible. Ideally, it would have been instant, but we don’t live in an ideal world and we had to settle for the second best thing. Obviously, the transfer was to be performed in a safe and secure manner.

Our first approach was to use a REST API. It’s very quick to implement and pretty much every software engineer is familiar with it.

So we developed a demo product. It worked great in our customer simulation environment and we decided to storm ahead.

The initial response from our actual customer was also positive and the product worked as intended. We thought we were golden. We focused on implementing other parts of the software and considered the data upload engine a closed chapter.

However, a new cohort of customers took on our system and this exposed a weakness in our RESTful solution.

Those new customers were different from the first batch. They rarely used the safe and reliable source of internet which is Wi-Fi. Instead, they almost always used mobile data. To make things worse they worked in remote areas where the connection was poor and at times non-existent.

It was also quite common for them to get access to the internet for a few seconds before going into darkness again.

That meant our data wasn’t getting to the server and the devices were clogged up with valuable information we needed to somehow get to our server.

REST simply didn’t cut it. Its failing was the amount of overhead data that needs to be exchanged between the server and client before it can even begin sending the stuff we care the most about. Oftentimes, when we successfully established a connection with the server and all of the required handshaking was complete and we were just about to start uploading our data, the connection would be lost. This cycle liked to repeat itself many times making our Real-Time system more like a Delayed-Time system.

So we went looking for answers. Ideally, Open Source answers.

Keeping the long story short, that’s when we stumbled upon ZeroMQ. Here’s the official introduction which succeeded at grabbing our team’s attention.

“ZeroMQ (also known as ØMQ, 0MQ, or zmq) looks like an embeddable networking library but acts like a concurrency framework. It gives you sockets that carry atomic messages across various transports like in-process, inter-process, TCP, and multicast. You can connect sockets N- to-N with patterns like fan-out, pub-sub, task distribution, and request-reply. It's fast enough to be the fabric for clustered products. Its asynchronous I/O model gives you scalable multicore applications, built as asynchronous message-processing tasks. It has a score of language APIs and runs on most operating systems. ZeroMQ is from iMatix and is LGPLv3 open source.”

We liked the sound of that. On the premise of being able to cut out any overhead and speed up our comms with the server, we started to experiment with it.

The learning curve was a bit steeper than with REST so it took a while to bake it into our system even though ZMQ is pretty easy once you understand it.

Here’s what a simple client and server look like. Written in Java, naturally.

Server.java

 public static void main(String[] args) throws Exception {
        ZMQ.Context context = ZMQ.context(1);

        //  Socket to talk to clients
        ZMQ.Socket responder = context.socket(ZMQ.REP);
        responder.bind("tcp://*:5556");

        while (!Thread.currentThread().isInterrupted()) {
            // Wait for next request from the client
            String msg = responder.recvStr();
            if (StringUtils.isNotEmpty(msg)) {

                // Do something with your data

                // Send ack back to client
                String reply = "Acked";
                responder.send(reply.getBytes(), 0);
            }
        }
        responder.close();
        context.term();
    }


Client.java

    public static void main(String[] args) {

        ZMQ.Context context = ZMQ.context(1);

        //  Socket to talk to server
        System.out.println("Connecting to server…");

        ZMQ.Socket requester = context.socket(ZMQ.REQ);
        requester.connect("tcp://localhost:5556");

        Event event = new Event(1L, "SecretMessage");
        String message = new Gson().toJson(event);
        System.out.println(message);

        for (int requestNbr = 0; requestNbr <= 10; requestNbr++) {

            requester.send(message.getBytes(), 0);
            byte[] reply = requester.recv(0);

        }
        requester.close();
        context.term();
    }

In the end, we went with ZMQ as we found the performance to be out of the ordinary. But don’t take my word for it.


We ran some tests to compare the speeds between our two solutions (REST and ZMQ). Below is a table comparing times it took for the Server side to receive a number of messages of the same size (31 bytes).


Events sent (31 bytes each)

REST

ZMQ

Performance Gain

1,000

6s

353ms

16x

10,000

38s

2202ms (2s)

17x

100,000

388s (6m 22s)

11445ms (11s)

34x

1,000,000

didn’t bother…

62s (1m 2s)

> 9000x

Drops the mic and leaves the room. 


To conclude, we have proven that ZMQ is indeed lightning fast and reduces bandwidth imprint of your application.


It is also a bit trickier to implement and adds another library your dev team must support. 


As always, it depends on the project you are working on whether it is worth the hassle or not but if you care about network performance, it’s really difficult to ignore ZMQ. 


P.S. If you’d like to see the code I’ve used for the benchmarks above. Drop me a message or comment below and I’ll happily upload to GitHub. 



Open source

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • NoSQL vs SQL: What, Where, and How
  • How Chat GPT-3 Changed the Life of Young DevOps Engineers
  • Kubernetes-Native Development With Quarkus and Eclipse JKube
  • Apache Kafka Is NOT Real Real-Time Data Streaming!

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: