关于MNS消息发送和接收的实现问题
来源:互联网 发布:eclipse for linux 64 编辑:程序博客网 时间:2024/04/29 16:33
我在使用MNS发送消息时,用的是阿里云的MNS。一些问题大都可以在官方文档上找到。
消息服务MNS提供了两种API接口,一种是队列接口,一种是主题接口。
队列接口适用于点对点的消息收发,当接收消息时,需要应用端自行轮询获取消息(拉模式)。
主题接口适用于一对多的消息收发,应用端只需要在某个地址上启动监听,服务端就会主动将消息推送过去(推模式)。
1,其实使用两种方式都有自己的利弊,不然提供两种方式也就没有什么区别了。2,队列模型保证消息至少会被消费一次, 支持多个生产者和消费者并发操作同一个消息队列。消费消息时尽量做到先进先出,正是因为分布式消息队列的一些特性并不能保证你能按照消息的发送顺序消费消息,如果你的业务必需先进先出, 建议在消息中加入序号信息以便消费消息后进行重新排序。
3,主题模型支持服务端主动将消息推送给用户指定的回调地址(Endpoint),消除用户程序不必要的轮询和资源消耗。
主题模型保证通知消息按照指定的策略推送给用户,支持多个消息发布者并发操作同一个主题。主题模式支持一对多广播消息,一条通知消息可以同时被多个订阅者接收和消费。
我这里主要说下实现方法:
一、队列接口
1.创建队列
public class CreateQueueDemo { public static void main(String[] args) { CloudAccount account = new CloudAccount("YourAccessId", "YourAccessKey", "MNSEndpoint"); MNSClient client = account.getMNSClient(); // 在程序中,CloudAccount以及MNSClient单例实现即可,多线程安全 String queueName = "TestQueue"; QueueMeta meta = new QueueMeta(); //生成本地QueueMeta属性,有关队列属性详细介绍见https://help.aliyun.com/document_detail/27476.html meta.setQueueName(queueName); // 设置队列名 meta.setPollingWaitSeconds(15); meta.setMaxMessageSize(2048L); try { CloudQueue queue = client.createQueue(meta); } catch (ClientException ce) { System.out.println("Something wrong with the network connection between client and MNS service." + "Please check your network and DNS availablity."); ce.printStackTrace(); } catch (ServiceException se) { se.printStackTrace(); logger.error("MNS exception requestId:" + se.getRequestId(), se); if (se.getErrorCode() != null) { if (se.getErrorCode().equals("QueueNotExist")) { System.out.println("Queue is not exist.Please create before use"); } else if (se.getErrorCode().equals("TimeExpired")) { System.out.println("The request is time expired. Please check your local machine timeclock"); } /* you can get more MNS service error code from following link: https://help.aliyun.com/document_detail/mns/api_reference/error_code/error_code.html */ } } catch (Exception e) { System.out.println("Unknown exception happened!"); e.printStackTrace(); } client.close(); // 程序退出时,需主动调用client的close方法进行资源释放 }}
当然,你必须有阿里云提供的相关的key、参数和密钥。
2.发送消息
public class ProducerDemo { public static void main(String[] args) { CloudAccount account = new CloudAccount("YourAccessId", "YourAccessKey", "MNSEndpoint"); MNSClient client = account.getMNSClient(); // 在程序中,CloudAccount以及MNSClient单例实现即可,多线程安全 try { CloudQueue queue = client.getQueueRef("TestQueue"); Message message = new Message(); message.setMessageBody("I am test message "); Message putMsg = queue.putMessage(message); System.out.println("Send message id is: " + putMsg.getMessageId()); } catch (ClientException ce) { System.out.println("Something wrong with the network connection between client and MNS service." + "Please check your network and DNS availablity."); ce.printStackTrace(); } catch (ServiceException se) { se.printStackTrace(); logger.error("MNS exception requestId:" + se.getRequestId(), se); if (se.getErrorCode() != null) { if (se.getErrorCode().equals("QueueNotExist")) { System.out.println("Queue is not exist.Please create before use"); } else if (se.getErrorCode().equals("TimeExpired")) { System.out.println("The request is time expired. Please check your local machine timeclock"); } /* you can get more MNS service error code from following link: https://help.aliyun.com/document_detail/mns/api_reference/error_code/error_code.html */ } } catch (Exception e) { System.out.println("Unknown exception happened!"); e.printStackTrace(); } client.close(); // 程序退出时,需主动调用client的close方法进行资源释放 }}
3.接受和删除消息
public class ConsumerDemo { public static void main(String[] args) { CloudAccount account = new CloudAccount("YourAccessId", "YourAccessKey", "MNSEndpoint"); MNSClient client = account.getMNSClient(); // 在程序中,CloudAccount以及MNSClient单例实现即可,多线程安全 try{ CloudQueue queue = client.getQueueRef("TestQueue"); Message popMsg = queue.popMessage(); if (popMsg != null){ System.out.println("message handle: " + popMsg.getReceiptHandle()); System.out.println("message body: " + popMsg.getMessageBodyAsString()); System.out.println("message id: " + popMsg.getMessageId()); System.out.println("message dequeue count:" + popMsg.getDequeueCount()); //删除已经取出消费的消息 queue.deleteMessage(popMsg.getReceiptHandle()); System.out.println("delete message successfully.\n"); } else{ System.out.println("message not exist in TestQueue.\n"); } } catch (ClientException ce) { System.out.println("Something wrong with the network connection between client and MNS service." + "Please check your network and DNS availablity."); ce.printStackTrace(); } catch (ServiceException se) { se.printStackTrace(); logger.error("MNS exception requestId:" + se.getRequestId(), se); if (se.getErrorCode() != null) { if (se.getErrorCode().equals("QueueNotExist")) { System.out.println("Queue is not exist.Please create before use"); } else if (se.getErrorCode().equals("TimeExpired")) { System.out.println("The request is time expired. Please check your local machine timeclock"); } /* you can get more MNS service error code from following link: https://help.aliyun.com/document_detail/mns/api_reference/error_code/error_code.html */ } } catch (Exception e) { System.out.println("Unknown exception happened!"); e.printStackTrace(); } client.close(); }}
4.删除队列
public class DeleteQueueDemo { public static void main(String[] args) { CloudAccount account = new CloudAccount("YourAccessId", "YourAccessKey", "MNSEndpoint"); MNSClient client = account.getMNSClient(); // 在程序中,CloudAccount以及MNSClient单例实现即可,多线程安全 try{ CloudQueue queue = client.getQueueRef("TestQueue"); queue.delete(); } catch (ClientException ce) { System.out.println("Something wrong with the network connection between client and MNS service." + "Please check your network and DNS availablity."); ce.printStackTrace(); } catch (ServiceException se) { se.printStackTrace(); } catch (Exception e) { System.out.println("Unknown exception happened!"); e.printStackTrace(); } client.close(); }}
二、主题方式
1.创建主题
public class CreateTopicDemo { public static void main(String[] args) { CloudAccount account = new CloudAccount("YourAccessId", "YourAccessKey", "MNSEndpoint"); MNSClient client = account.getMNSClient(); // 在程序中,CloudAccount以及MNSClient单例实现即可,多线程安全 String topicName = "TestTopic"; TopicMeta meta = new TopicMeta(); meta.setTopicName(topicName); try { CloudTopic topic = client.createTopic(meta); } catch (Exception e) e.printStackTrace(); System.out.println("create topic error, " + e.getMessage()); } client.close(); }}
2.发送消息
public class PublishMessageDemo { public static void main(String[] args) { CloudAccount account = new CloudAccount("YourAccessId", "YourAccessKey", "MNSEndpoint"); MNSClient client = account.getMNSClient(); // 在程序中,CloudAccount以及MNSClient单例实现即可,多线程安全 CloudTopic topic = client.getTopicRef("TestTopic"); try { TopicMessage msg = new Base64TopicMessage(); //可以使用TopicMessage结构,选择不进行Base64加密 msg.setMessageBody("hello world!"); msg.setMessageTag("filterTag"); //设置该条发布消息的filterTag msg = topic.publishMessage(msg); System.out.println(msg.getMessageId()); System.out.println(msg.getMessageBodyMD5()); } catch (Exception e) { e.printStackTrace(); System.out.println("subscribe error"); } client.close(); }}
3.创建订阅、接受消息
public class ConsumerDemo { public static void main(String[] args) { CloudAccount account = new CloudAccount("YourAccessId", "YourAccessKey", "MNSEndpoint"); MNSClient client = account.getMNSClient(); // 在程序中,CloudAccount以及MNSClient单例实现即可,多线程安全 try{ CloudTopic topic = client.getTopicRef("TestTopic"); ubscriptionMeta subMeta = new SubscriptionMeta(); subMeta.setSubscriptionName("TestSub"); subMeta.setNotifyContentFormat(SubscriptionMeta.NotifyContentFormat.SIMPLIFIED); subMeta.setEndpoint(topic.generateQueueEndpoint("TestQueue"); subMeta.setFilterTag("filterTag"); topic.subscribe(subMeta); //订阅相关主题 CloudQueue queue = client.getQueueRef("TestQueue"); Message popMsg = queue.popMessage(); if (popMsg != null){ System.out.println("message handle: " + popMsg.getReceiptHandle()); System.out.println("message body: " + popMsg.getMessageBodyAsString()); System.out.println("message id: " + popMsg.getMessageId()); System.out.println("message dequeue count:" + popMsg.getDequeueCount()); //删除已经取出消费的消息 queue.deleteMessage(popMsg.getReceiptHandle()); System.out.println("delete message successfully.\n"); } else{ System.out.println("message not exist in TestQueue.\n"); } } catch (ClientException ce) { System.out.println("Something wrong with the network connection between client and MNS service." + "Please check your network and DNS availablity."); ce.printStackTrace(); } catch (ServiceException se) { se.printStackTrace(); logger.error("MNS exception requestId:" + se.getRequestId(), se); if (se.getErrorCode() != null) { if (se.getErrorCode().equals("QueueNotExist")) { System.out.println("Queue is not exist.Please create before use"); } else if (se.getErrorCode().equals("TimeExpired")) { System.out.println("The request is time expired. Please check your local machine timeclock"); } /* you can get more MNS service error code from following link: https://help.aliyun.com/document_detail/mns/api_reference/error_code/error_code.html */ } } catch (Exception e) { System.out.println("Unknown exception happened!"); e.printStackTrace(); } client.close(); }}4.取消订阅、删除zhu't
队列模型保证消息至少会被消费一次, 支持多个生产者和消费者并发操作同一个消息队列。
消费消息时尽量做到先进先出,正是因为分布式消息队列的一些特性并不能保证你能按照消息的发送
顺序消费消息,如果你的业务必需先进先出, 建议在消息中加入序号信息以便消费消息后进行重新排
序。
队列模型保证消息至少会被消费一次, 支持多个生产者和消费者并发操作同一个消息队列。
消费消息时尽量做到先进先出,正是因为分布式消息队列的一些特性并不能保证你能按照消息的发送
顺序消费消息,如果你的业务必需先进先出, 建议在消息中加入序号信息以便消费消息后进行重新排
序。
队列模型保证消息至少会被消费一次, 支持多个生产者和消费者并发操作同一个消息队列。
消费消息时尽量做到先进先出,正是因为分布式消息队列的一些特性并不能保证你能按照消息的发送
顺序消费消息,如果你的业务必需先进先出, 建议在消息中加入序号信息以便消费消息后进行重新排
序。
队列模型保证消息至少会被消费一次, 支持多个生产者和消费者并发操作同一个消息队列。
消费消息时尽量做到先进先出,正是因为分布式消息队列的一些特性并不能保证你能按照消息的发送
顺序消费消息,如果你的业务必需先进先出, 建议在消息中加入序号信息以便消费消息后进行重新排
序。
public class DeleteTopicDemo { public static void main(String[] args) { CloudAccount account = new CloudAccount("YourAccessId", "YourAccessKey", "MNSEndpoint"); MNSClient client = account.getMNSClient(); // 在程序中,CloudAccount以及MNSClient单例实现即可,多线程安全 CloudTopic topic = client.getTopicRef("TestTopic"); try { topic.unsubscribe("TestSub"); topic.delete(); } catch (Exception e) { e.printStackTrace(); System.out.println("delete topic error"); } client.close(); }}
这个几乎是官网的案例。
但是只要按照这样的顺序和思路写一定不会有问题的。
在使用Spring的时候多使用注入方式。
所以考虑到这个,一半会将这些东西的配置信息写在XML里边。如
<bean id="queueMeta" class="com.aliyun.mns.model.QueueMeta"> <property name="queueName" value="${queueName}"/> <property name="pollingWaitSeconds" value="15"/> <property name="maxMessageSize" value="2048"/> </bean>
- 关于MNS消息发送和接收的实现问题
- 关于Windows消息的发送和接收入门
- 关于Windows消息的发送和接收入门
- C#简单实现自定义消息的发送和接收
- OpenJMS程序实现消息的发送和接收
- JMS_使用ActiveMQ实现消息的发送和接收
- RabbitMQ+Spring Quartz 实现消息的定时发送和接收
- 消息的创建发送和接收
- ActiveMQ 消息的发送和接收
- erlang的消息发送和接收
- 关于VC++中,两种自定义消息的发送与接收的方法实现进行说明。
- 关于VC++中,两种自定义消息的发送与接收的方法实现进行说明。
- 关于VC++中,两种自定义消息的发送与接收的方法实现进行说明
- 关于VC++中,两种自定义消息的发送与接收的方法实现进行说明。
- 关于VC++中,两种自定义消息的发送与接收的方法实现进行说明
- ActiveMQ消息发送和接收
- ActiveMQ消息发送和接收
- ActiveMQ消息发送和接收
- Java-多个多线程求和例子以及各种方式的执行效率对比
- 为什么用mui框架写的头部,放进安卓原生态开发里边,头部不见了,只有头部以下的内容?
- Kotlin 类 对象 函数
- 小学奥数公式大全 学习奥数必备“工具”
- 有関Failed to start component [StandardEngine[Catalina].StandardHost[localhost]問題
- 关于MNS消息发送和接收的实现问题
- GooglePlay上架流程
- 初入自动化行业,请多关照。
- jQuery判断一个元素是否含有一个指定的类(class)
- java中基本数据类型转换
- dto简单应用介绍 http://blog.csdn.net/visant
- Python的安装
- 用JQ去实现数字动态增加动画
- 欢迎使用CSDN-markdown编辑器