最近写的一个通信框架中有两种最基本的消息发送方式:同步发送和异步发送。
同步方式:
消息的发送方发A送一条消息到接收端B,B收到消息之后需要对消息进行处理,然后
发送ACK确认消息回A,A收到B的ACK之后就可以认为这条消息发送成功,并且保证B顺利收到并处理,在A收到ACK之前A将一直处于阻塞等待状态。
异步方式:
可细分成发送线程和接受线程异步,发送端进程和接收端进程异步;
发送线程和接收线程的异步指消息发送线程A发消息到B,A和B都有消息的接收和发送缓存,A将消息送入发缓存之后立即返回接着发下一条消息,缓存中的消息将被逐条写入TCP,B端从TCP拿到消息先入收缓存,B从收缓存中逐条取出处理,这里的收发两个线程处于不同的进程中,且同一时间可能同时处理不同的消息。
发送端进程和接收端端进程异步指的是,发送方和接收方不必同时在线,A将消息发送到消息队列,B上线之后从消息队列中获取A发送过来的消息。
同步和异步发送消息对于消息发送可靠性的保障上有区别。
这里的消息发送可靠性指消息在网络连接异常断开,进程异常重启之后所有的消息都不丢失。
同步发送保证了每条消息都被顺利收到并得到处理,若发送消息之后等待ACK超时表示对方可能未妥善收到并处理消息,发送方可以对消息进行重发等操作。因此同步发送的方式一定程度上保证了消息的可靠性。
异步方式由于中间存在收发缓存,当接收端进程异常重启,缓存内消息可能丢失,因此发送方发出去的消息并不能保证被接收并得到处理。像线程级的异步来说,必须在收发双方的消息中增加消息序列号,并对发送的每条消息,消息发送的序列号,消息接收的序列号进行持久化,这样进程重启之后可以对双方的序列号进行同步,从持久化模块中取出丢失的部分消息。以这样的方式才能保证消息发送的可靠性。
进程级的异步收发两端消息均通过中间的消息队列进行,消息队列最常见的就是消息中间件,JMS,MQ等等,发送端通过同步方式将消息发往消息队列,消息队列必须对消息进行持久化,然后以异步或同步方式发往消息接收方,这里的关键就是发送方和MQ之间通过同步方式和MQ上的消息持久化来保A,B两端的消息发送可靠性。
在保证消息发送可靠性的前提下同步方式发送消息的处理性能可能反而超越异步方式的发送,原因是异步发送每条消息需要进行多次地持久化数据。