Jump to content

Add support for AMQP 0-9-1 messaging protocol

KT Walrus

Recommended Posts

I'm in the process of adding support in my apps for the RabbitMQ message broker to separate admin tasks (that may be performed asynchronously) from the app's front-end. RabbitMQ implements the AMQP 0-9-1 messaging protocol (with other protocols supported via rabbitmq-plugin).

This is turning out to be quite nice. Just like ICS4 added support for Redis database cacheing, I would like to see the next version of ICS4 add support for AMQP 0-9-1 asynchronous message passing to backend admin tasks.

For example, it would be better if handling emails in and out of ICS4 where done through RabbitMQ to start with. The parameters for an outgoing email message could be queued to one or more admin task clients that wait on new email parameters for outgoing messages and processes the message template with the parameters to form a complete mail message and then sends them at out using an SMTP service. Note the admin workers can be written in PHP and run within the ICS4 environment (just like current ICS4 tasks are run from a cronjob). They simply have to wait on messages from a queue in RabbitMQ and process these messages (in this case, sending or receiving emails).

For incoming emails, it is rather easy to configure Postfix to pipe incoming emails to a PHP file for queuing in RabbitMQ. A separate admin worker would watch this queue and ingest any properly addressed messages and store those messages (along with attachments) in the database. This could be implemented for support messages in Commerce, but could also be used to implement "post by email" functionality in the suite (like to upload photos to Gallery via email).

For my apps, I want all database updates to be done asynchronously via RabbitMQ. This means that I can't use auto-increment primary keys but must use global UUIDs for my database tables. That is, instead of updating the database with a series of INSERT/UPDATE queries directly, my app will generate a UUID for the post and queue all data necessary to update the database through RabbitMQ to an admin worker that knows how to turn this data into an application content post and update the database asynchronously. I plan on cacheing the post data in Redis before queuing to the backend so that my app can show the new post to the user even before it makes it into the database (since RabbitMQ is asynchronous message delivery).

There are many other features in ICS4 that could be offloaded to RabbitMQ over time to make ICS4 even faster and more scaleable (and highly available). My goal is to have my ICS4 frontend only have read access to the MySQL database and use RabbitMQ and Redis as much as possible. This would allow better security to my database since the MySQL user used by ICS4 frontend would be restricted from performing update queries while the actual updates would be done by an admin worker using an admin MySQL user/password.

BTW, it appears to be very easy to run a RabbitMQ Cluster in High Availability mode using containers. Such a cluster would survive temporary or long term unavailability of a number of nodes in the cluster without losing any queued messages. Workers could be scaled up/down as needed rather easily since their job is to asynchronously process front-end requests. You can even implement a queue with only one worker processing all messages in the queue. This allows you to "serialize" the database requests (which might come in handy for some tasks - I have one such task in my ICS4 apps that really benefits from being applied serially). The backend workers can apply multiple update queries in a single MySQL transaction to make it harder for the database to become inconsistent.

Finally, failures in a backend admin worker due to bad input or a permission issue can be reported to the user via ICS4 notification messages. That is, failure to apply all updates on new content creation could send a notification to the poster that the backend failed to add the new content to the database (because the database was not available for update) and that the admin worker had requeued the new content for retrying later. Just like an SMTP server may inform the sender that the message couldn't be delivered and will keep trying for a few days, the admin worker could send similar notifications to the poster (and maybe an SMS message to the ICS4 Admin) that there was a problem in the backend.

Link to comment
Share on other sites


This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...