开发者社区> 问答> 正文

【阿里云产品公测】MQS使用体会和建议

dongcc 2014-11-05 00:08:24 14834
帮忙投个票哈: http://bbs.aliyun.com/read/178799.html   编号47,谢啦


无意间看到阿里云推出了消息队列服务MQS功能,由于长期从事和消息队列(Messaging)相关的工作,出于好奇,申请了下阿里云的队列服务。


消息队列最主要的的要求就是可靠,一般说来,为了达到这个可靠,如果自己搭建消息队列服务器,需要花不少的时间在维护上,
特别是在异构的环境中,阿里云的消息队列产品优势里介绍的第一点,简单易用里说————
“您无需自行搭建消息队列服务,免运维”
这一点对于企业级应用还是比较诱人的,试想如果有几百个队列服务器需要维护,还是比较愁人的。


  • 编程接口

对于接口————“我们提供标准的HTTP RESTful接口简单易用,对平台无依赖”,这一点虽然对,但是实际上也就意味着,
如果消息队列服务不可用的情况下将无法提交消息,也就是应用如果遇到队列服务不可用的情况时,应用应该具备缓存数据的能力,
然后当队列服务可用时,重新提交,否则就会出现数据丢失的情况。或者就完全依赖阿里云提供的消息服务的可靠性了。


对于数据交换格式,支持XML格式,目前JSON格式由于数据格式比较简单,格式都是压缩的,占用带宽小,易于解析等等似乎更有优势,
因此如果能支持JSON格式就更好了。


正好有Java SDK,直接拿它写了个测试程序试了下...


  • 建立连接

MQSClient client = new DefaultMQSClient("http://dongcc.mqs-beijing.aliyuncs.com","accessId", "accessKey");
不知道为什么,一开始直接设置了个id(dongcc),总是不能正确运行,报错:
[Error Code]:AccessDenied, [Message]:The OwnerId that your Access Key Id associated to is forbidden for this operation.


而文档里写的是
MQSClient client= new DefaultMQSClient("http://<QueueOwnerId>.mqs-<Region>.aliyuncs.com", "<AccessKeyId>","<AccessKeySecret>");
一直没弄明白这个QueueOwnerId是怎么定义的。后来从消息队列控制台发现有获取地址的功能,因此找到了这个QueueOwnerId:
[attachment=63952]



而且从建立连接的方式,可以看出,跨区域的消息队列是不能共享的。


  • 队列

开始用尝试用代码建queue,习惯性的建了个test.q1,结果报错:
[Error Code]:InvalidQueueName, [Message]:The queuename you provided is invalid. QueueName should start with alpha and contain only alpha, digit or -.
原来是queue名字不支持".",只能用"-", 由于以前一直采用地区.应用名.对列名的格式建queue,这么一改,还很不习惯,如果能支持点(.)就好了。


建queue的时候有如下参数:
QueueMeta meta = new QueueMeta();
meta.setQueueName(queueName);
meta.setDelaySeconds(0L);                                    //发送到该Queue所有消息的延迟可见时间,单位为秒
meta.setMaxMessageSize(65530L);                        //消息体的最大长度,单位为byte
meta.setMessageRetentionPeriod(345600L);             //消息的最长存活时间,单位为秒,最小60秒
meta.setVisibilityTimeout(30L);                                //消息取出后维持不可见状态的时间,单位为秒,最小1秒
meta.setPollingWaitseconds(0);                               //长轮询等待时间,单位为秒,默认为0


对于MessageRetentionPeriod范围: 60 (1 分钟)-1296000(15 天) ,最长15天,这就意味着,消息没法持久化。
对于PollingWaitseconds,我感觉是取消息的等待时间,但在实际测试中,好像不是这样,好像没有等待就直接返回了,不知道是bug还是我理解错了。
实际上对于MessageRetentionPeriod,PollingWaitseconds,感觉最好是消息的参数,这样相比队列的参数更加灵活,
否则就得设置不同的队列来处理,比如有时候(比如backend)程序需要取消息的时候希望timeout的时间(PollingWaitseconds)是30秒,
有时候对于同一类消息出于响应时间的考虑,可能timeout的时间就是5秒或者更少。


