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技术研究出来. 本 ...
随机推荐
- 清除delphi 控件DBgrid 的记录
http://blog.csdn.net/windhaunting/article/details/4751560 1.TTable(DBGrid1.DataSource.DataSet).Empty ...
- oracle闪回技术总结之闪回数据库
[实施步骤] 步骤一.设置如下的初始化参数: Sql>小时:以分钟为单位 SQL> 点00分左右发现表被删除 切了几个归档 22:00:38SQL>:06:05 SQL> :0 ...
- spring mvc controller中获取request head内容
spring mvc controller中获取request head内容: @RequestMapping("/{mlid}/{ptn}/{name}") public Str ...
- Flex移动皮肤开发(三)
范例文件 mobile-skinning-part3 在关于创建Flex移动皮肤系列文章的第二部分里,我们讨论了屏幕密度(DPI)对组件皮肤以及移动应用布局所带来的影响. 我还展示了如何使用缩放应用, ...
- MVC + AngularJS 初体验(实现表单操作)
AngularJS AngularJS 通过新的属性和表达式扩展了 HTML. AngularJS 可以构建一个单一页面应用程序(SPAs:Single Page Applications). Ang ...
- Docker环境中部署OwnCloud 9.0
整体思路: 1.官方获取mysql.php+apache镜像: 2.基于php+apache,创建OwnCloud镜像: 3.启动mysql镜像: 4.启动OwnCloud镜像,链接mysql镜像,访 ...
- SimRank协同过滤推荐算法
在协同过滤推荐算法总结中,我们讲到了用图模型做协同过滤的方法,包括SimRank系列算法和马尔科夫链系列算法.现在我们就对SimRank算法在推荐系统的应用做一个总结. 1. SimRank推荐算法的 ...
- 吉特仓储管系统(开源)--使用Grunt压缩JS文件
在吉特仓储管理系统开发的过程中大量使用到了JS,随着JS文件的增多我们需要对JS进行有效的管理,同时也要对JS文件进行一些压缩.文本用于记录一下使用grunt压缩JS的操作步骤,便于遗忘之后记录查找, ...
- Java 异步 IO
新的异步功能的关键点,它们是Channel 类的一些子集,Channel 在处理IO操作的时候需要被切换成一个后台进程.一些需要访问较大,耗时的操作,或是其它的类似实例,可以考虑应用此功能. ...
- Javascript之深入浅出prototype
我们先来讲一个故事,一个大大的池塘,里面有很多鱼.这是属于我们大家的池塘所以里面的鱼我们都可以吃,但是我们也会从集市买一些鱼放在家里,那么放在家里的鱼肯定是属于我们私人的,外人是不会拥有的.那么在js ...