Enhancing Shared Mobility Apps with RabbitMQ

By Don Omondi, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud’s incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.

Queues, everybody hates being at the wrong end of them, but nobody doubts the level of organization and efficiency that they bring in service delivery. Civilizations have been using queues for centuries, but it wasn’t until the intervention of a Danish mathematician Agner Krarup Erlang, that the concept of queues evolved from just a social culture to a science. Erlang developed the Queueing theory while creating models to describe the Copenhagen telephone exchange. Erlang, the highly concurrent, functional programming language, is named in his honor.

Since its transition to a science, queues have been heavily used when developing applications in almost every sector. They are predominantly found in telecoms, banking, e-commerce, computer telephony and instant messaging. WhatsApp, written in Erlang, is one of the best examples of such implementation.

You don’t have to write your application in Erlang to use queues though. As a matter of fact, many people designate the queuing functionality to specialized software. RabbitMQ is at the pinnacle of such software. Also written in Erlang, RabbitMQ claims to be the most widely deployed open source message broker.

The brief history and introductions aside, let’s see how we can integrate RabbitMQ in shared mobility apps.

The Rise and Rise of Shared Mobility

The sharing economy, also known as collaborative consumption, has seen a sharp rise in the past years mostly driven by emerging sectors such as social lending, peer-to-peer accommodation and peer-to-peer travel experiences. Shared mobility in particular, has become a lucrative and competitive field more so in the areas of car-sharing, bicycle sharing and even scooter sharing. I’d go on to predict baby stroller sharing as the next big frontier.

The high demand for these services has increased the pressure for the applications behind them to be reliable, fast and efficient. A common way to achieve this is by decoupling different services into separate components that can each be executed or fail, without impacting the others — the so called microservices trend. In the case of failure, automated retry mechanisms should be put in place.

Let’s look at a typical example by taking 5 mins to create our own ride sharing app-or at least the core components of it. When a rider within our ride sharing app moves around, we would like to perform certain actions based on that event. The actions could be to:-

1) Log that event in our geolocation capable database such as PostgreSQL or Elasticsearch for future analytics.
2) Notify and update all opened client applications within the rider’s location of his new position.
3) Save that new location in a fast in-memory Key-Value store like Redis so that newly opened client applications can see nearby riders for a given time-to-live (ttl) of say 5 minutes.

Other actions could also be done depending on certain conditions and features, like sending the rider a voice text if he is driving too fast, or update current ride price on clients’ phones for real-time billing.

The keen eye would notice that all the actions mentioned above can and ideally should be executed independent of the other. With non-concurrent languages like PHP, it’s a near impossibility, whereas with highly concurrent ones like Go you’d still have to handle failure and retries manually and you’d lose the data in event of server crash or restart. This is the kind of situation where RabbitMQ shines.

The diagram above depicts at a very high level, what RabbitMQ helps you achieve. Basically, one event comes in along with some data and attributes and RabbitMQ routes (forwards) it to the appropriate channels where consumers await to process that data. Until those consumers acknowledge the message, typically after successful processing is done, RabbitMQ will keep that message in its queue and keep retrying to send it back for processing and acknowledgement.

At a lower level, RabbitMQ achieves this utilizing its concepts of exchanges, bindings and queues. Of course there are tons of other interesting features, but for our simple ride sharing app these are what we need to understand and use.

In a nutshell, our RabbitMQ broker receives the message from our mobility app, formally termed as the producer. Within the broker, the message arrives at the exchange, which is now responsible for routing of the message to queues bound to it. Thus bindings have to be created from the exchange to queues before producing messages. The message routing depends on different factors such as the exchange type. Our simple mobility app uses the fanout exchange type where the exchange routes messages to all of the queues that are bound to it.

If all this is beginning to sound complex, trust me it’s not, and the following practical example will prove it.

A Simple Frontend

First, we’ll build out a very basic frontend which will fetch our current location and show it on a map. When we move, it will also update that location and its respective map position. Lastly, for every location update, we will send the coordinates and rider_id to our backend which in turn will send it to RabbitMQ for fanout routing and processing.

We’ll need a few tools to begin with, make sure nodejs is installed. I also happen to prefer yarn to npm, whose advanced caching comes in handy in intermittent connectivity situations .

The 5 packages are all we need for our simple mobility app. The necessary frontend HTML itself is ridiculously simple.

30 lines and that’s it! We only need to render a leaflet powered map and have alertify.js popup some simple alerts and notifications on certain events.

Now for the business logic in app.js. Leaflet has some very nice built-in helpers that can automatically ask for permission and, if granted, detect your location, position a blue marker on the map’s center and track your movement. It does all the heavy lifting for our simple mobility app. All we have to do, is hook into leaflet’s location success event and emit a socket.io event. We’ll also add a custom yellow marker to show other riders on the map.

The business logic is a bit longer than the HTML, but it still clocks in under 200 lines of heavily commented JavaScript.

The express server.js code is 50 lines of JavaScript bliss.

It starts by simply requiring some necessary libraries, then specifying some folders that host static assets for our frontend. We then establish a RabbitMQ connection and specify an exchange as a fanout type. Next, we create some queues and bind them to the created exchange. We then wait for a socket.io server connection to materialize then listen for the ‘send’ and ‘receive’ from all clients. The ‘send’ events from our frontend will be forwarded to our RabbitMQ broker. Lastly, we bind an express server to port 80 (Node might need sudo permissions if on linux).

The last part of our simple mobility app, are the RabbitMQ consumers. We’ll start with the ‘map-queue’ consumer. It basically consumes messages from the ‘map-queue’ and forwards it back to our socket.io server to distribute to frontend clients.

consumers/map.js

Just 23 lines and we’re done! We’ll similarly build consumers for the ‘analytics-queue’ and the ‘redis-queue’. This will simply log the data received from the queue for now.

consumers/analytics.js

consumers/redis.js

Running the Demo

We’re ready to view our simple mobility app in action now. Change to our project directory, open up 4 terminals and run these commands.

Open a browser, preferably chromium based, and visit http://localhost

Your location is now show at the center of the map. Now, open a new browser tab and move around, or better yet mock movement by sending slightly new coordinates from the browser console.

Watch new popups appear on the map.

Monitor your console logs and see them logging that data. You can kill a consumer to mock server downtime, wait a minute, an hour or even a day and the messages will still be processed and in order.

Now you see how simple it is to enhance mobility apps with a powerful message queue like RabbitMQ. Never again should your users suffer because your analytics database is down, nor should your analytics database have to wait for Redis to load data from disk during restoration. You can download the source code of this sample ride sharing app from GitHub.

Reference:https://www.alibabacloud.com/blog/enhancing-shared-mobility-apps-with-rabbitmq_594596?spm=a2c41.12692490.0.0

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.