对于MessageSize,64K感觉有点小,我遇到过一个企业应用里的消息大小是50M的xml文本~


不过队列属性里好像没有最大深度,难道是放消息没有限制?


  • 消息的发送

发送消息,就两个属性可以设置(Priority和DelaySeconds):
CloudQueue queue = client.getQueueRef(queueName);
Message message = new Message();
message.setMessageBody("I am test message.");
message.setPriority(8) ;                 //消息的优先级,优先级越高的消息,越容易更早被消费
queue.putMessage(message);


正如上面提到的,希望能够对于消息设置MessageRetentionPeriod,这样更为灵活,而且,有些情况下持久消息还是很有用的。


  • 消息的读取

对于读取消息,有同步和异步两种方式:
同步读取
Message msg = queue.popMessage();
String messageBody = msg.getMessageBodyAsString();
String msgId = msg.getMessageId();
String receiptHandle = msg.getReceiptHandle();


读消息的时候,希望能对消息的PollingWaitseconds进行设置,这样更为灵活,或者popMessage价格取消息的等待时间之类的。
从参考看,http request是支持这个参数的,但Java SDK和Python SDK好像没这个参数。


异步读取
queue.asyncPopMessage(new AsyncCallback<Message>() {
public void onSuccess(Message msg) {
  String messageBody = msg.getMessageBodyAsString();
  String msgId = msg.getMessageId();
  String receiptHandle = msg.getReceiptHandle();
  System.out.println("msg :" + messageBody);
}
public void onFail(Exception ex) {
  ex.printStackTrace();
}
}


消息的读取最初测试的时候发现这个消息好像不想我想象中的,读完了就删除了,这个消息好像会一直存在,除非以显式的方式删除:
queue.deleteMessage(receiptHandle);


后来发现文档关于消息投递保障是这么描述的:在消息有效期内,确保消息 至少能被成功消费一次


一般说来消息QoS有三种:
  • 至少一次
  • 刚好一次
  • 至多一次

个人感觉对于可靠消息传输,一般都要求刚好一次,当然也可以在应用里读取完消息后直接删除。


总体感觉,阿里云的消息队列服务的响应速度还是不错的,如果走内网的话,估计更快,当然测试中也没发现过丢包的情况。







消息中间件 XML JSON 缓存 运维 Java 网络性能优化 开发工具 数据格式 Python
分享到
取消 提交回答
全部回答(4)
  • 河南seo
    2015-05-01 17:33:59
    Re【阿里云产品公测】MQS使用体会和建议
    个人网站:http://www.lichuangcheng.com/

    -------------------------

    Re【阿里云产品公测】MQS使用体会和建议
    学习啦!!! 欢迎大家访问我的个人网站!http://www.lichuangcheng.com
    0 0
  • dongcc
    2014-11-06 15:05:01
    回2楼boboan的帖子
    阿里云MQS能保证99.9%的可用性,还是相当厉害的,缓存在客户端要取决于什么应用,某些情况下客户端很多的话,缓存在客户端维护起来就不太好弄;不过这个毕竟是少数情况,通过ECS的稳定性,我相信阿里云MQS稳定性

    -------------------------

    Re【阿里云产品公测】MQS使用体会和建议
    引用第3楼boboan于2014-11-05 14:36发表的  :
    2  json格式这个可以有。

    3 我第一看文档也没弄明白QueueOwnerId。。。是在创建队列后,才搞明白的。这个是文档的问题,没说明白,要改进的地方

    4 mqs目前对放消息数是没有限制的。
    .......

    关于 PollingWaitseconds ,也许是java sdk的问题,我记得我测试的时候好像没发现会等待。。。
    我知道http request的时候可以指定 PollingWaitseconds ,但java sdk或是python sdk没这个参数(不知道是不是我的sdk版本太低或是别的什么原因),文档的说法是会参考queue设置的 PollingWaitseconds。

    -------------------------

    Re【阿里云产品公测】MQS使用体会和建议
    引用第4楼boboan于2014-11-05 14:40发表的  :
    6  “希望能够对于消息设置MessageRetentionPeriod,这样更为灵活,而且,有些情况下持久消息还是很有用的。”    
        
    灵活和方便管理需要平衡。            

    mqs本身消息是有持久化。但mqs本身不是存储服务,其实可以选择本地存储或是oss。
    .......

    灵活和方便管理需要平衡,这点我完全同意。
    如果mqs本身的消息有持久化的,不知道如果出现服务停止的时候(正常或异常),服务回复后,消息会还在么?
    正常说来15天是够的,有些业务请求,会由于某种原因未被处理,如果到了15天后,就消失了,感觉也许应该留个什么记录可以作为追溯的依据。。。

    -------------------------

    Re【阿里云产品公测】MQS使用体会和建议
    引用第5楼boboan于2014-11-05 14:41发表的  :
    7 “对于MessageSize,64K感觉有点小,我遇到过一个企业应用里的消息大小是50M的xml文本”

    。。。50M的消息,这个确实有点大。建议存oss,然后把它的地址发到消息    。


    这个建议不错~

    -------------------------

    Re【阿里云产品公测】MQS使用体会和建议
    引用第6楼boboan于2014-11-05 14:44发表的  :
    8  跨区域的消息队列是不能共享的

    请问这个是什么意思,你希望怎么共享?

    9 之前你是使用的什么队列,习惯性的建了个test.q1 ?
    .......

    目前阿里有三个地区,北京,青岛,杭州(也许以后能跨国家?),不同地区访问速度不一样,如果一个应用在不同地区使用,比如放消息的应用在杭州,读消息处理消息的应用在北京,如果消息能做到共享的话(或者互通),就可以避免访问速度带来的一些问题了。


    我一般用的是IBM MQ和开源的MQTT类的产品(基于pub/sub的,因此基于topic string,使用就不是点了,是斜线,如/REGION/BU/APPLNAME/XXX)。
    0 0
  • boboan
    2014-11-05 14:30:54
    1. “如果消息队列服务不可用的情况下将无法提交消息”。


    个人觉得这个问题不大,mqs保证的是99.9%服务可用性,Always Writable。当然公网的网络环境不稳定是有的。缓存数据在客户端来做是不是会更好?

    -------------------------

    2  json格式这个可以有。

    3 我第一看文档也没弄明白QueueOwnerId。。。是在创建队列后,才搞明白的。这个是文档的问题,没说明白,要改进的地方

    4 mqs目前对放消息数是没有限制的。

    5 PollingWaitseconds 是指,当queue没有消息时,针对该queue receive message请求最长等待时间。超过这个时间后,返回MsgNotExsits。如果在这个时间范围内,有了消息,就直接返回消息。                    

    -------------------------

    6  “希望能够对于消息设置MessageRetentionPeriod,这样更为灵活,而且,有些情况下持久消息还是很有用的。”    
        
    灵活和方便管理需要平衡。            

    mqs本身消息是有持久化。但mqs本身不是存储服务,其实可以选择本地存储或是oss。

    -------------------------

    7 “对于MessageSize,64K感觉有点小,我遇到过一个企业应用里的消息大小是50M的xml文本”

    。。。50M的消息,这个确实有点大。建议存oss,然后把它的地址发到消息    。

    -------------------------

    8  跨区域的消息队列是不能共享的

    请问这个是什么意思,你希望怎么共享?

    9 之前你是使用的什么队列,习惯性的建了个test.q1 ?

    0 0
  • qiujin2012
    2014-11-05 10:53:31
    支持他,就给他投票,猛戳:
    http://bbs.aliyun.com/read/178799.html
    0 0
添加回答

集结各类场景实战经验,助你开发运维畅行无忧

推荐文章
相似问题