Key difference between AMQP and HTTP in distributed web applications
Even my experienced colleagues don’t understand the basic fundamental difference: AMQP promises you guaranteed delivery (and processing), but HTTP — don’t.
Disclaimer: I know that there is written “not guaranteed” in the RabbitMQ documentation. But, Rabbit at least try to do it (and does it very well), while HTTP does not guarantee anything by design.
Let me remind how HTTP works: the client sends a request, and “hangs” waiting for response. If you will abort the execution, or disconnect the client from server by any reason — the answer will be lost forever. Some systems, AFAIK, also will interrupt the processing if client drops the connection.
If the fatal error occurs on server side, we can get the response code (500/503) as well as get nothing. And we don’t know, had our request be processed completely, or partially, or just died when begin to send response to us, or there was deadlock between two “parallel” requests, or it’s such long by it’s nature, or backend is very busy and we were rejected by balancer, or.. I think you understand me.
None of known HTTP-clients, none of AJAX-functions in browsers don’t automatically repeat the same query if previous response was unsuccessfull. This behaviour is right: while we at client side don’t know that happens, the second request could perform unwanted operation (for example, transfer money twice).
In the case of using AMQP (I mean RabbitMQ and suggest it to you) — you have a “guarantee” that your request is received and will be processed as soon as possible. The “backend side” does not left client until the message will be persisted to safe storage. It is fast operation without any “highload”, unlike HTTP where the reception of the request is (in most cases) physically coupled with its processing.
Then, the delivery mechanism also guarantees you that if the service (worker) took a message to processing — and fell, the message will be returned to queue and will be processed by another (or restarted) service instance.
According to the rules of functional programming, each function must have exactly one output, and should not have side effects. The only result of processing the incoming message — is an outgoing message. If the outgoing message was published — it is a guarantee that the task was performed.
So, the AMQP protocol means by design that when the service begin to process message — it does not remove message from queue. It only marks it as busy. If the service fails — the message will be automatically “released”. But if the service successfully finish processing, it will publish an outgoing message, and only after this it will destroy incoming message.
Summary: with HTTP you’re dealing with an absolute anarchy: you do not know what happened there, is the processing complete or not, could you make a second request or not. But with AMQP you are dealing with a clearly structured and guaranteed transitions of life cycle: input, processing, output.
Moreover, it allows you to write code in the “let it crash” style, even on an ordinary PHP, without unnecessary guards and watchdogs because all communication between the components of your application — are transactional by nature, and are monitored by any convenient monitoring.
Originally published at www.dobryakov.net on January 29, 2016.