在上一篇中,我们介绍了消息的顺序收发保证:

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

在本文中我们主要介绍下复杂对象消息是否需要支持序列化以及消息的持久化。

在实际的业务应用开发中,我们经常会将复杂业务对象放到消息里面,实现异构系统之间的集成、模块间的解耦等等。

同时,我们还比较关注消息队列服务是否支持消息的持久化,消息队列如果宕机后持久化的消息是否可以还原?

在Azure Messaging的官方说明中,没有特地的介绍复杂对象消息是否需要支持序列化的要求,但是,我们在上篇博文中,有个消息创建方法,as following,

BrokeredMessage类的构造函数:

//
// Summary:
// Constructor that creates a BrokeredMessage from a given object using the
// provided XmlObjectSerializer
//
// Parameters:
// serializableObject:
// The serializable object.
//
// serializer:
// The serializer object.
//
// Exceptions:
// System.ArgumentNullException:
// Thrown when null serializer is passed to the method with a non-null serializableObject
//
// Remarks:
// You should be aware of the exceptions that their provided Serializer can
// throw and take appropriate actions. Please refer to for a possible list of
// exceptions and their cause.
public BrokeredMessage(object serializableObject, XmlObjectSerializer serializer);

看来消息的构造,支持动态传入XmlObjectSerializer, so,

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

