0. Can't find 'reliable' on Akka homepage
Check out the akka official site, we can see many attractive words: 'high performance', 'asynchronous', 'resilient', etc, but I didn't find 'reliable'.
1. One rule of Akka
at-most-once delivery, it means no guaranteed delivery.
2. How about Erlang and TCP?
3. Why No Guaranteed Delivery?
My simple answer is: expensive overhead, impossible on distributed network (the target node might be dead), we can implement it on business level, rather than transport level.
The best answer I found lies in Erlang FAQ 10.9.
Most people find it simplest to program as though the answer was "yes, always".
Per Hedeland covered the issues on the mailing list (edited a bit):
"Delivery is guaranteed if nothing breaks" - and if something breaks, you will find out provided you've used link/1. I.e. you will get an EXIT signal not only if the linked process dies, but also if the entire remote node crashes, or the network is broken, or if any of these happen before you do the link.
It seems this issue of "guaranteed delivery" comes up every now and then, but I've never managed to find out exactly what it is those that are asking for it actually want:
--A guarantee that the message is put into the receiver's input queue? But if the receiver dies before extracting it from there, that guarantee is useless, as the message is lost anyway.
--A guarantee that the receiver extracts the message from its input queue? Well, besides the obvious problem that depending on how the receiver is written, even if it lives happily ever after it may never extract that particular message, it suffers from a variant of the previous problem: Even if you "know" that the receiver has "consumed" the message, it may die before acting on it in any way, and then again it may as well never have been sent.
--A guarantee that the receiver actually processes the message? Just kidding of course, hopefully it's obvious to everyone that the only way to obtain such a guarantee, regardless of what programming and communication system you use, is that the receiver is programmed to send an explicit acknowledgment when the processing is complete (of course this may be hidden below an abstraction such as RPC, but the fundamental principle holds).
Add to this that any guarantee would have to entail some form of ack from the remote in at least a distributed system, even if it wasn't directly visible to the programmer. E.g. you could have '!' block until the ack comes back from the remote saying that the message had progressed however far you required - i.e. synchronous communication of sorts. But this would penalize those that don't require the "guarantee" and want asynchronous communication.
So, depending on your requirements, Erlang offers you at least these levels of "guarantee":
Super-safe
Receiver sends ack after processing; sender links, sends, waits for ack or EXIT. This means the sender knows, for each message, whether it was fully processed or not.
Medium-safe
Receiver doesn't send acks; Sender links, sends message(s). This means an EXIT signal informs the sender that some messages may never have been processed.
Pretty-safe
Receiver doesn't send acks; sender sends messages. :-)
There are any number of combinations of these (e.g. receiver sends ack not after each message but at some critical points in the processing).
Per concluded by pointing out that "if you think TCP guarantees delivery, which most people probably do, then so does Erlang".
4. Another perspective, how about the reliable distributed systems?
For instance, Apache Storm. and MQ.
Reference:
[1] Akka 2.3 Official Documentation
[2] http://www.infoq.com/articles/no-reliable-messaging
[3] http://www.erlang.org/faq/academic.html 10.9