Azure Messaging-ServiceBus Messaging消息队列技术系列3-消息顺序保证

上一篇:Window Azure ServiceBus Messaging消息队列技术系列2-编程SDK入门  http://www.cnblogs.com/tianqing/p/5944573.html

介绍了Azure Service Bus的编程SDK(主要的编程接口)

本文中我们以实际的使用场景来说明Azure Messaging是否支持以及如何编码实现:消息的收发顺序保证

消息的收发在实际业务中往往是有顺序的:发送时1-2-3-4-5,接收时也必须是1-2-3-4-5,即FIFO特性。

在本文的Demo中,我们模拟销售订单消息队列异步处理场景,消息体是一条SalesOrder,顺序发送,顺序接收。

1. 我们还是使用上篇博客中在Windows Azure的Portal上建立好的NameSpaceservicebustest

销售订单队列名称:OrderQueue

2.简单封装一个Service Bus的工具类:ServiceBusUtils: 用于创建队列、删除队列、创建QueueClient、创建BrokerdMessage

using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace AzureMessaging.FIFO
{
    /// <summary>
    /// ServiceBus工具类
    /// </summary>
    class ServiceBusUtils
    {
        //Namespace名称
        private static readonly string namespaceName = "servicebustest";

        /// <summary>
        /// 创建队列
        /// </summary>
        /// <param name="queueName">队列名称</param>
        /// <param name="isSession">是否支持会话</param>
        public void CreateQueue(string queueName, bool isSession = true)
        {
            var namespaceClient = NamespaceManager.Create();
            if (namespaceClient.QueueExists(queueName))
            {
                namespaceClient.DeleteQueue(queueName);
            }

            var queue = new QueueDescription(queueName) { RequiresSession = isSession };
            namespaceClient.CreateQueue(queue);
        }

        /// <summary>
        /// 删除队列
        /// </summary>
        /// <param name="queueName">队列名称</param>
        public void DeleteQueue(string queueName)
        {
            var namespaceClient = NamespaceManager.Create();
            if (namespaceClient.QueueExists(queueName))
            {
                namespaceClient.DeleteQueue(queueName);
            }
        }

        /// <summary>
        /// 创建队列客户端
        /// </summary>
        /// <returns>队列客户端</returns>
        public QueueClient GetQueueClient(string queueName, bool isSession = false, ReceiveMode mode = ReceiveMode.ReceiveAndDelete)
        {
            return QueueClient.Create(queueName, mode);
        }
        /// <summary>
        /// 创建队列客户端
        /// </summary>
        /// <returns>队列客户端</returns>
        public QueueClient GetReceiveQueueClient(string queueName, ReceiveMode mode = ReceiveMode.PeekLock)
        {
            var namespaceClient = NamespaceManager.Create();
            return QueueClient.Create(queueName, mode);
        }

        /// <summary>
        /// 构造消息
        /// </summary>
        /// <param name="serializableObject">可序列化的对象</param>
        /// <returns>消息</returns>
        public BrokeredMessage Create(Object serializableObject)
        {
            var serializer = new DataContractSerializer(serializableObject.GetType(),
                new DataContractSerializerSettings() { IgnoreExtensionDataObject = true, PreserveObjectReferences = false });
            var message = new BrokeredMessage(serializableObject);
            message.Properties.Add("Type", serializableObject.GetType().ToString());

            return message;
        }
    }
}

