本文介绍消息服务MNS中使用LongPolling的最佳实践。

背景信息

  • 消息服务MNS提供了LongPolling类型的接收消息的方法,在接收消息的时候把等待时间设置在1s~30s。使用LongPolling可以让请求一直在服务器上运行,等到有消息的时候才返回,保证第一时间收到消息的同时也避免您发送大量无效请求。LongPolling是消息服务MNS的推荐用法。

    LongPolling参数设置详情请参见ReceiveMessage

  • LongPolling需要保持HTTP层的长连接在服务器上,而对于服务器来说,HTTP层的长连接的资源是有限的。为了避免受到恶意攻击,消息服务MNS对单用户的每个Queue的连接数是有限制的。详情请参见使用限制

问题描述

您在单台机器上打开上百个线程同时访问消息服务MNS服务器获取消息,队列中没有消息时,单台机器上发送了上百个LongPolling的请求。如果您同时使用了较多机器,那么可能同时发送上千个LongPolling的请求。

这时您再发LongPolling,消息服务MNS服务器就会返回:消息不存在。

有时您是在一个While循环里不停的做LongPolling请求,却没有做异常处理,最后发出了极大量的请求,不能达到使用LongPolling的预期效果。

解决方案

当您打开上百个线程同时访问消息服务MNS服务器时,如果队列里已经没有消息,就不需要上百个线程同时运行LongPolling。此时只需要打开1~N个线程运行LongPolling。当运行LongPolling的线程发现队列里有消息时,唤醒其他线程一起接收消息,达到快速响应的目的。

长轮询示例代码是一个使用MessageReceiver获取消息的最佳实践。所有获取消息的线程都新建了MessageReceiver,使用receiver.receiveMessage来获取消息。

MessageReceiver内部做了LongPolling的排他机制,只要有一个线程在做LongPolling,其它线程只需要等待。