Azure Messaging-ServiceBus Messaging消息队列技术系列4-复杂对象消息是否需要支持序列化和消息持久化
在上一篇中,我们介绍了消息的顺序收发保证:
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-复杂对象消息是否需要支持序列化和消息持久化的更多相关文章
- Azure Messaging-ServiceBus Messaging消息队列技术系列-索引篇
Azure Messaging ServiceBus Messaging相关的技术系列,最近已经整理了不少了,统一做一个索引链接,置顶. 方便查找,并后续陆陆续续再增加. 学习消息队列技术,可以先看第 ...
- Azure Messaging-ServiceBus Messaging消息队列技术系列5-重复消息:at-least-once at-most-once
上篇博客中,我们用实际的业务场景和代码示例了Azure Messaging-ServiceBus Messaging对复杂对象消息的支持和消息的持久化: Azure Messaging-Service ...
- Azure Messaging-ServiceBus Messaging消息队列技术系列3-消息顺序保证
上一篇:Window Azure ServiceBus Messaging消息队列技术系列2-编程SDK入门 http://www.cnblogs.com/tianqing/p/5944573.ht ...
- Azure Messaging-ServiceBus Messaging消息队列技术系列8-服务总线配额
上篇博文中我们介绍了Azure ServiceBus Messaging的消息事务机制: Azure Messaging-ServiceBus Messaging消息队列技术系列7-消息事务(2017 ...
- Azure Messaging-ServiceBus Messaging消息队列技术系列6-消息回执
上篇博文中我们介绍了Azure Messaging的重复消息机制.At most once 和At least once. Azure Messaging-ServiceBus Messaging消息 ...
- Window Azure ServiceBus Messaging消息队列技术系列1-基本概念和架构
前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家. 首先,Windows Azure提供了两种类型 ...
- Window Azure ServiceBus Messaging消息队列技术系列2-编程SDK入门
各位,上一篇基本概念和架构中,我们介绍了Window Azure ServiceBus的消息队列技术的概览.接下来,我们进入编程模式和详细功能介绍模式,一点一点把ServiceBus技术研究出来. 本 ...
- Azure Messaging-ServiceBus Messaging消息队列技术系列1-基本概念和架构
前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家. 首先,Windows Azure提供了两种类型 ...
- Azure Messaging-ServiceBus Messaging消息队列技术系列2-编程SDK入门
各位,上一篇基本概念和架构中,我们介绍了Window Azure ServiceBus的消息队列技术的概览.接下来,我们进入编程模式和详细功能介绍模式,一点一点把ServiceBus技术研究出来. 本 ...
随机推荐
- Java 英语
Open quote,左括弧 associated with,关联
- jQuery event,冒泡,默认事件用法
jQuery event,冒泡,默认事件用法 <%@ page language="java" import="java.util.*" pageEnco ...
- 部署AlwaysOn第一步:搭建Windows服务器故障转移集群
在Windows Server 2012 R2 DataCenter 环境中搭建集群之前,首先要对Windows服务器故障转移集群(Windows Server Failover Cluster,简称 ...
- [Scoi2010]游戏
游戏 Time Limit:5000MS Memory Limit:165888KB 64bit IO Format:%lld & %llu Submit Status Pra ...
- oracle sql 知识小结
Oracle_sql : 第一单元:select 语句: ①:字符串连接操作符: || ②:去除重复行:distinct 第二单元:条件限制和排序 ①:关键字:where ②:比较操作符:=,&g ...
- 《JAVASCRIPT高级程序设计》DOM扩展
虽然DOM为XML及HTML文档交互制定了一系列的API,但仍然有几个规范对标准的DOM进行了扩展.这些扩展中,有很多是浏览器专有的,但后来成了事实标准,于是其他浏览器也提供了相同的实现:浏览器开发商 ...
- 利用 UltraEdit 重新排版 XML 结构数据
我们在工作常碰到这种情况,通讯数据或文件数据是以 XML 结构形式保存的,但通常 XML 结构比较混乱,不易分析.现在我们利用 UltraEdit32对该类型数据做 Reformat,具体操作如下: ...
- WinForm——记住密码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runti ...
- Python学习--17 进程和线程
线程是最小的执行单元,而进程由至少一个线程组成.如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间. 进程 fork调用 通过fork()系统调用,就可以生成一个子进程 ...
- C#中字符和字符串总结
Char类是C#提供的字符类型,String是C#提供的字符串类型. 字符: Char类在C#中表示一个Unicode字符. Char类只定义一个Unicode字符. Char类常用的方法及说明如下: ...