2. 示例SalesOrder实体类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AzureMessaging.FIFO
{
    /// <summary>
    /// 销售订单类
    /// </summary>
    public class SalesOrder
    {
        /// <summary>
        /// 订单ID
        /// </summary>
        public string OrderID { get; set; }

        /// <summary>
        /// 订单编号
        /// </summary>
        public string Code { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 总价格
        /// </summary>
        public Decimal TotalPrice { get; set; }

        /// <summary>
        /// 产品ID
        /// </summary>
        public int ProductID { get; set; }
    }
}

3. 消息顺序发送

向OrderQueue发送10条消息订单消息,输出每条消息的顺序号以及MessageID

private static readonly string queueName = "OrderQueue";
    /// <summary>
        /// 发送消息
        /// </summary>
        private static void MessageSend()
        {
            var sbUtils = new ServiceBusUtils();

            //创建队列
            sbUtils.CreateQueue(queueName, false);

            //顺序发送消息到OrderQueue
            var queueSendClient = sbUtils.GetQueueClient(queueName);
            for (int i = 0; i < 10; i++)
            {
                var order = new SalesOrder() { OrderID = i.ToString(), Code = "SalesOrder_" + i, CreateTime = DateTime.Now, ProductID = 17967, TotalPrice = new decimal(19999) };
                var message = sbUtils.Create(order);
                queueSendClient.Send(message);
                Console.WriteLine(string.Format("Send {0} Message: {1}", i, message.MessageId));
            }

            Console.WriteLine("Send Completed!");
        }

程序输出:

4. 消息顺序接收

消费OrderQueue中的消息,验证消息的接收顺序

private static readonly string queueName = "OrderQueue";
 /// <summary>
        /// 接收消息
        /// </summary>
        private static void MessageReceive()
        {
            int index = 0;
            BrokeredMessage msg = null;
            var sbUtils = new ServiceBusUtils();
            var queueReveiveClient = sbUtils.GetReceiveQueueClient(queueName, ReceiveMode.ReceiveAndDelete);
            while ((msg = queueReveiveClient.Receive(TimeSpan.FromMilliseconds(3))) != null)
            {
                Console.WriteLine(string.Format("Received {0} Message: {1}", index, msg.MessageId));
                index++;
            }

            ////删除队列
            //sbUtils.DeleteQueue(queueName);

            Console.WriteLine("Receive Completed!");
        }

程序输出:

可以看出,Azure Messaging中ServiceBus对消息的收发是有顺序保证的。

下一篇我们继续其他特性的验证和介绍。

周国庆

2017/3/9

时间: 2024-08-18 20:00:57

Azure Messaging-ServiceBus Messaging消息队列技术系列3-消息顺序保证的相关文章

Azure Messaging-ServiceBus Messaging消息队列技术系列8-服务总线配额

上篇博文中我们介绍了Azure ServiceBus Messaging的消息事务机制: Azure Messaging-ServiceBus Messaging消息队列技术系列7-消息事务(2017-03-30 22:12) 本文中我们介绍一下ServiceBus Messaging的一些配额,或者说使用说明和限制.原文请参考: https://docs.microsoft.com/zh-cn/azure/service-bus-messaging/service-bus-quotas 我们着

Azure Messaging-ServiceBus Messaging消息队列技术系列6-消息回执

上篇博文中我们介绍了Azure Messaging的重复消息机制.At most once 和At least once. Azure Messaging-ServiceBus Messaging消息队列技术系列5-重复消息:at-least-once at-most-once 本文中我们主要研究并介绍Azure Messaging的消息回执机制:实际应用场景: 同步收发场景下,消息生产者和消费者双向应答模式,例如:张三写封信送到邮局中转站,然后李四从中转站获得信,然后在写一份回执信,放到中转站

Window Azure ServiceBus Messaging消息队列技术系列1-基本概念和架构

前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家. 首先,Windows Azure提供了两种类型的消息队列机制:Azure Queues和ServiceBus Queues. 其中,Azure Queues,作为Azure Storage基础设施的一部分,提供了一套简单的基于Rest的Interface,面向不同的服务间提供可靠的.持久化的消息队列. ServiceBus Queues作为Az

Window Azure ServiceBus Messaging消息队列技术系列2-编程SDK入门

各位,上一篇基本概念和架构中,我们介绍了Window Azure ServiceBus的消息队列技术的概览.接下来,我们进入编程模式和详细功能介绍模式,一点一点把ServiceBus技术研究出来. 本章我们主要介绍ServiceBus的编程SDK编程入门. 首先,微软提供了两个主要的Nuget Packages: Microsoft Azure Service Bus 3.4.0 主要的NameSpace有以下几个: 1. Microsoft.ServiceBus,这个下面有两个主要的类:Tok

Azure Messaging-ServiceBus Messaging消息队列技术系列7-消息事务

上篇博文中我们介绍了Azure Messaging-ServiceBus Messaging消息回执机制. Azure Messaging-ServiceBus Messaging消息回执机制 本文中我们主要研究消息的事务.直奔主题: Service Bus Queues支持事务,基于TransactionScope Service Bus Queues provide support for local transactions in the context of a single queue

消息队列技术之基本概念

最近一直在总结Azure Messaging ServiceBus Messaging相关的技术:消息顺序.消息持久化.复杂对象消息的序列化.消息事务.消息回执等机制. 感觉有必要补充一篇消息队列技术的基本概念,无论RabbitMQ.ActiveMQ还是其他,都有的一些基本概念.术语.机制,分享给大家,希望大家在搞消息队列技术的时候能够快速 理解.排上用场. 1. 消息生产者.消息者.队列.主题 消息生产者Producer:发送消息到消息队列. 消息消费者Consumer:从消息队列接收消息.

消息队列技术

消息队列技术 上周,我们举办了第二届技术沙龙,我这边主要演讲了消息队列技术的议题,现分享给大家: 在我们团队内部,随着消息应用中心(任务中心)的广泛应用,有时候我们感觉不到消息队列的存在,但这不影响消息队列在高可用.分布式.高并发架构下的核心地位. 消息队列都应用到了哪些实际的应用场景中? 一.再谈消息队列的应用场景 异步处理:例如短信通知.终端状态推送.App推送.用户注册等 数据同步:业务数据推送同步 重试补偿:记账失败重试 系统解耦:通讯上下行.终端异常监控.分布式事件中心 流量消峰:秒杀

再谈消息队列技术

上周,我们举办了第二届技术沙龙,我这边主要演讲了消息队列技术的议题,现分享给大家: 在我们团队内部,随着消息应用中心(任务中心)的广泛应用,有时候我们感觉不到消息队列的存在,但这不影响消息队列在高可用.分布式.高并发架构下的核心地位. 消息队列都应用到了哪些实际的应用场景中? 一.再谈消息队列的应用场景 异步处理:例如短信通知.终端状态推送.App推送.用户注册等 数据同步:业务数据推送同步 重试补偿:记账失败重试 系统解耦:通讯上下行.终端异常监控.分布式事件中心 流量消峰:秒杀场景下的下单处

全面理解Handler第一步:理解消息队列,手写消息队列

前言 Handler机制这个话题,算是烂大街的内容.但是为什么偏偏重拿出来"炒一波冷饭"呢?因为自己发现这"冷饭"好像吃的不是很明白.最近在思考几个问题,发现以之前对Handler机制的了解是在过于浅显.什么问题? Handler机制存在的意义是什么?能否用其他方式替换? Looper.loop();是一个死循环,为什么没有阻塞主线程?用什么样的方式解决死循环的问题? 如果透彻的了解Handler,以及线程的知识.是肯定不会有这些疑问的,因为以上问题本身就存在问题.