接下来,我们用上一篇中的代码,做一个复杂对象消息收发的测试,我们还是用上次的SalesOrder类,但是增加一个SalesOrderItem集合和双向关联,来描述销售订单和销售订单明细的的1:n的业务领域模型。

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; } private List<SalesOrderItem> items; /// <summary>
/// 销售订单明细
/// </summary>
public List<SalesOrderItem> Items
{
get
{
if (items == null)
items = new List<SalesOrderItem>(); return items;
}
set
{
items = value;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace AzureMessaging.FIFO
{
/// <summary>
/// 销售订单明细
/// </summary>
public class SalesOrderItem
{
/// <summary>
/// 标识
/// </summary>
public string ID { get; set; } /// <summary>
/// 客户ID
/// </summary>
public int CustomerID { get; set; } /// <summary>
/// 所属的销售订单ID
/// </summary>
public string SalesOrderID
{
get
{
if (Order != null)
return Order.OrderID; return string.Empty;
}
} /// <summary>
/// 所属的销售订单
/// </summary>
public SalesOrder Order { get; set; }
}
}

创建销售订单实例类方法:

  private static SalesOrder CreateSalesOrder(int i)
{
var order = new SalesOrder() { OrderID = i.ToString(), Code = "SalesOrder_" + i, CreateTime = DateTime.Now, ProductID = , TotalPrice = new decimal() };
order.Items.Add(new SalesOrderItem() { ID = Guid.NewGuid().ToString(), Order = order, CustomerID = }); return order;
}

在构造SalesOrder和SalesOrderItems时,我们做了双向关联。
消息顺序收发测试:

 using Microsoft.ServiceBus.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace AzureMessaging.FIFO
{
class Program
{
private static readonly string queueName = "OrderQueue";
static void Main(string[] args)
{
MessageSend();
Console.ReadKey(); MessageReceive();
Console.ReadKey();
} /// <summary>
/// 发送消息
/// </summary>
private static void MessageSend()
{
var sbUtils = new ServiceBusUtils(); //创建队列
sbUtils.CreateQueue(queueName, false); //顺序发送消息到OrderQueue
var queueSendClient = sbUtils.GetQueueClient(queueName);
for (int i = ; i < ; i++)
{
var order = CreateSalesOrder(i);
var message = sbUtils.Create(order);
queueSendClient.Send(message);
Console.WriteLine(string.Format("Send {0} MessageID: {1}", i, message.MessageId));
} Console.WriteLine("Send Completed!");
} /// <summary>
/// 接收消息
/// </summary>
private static void MessageReceive()
{
int index = ;
BrokeredMessage msg = null;
var sbUtils = new ServiceBusUtils();
var queueReveiveClient = sbUtils.GetReceiveQueueClient(queueName, ReceiveMode.ReceiveAndDelete);
while ((msg = queueReveiveClient.Receive(TimeSpan.FromMilliseconds())) != null)
{
Console.WriteLine(string.Format("Received {0} MessageID: {1}", index, msg.MessageId));
index++;
} ////删除队列
//sbUtils.DeleteQueue(queueName); Console.WriteLine("Receive Completed!");
} private static SalesOrder CreateSalesOrder(int i)
{
var order = new SalesOrder() { OrderID = i.ToString(), Code = "SalesOrder_" + i, CreateTime = DateTime.Now, ProductID = , TotalPrice = new decimal() };
order.Items.Add(new SalesOrderItem() { ID = Guid.NewGuid().ToString(), Order = order, CustomerID = }); return order;
}
}
}

可以看出,复杂对象消息只要指定适当的XmlObjectSerializer,即可。

在双向引用这种领域模型的设计场景下,我们配置了PreserveObjectReferences = true

var serializer = new DataContractSerializer(serializableObject.GetType(),
new DataContractSerializerSettings() { IgnoreExtensionDataObject = true, PreserveObjectReferences = true });

解决了序列化时循环引用的问题。
关于消息的持久化,Azure messaging有官方的说明:所有的队列都是持久化的,持久化存储是SQL Server,不提供内存中的消息队列。

毕竟是PaaS层的消息队列服务,消息的持久化和高可用性微软还是有保障的。

本篇中我们介绍并验证了Azure Messaging Service Bus复杂对象消息是否需要支持序列化和消息持久化,下一篇我们继续介绍消息的重复发送问题。

周国庆

2017/3

Azure Messaging-ServiceBus Messaging消息队列技术系列4-复杂对象消息是否需要支持序列化和消息持久化的更多相关文章

  1. Azure Messaging-ServiceBus Messaging消息队列技术系列-索引篇

    Azure Messaging ServiceBus Messaging相关的技术系列,最近已经整理了不少了,统一做一个索引链接,置顶. 方便查找,并后续陆陆续续再增加. 学习消息队列技术,可以先看第 ...

  2. Azure Messaging-ServiceBus Messaging消息队列技术系列5-重复消息:at-least-once at-most-once

    上篇博客中,我们用实际的业务场景和代码示例了Azure Messaging-ServiceBus Messaging对复杂对象消息的支持和消息的持久化: Azure Messaging-Service ...

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

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

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

    上篇博文中我们介绍了Azure ServiceBus Messaging的消息事务机制: Azure Messaging-ServiceBus Messaging消息队列技术系列7-消息事务(2017 ...

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

    上篇博文中我们介绍了Azure Messaging的重复消息机制.At most once 和At least once. Azure Messaging-ServiceBus Messaging消息 ...

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

    前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家. 首先,Windows Azure提供了两种类型 ...

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

    各位,上一篇基本概念和架构中,我们介绍了Window Azure ServiceBus的消息队列技术的概览.接下来,我们进入编程模式和详细功能介绍模式,一点一点把ServiceBus技术研究出来. 本 ...

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

    前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家. 首先,Windows Azure提供了两种类型 ...

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

    各位,上一篇基本概念和架构中,我们介绍了Window Azure ServiceBus的消息队列技术的概览.接下来,我们进入编程模式和详细功能介绍模式,一点一点把ServiceBus技术研究出来. 本 ...

随机推荐

  1. 算法一之N皇后问题

    (写这篇文章主要是明天就要考试了,算法考试,今天不想再复习了,xiang着今天也开通了博客,于是在这个平台上进行复习,应该会更高效.最后祝愿我明天考个好成绩.嘻嘻...) n皇后问题,主要是应用到回溯 ...

  2. 结合swiper使用图片懒加载

    本人渣渣一枚,技术一般,记录下笔记,大神勿喷,可以留下优化建议,谢谢 最近刚刚做了个展示型的网站,使用swiper搭的框架,因为图片比较多,所 以首次加载稍微有些慢,虽然压缩过了,但是尽可能的优化吧, ...

  3. yum网络源配置

    [root@xuegod60 ~]# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak[root@x ...

  4. POJ2503(hash)

    Babelfish Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 41263   Accepted: 17561 Descr ...

  5. office如何去除多页签

    写文档会遇到同时打开多个文档,偶尔可能需要对比,而有时office会出现跟浏览器类似的多页签界面.如何去除多页签,office本身没有此加载项,一般都是作为插件或组件形式另外安装,导致我们不知道从哪里 ...

  6. Git学习之路(4)- 撤销操作、删除文件和恢复文件

    ▓▓▓▓▓▓ 大致介绍 经过前面的学习(小白学Git)已经建立了版本库,并上传了文件,这次来学习对这些文件进行基本的操作,即: ◆ 撤销操作 ◆ 删除文件 ◆ 恢复文件 我在此之前,已经将三个文件提交 ...

  7. 【小梅哥FPGA进阶教程】第九章 基于串口猎人软件的串口示波器

    九.基于串口猎人软件的串口示波器 1.实验介绍 本实验,为芯航线开发板的综合实验,该实验利用芯航线开发板上的ADC.独立按键.UART等外设,搭建了一个具备丰富功能的数据采集卡,芯航线开发板负责进行数 ...

  8. nginx : server_name localhost 和 chrome : Provisional headers are shown

    问题相关问题现象:解决思路解决方案总结 问题相关 nginx : server_name localhost chrome : Provisional headers are shown 问题现象: ...

  9. Python学习--20 Web开发

    HTTP格式 HTTP协议是基于TCP和IP协议的.HTTP协议是一种文本协议. 每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的. HTTP ...

  10. 基于Spring DM管理的Bundle获取Spring上下文对象及指定Bean对象

    在讲述服务注册与引用的随笔中,有提到context.getServiceReferences()方法,通过该方法可以获取到OSGI框架容器中的指定类型的服务引用,从而获取到对应的服务对象.同时该方法还 ...