我在发包时使用 Confirm 模式处理消息确认, 在发消息时使用了锁,在处理接收到的消息时使用了同一把锁,导致了死锁的产生。
产生死锁的原因 ConfirmSelect 会等待消费者的收包事件处理完成,注意是处理完成而非收到消费者的确认信号。
伪代码
生产者:
lock(lockobj){
代码1
ConfirmSelect(); //开启确认模式
代码2
}
消费者
代码1
lock(lockobj){
代码2
}
代码3
当 消费者进入锁,执行到 ConfirmSelect 时,如果此时有消费者再处理 会等待消费者处理完成, 消费者 处理到lock(lockobj) 时等待 生产者 的锁释放,两者互相等待,导致了死锁。
最终引发心跳超时。
RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Library, code=0, text=“End of stream”, classId=0, methodId=0, cause=System.IO.EndOfStreamException: Heartbeat missing with heartbeat == 60 seconds
既然知道了这个,那么这就可以优化一下了,接收到rabbit过来的包裹之后启用异步去处理,这样不会阻塞发包!