(六)分布式通信----MessagePack序列化
==>>点击查看本系列文章目录
1. .Net Core的序列化方式
1.1 json.Net
常用的工具包,如Newtonsoft.Json, 它是基于json格式的序列化和反序列化的组件
json.net 有以下优点:
侵入性:可以不添加attribute,就能进行序列化操作
灵活性:可以灵活性配置,比如允许被序列化的成员自定义名字,屏蔽的非序列化属性成员
可读性: 数据格式比较简单, 易于读写
依赖性:可以序列化成JObject,无需依赖对象进行序列化和泛型化。
1.2 protobuf
它是基于二进制格式的序列化和反序列化的组件
protobuf 有以下优点:
性能高 : 序列化后体积相比Json和XML很小,适合RPC二进制传输
跨语言:支持跨平台多语言
兼容性:消息格式升级和兼容性还不错
速度快 :序列化反序列化速度很快,快于Json的处理速度
1.3 messagepack
它是基于二进制格式的序列化和反序列化的组件
messagepack有以下优点:
性能高:序列化后体积相比Json和XML很小,适合RPC二进制传输
跨语言:支持跨平台多语言
兼容性:消息格式升级和兼容性还不错
速度快 :序列化反序列化速度很快,快于Json的处理速度
messagepack不管是小数据量还是大数据量都保持比较稳定的性能,本文中使用messagepack序列化方式。
2. 项目编码及设计模式
如下是文件结构:
2.1 工厂模式
抽象接口 工厂负责创建编码器和解码器
1.工厂
/// <summary>
/// 一个抽象的传输消息编解码器工厂。
/// </summary>
public interface ITransportMessageCodecFactory
{
/// <summary>
/// 获取编码器。
/// </summary>
/// <returns>编码器实例。</returns>
ITransportMessageEncoder GetEncoder(); /// <summary>
/// 获取解码器。
/// </summary>
/// <returns>解码器实例。</returns>
ITransportMessageDecoder GetDecoder();
}
2.编码器
/// <summary>
/// 编码器
/// </summary>
public interface ITransportMessageEncoder
{
byte[] Encode(TransportMessage message);
}
3.解码器
/// <summary>
/// 解码器
/// </summary>
public interface ITransportMessageDecoder
{
TransportMessage Decode(byte[] data);
}
实现类 工厂、编码器、解码器为MessagePack的实现
1.工厂
public sealed class MessagePackTransportMessageCodecFactory : ITransportMessageCodecFactory
{
#region Field
private readonly ITransportMessageEncoder _transportMessageEncoder = new MessagePackTransportMessageEncoder();
private readonly ITransportMessageDecoder _transportMessageDecoder = new MessagePackTransportMessageDecoder();
#endregion Field #region Implementation of ITransportMessageCodecFactory /// <inheritdoc />
/// <summary>
/// 获取编码器
/// </summary>
/// <returns></returns>
public ITransportMessageEncoder GetEncoder()
{
return _transportMessageEncoder;
} /// <inheritdoc />
/// <summary>
/// 获取解码器
/// </summary>
/// <returns></returns>
public ITransportMessageDecoder GetDecoder()
{
return _transportMessageDecoder;
}
#endregion Implementation of ITransportMessageCodecFactory
}
2.编码器
public sealed class MessagePackTransportMessageEncoder : ITransportMessageEncoder
{
#region Implementation of ITransportMessageEncoder public byte[] Encode(TransportMessage transportMessage)
{
MessagePackTransportMessage messagePackTransportMessage = new MessagePackTransportMessage(transportMessage);
return MessagePackSerializer.Serialize(messagePackTransportMessage);
} #endregion Implementation of ITransportMessageEncoder
}
3.解码器
public sealed class MessagePackTransportMessageDecoder : ITransportMessageDecoder
{
#region Implementation of ITransportMessageDecoder public TransportMessage Decode(byte[] data)
{
MessagePackTransportMessage messagePackTransportMessage = MessagePackSerializer.Deserialize<MessagePackTransportMessage>(data);
return messagePackTransportMessage.GetTransportMessage();
} #endregion Implementation of ITransportMessageDecoder
}
2.2 装饰器模式
高层的消息模型:
public class TransportMessage
{
/// <summary>
/// 消息Id。
/// </summary>
public string Id { get; set; } /// <summary>
/// 消息内容。
/// </summary>
public object Content { get; set; } /// <summary>
/// 内容类型。
/// </summary>
public string ContentType { get; set; }
}
由于MessagePack序列化方式具有侵入性,需要添加 MessagePackObjectAttribute 和 KeyAttribute 特性,因此需要对 TransportMessage 做装饰:
using MessagePack; [MessagePackObject]
public class MessagePackTransportMessage
{
private TransportMessage _transportMessage;
public MessagePackTransportMessage(): this(new TransportMessage())
{
} public MessagePackTransportMessage(TransportMessage transportMessage)
{
this._transportMessage = transportMessage;
} public TransportMessage GetTransportMessage()
{
return _transportMessage;
}
/// <summary>
/// 消息Id。
/// </summary>
[Key()]
public string Id
{
get { return _transportMessage.Id; }
set { _transportMessage.Id = value; }
} /// <summary>
/// 消息内容。
/// </summary>
[Key()]
public object Content
{
get { return _transportMessage.Content; }
set { _transportMessage.Content = value; }
} /// <summary>
/// 内容类型。
/// </summary>
[Key()]
public string ContentType
{
get { return _transportMessage.ContentType; }
set { _transportMessage.ContentType = value; }
}
}
2.3 依赖注入
Autofac 是一个依赖注入工具包,比.net Core 原始的依赖注入拥有更完善的功能,中文官方文档:https://autofaccn.readthedocs.io/zh/latest/index.html
using Autofac; public static class ContainerBuilderExtensions
{
/// <summary>
/// 使用messagepack编码解码方式
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
public static ContainerBuilder UseMessagePackCodec(this ContainerBuilder builder)
{
builder.RegisterType(typeof(MessagePackTransportMessageCodecFactory)).As(typeof(ITransportMessageCodecFactory)).SingleInstance();
return builder;
}
}
2.4 单元测试
端到端的测试,同时测试编码和解码
using MessagePack;
using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass]
public class MessagePackTest
{
[TestMethod]
public void TestCodec()
{
Person person = new Person
{
Name = "张宏伟",
Age =
};
TransportMessage transportMessage = new TransportMessage
{
Id = "",
ContentType = "Person",
Content = person
};
MessagePackTransportMessageCodecFactory factory = new MessagePackTransportMessageCodecFactory();
ITransportMessageEncoder encoder = factory.GetEncoder();
ITransportMessageDecoder decoder = factory.GetDecoder();
byte[] vs = encoder.Encode(transportMessage);
TransportMessage message =decoder.Decode(vs);
Assert.AreEqual(message.Id, "");
Assert.AreEqual(message.ContentType, "Person");
Assert.AreEqual(((object[])message.Content)[].ToString(), "张宏伟" );
Assert.AreEqual(((object[])message.Content)[].ToString(), "");
} [MessagePackObject]
public class Person
{
[Key()]
public string Name { get; set; }
[Key()]
public int Age { get; set; }
}
}
(六)分布式通信----MessagePack序列化的更多相关文章
- CRL快速开发框架系列教程六(分布式缓存解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable
酒,是个好东西,前提要适量.今天参加了公司的年会,主题就是吃.喝.吹,除了那些天生话唠外,大部分人需要加点酒来作催化剂,让一个平时沉默寡言的码农也能成为一个喷子!在大家推杯换盏之际,难免一些画面浮现脑 ...
- spring boot / cloud (十六) 分布式ID生成服务
spring boot / cloud (十六) 分布式ID生成服务 在几乎所有的分布式系统或者采用了分库/分表设计的系统中,几乎都会需要生成数据的唯一标识ID的需求, 常规做法,是使用数据库中的自动 ...
- axis实现webservices分布式通信
分布式通信原理 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2ZsMjAxMjEzMTQ=/font/5a6L5L2T/fontsize/400/fil ...
- 10.axis实现webservices分布式通信
转自:https://www.aliyun.com/jiaocheng/310112.html 分布式通信原理 基本原理:stub和skeleton作为客户端和服务端传输的中介,stub和skelet ...
- dotnet 使用 MessagePack 序列化对象
和很多序列化库一样,可以通过 MessagePack 序列化和反序列化,和 json 相比这个库提供了二进制的序列化,序列化之后的内容长度比 json 小很多 这个库能序列的内容不多,大多数时候建议使 ...
- 4.7 ROS分布式通信
4.7 ROS分布式通信 ROS是一个分布式计算环境.一个运行中的ROS系统可以包含分布在多台计算机上多个节点.根据系统的配置方式,任何节点可能随时需要与任何其他节点进行通信. 因此,ROS对网络配置 ...
- SignalR 中使用 MessagePack 序列化提高 WebSocket 通信性能
It's like JSON.but fast and small. MessagePack is an efficient binary serialization format. It lets ...
- (七)分布式通信----Netty实现NIO通信
目录 1. 消息监听器 2. 指令执行器 3. 消息发送器 4. 客户端工厂 5. 序列化工具 6. 通信主机 项目文件结构图 通信主机: 1. 消息监听器(黄色框) 这部分由 Netty 实现,Ne ...
随机推荐
- nginx文件名逻辑漏洞_CVE-2013-4547漏洞复现
nginx文件名逻辑漏洞_CVE-2013-4547漏洞复现 一.漏洞描述 这个漏洞其实和代码执行没有太大的关系,主要原因是错误地解析了请求的URL,错误地获取到用户请求的文件名,导致出现权限绕过.代 ...
- docker学习ppt
保存下学习资料
- [系列] Go gRPC Hello World
目录 概述 四类服务方法 安装 写个 Hello World 服务 推荐阅读 概述 开始 gRPC 了,这篇文章学习使用 gRPC,输出一个 Hello World. 用 Go 实现 gRPC 的服务 ...
- html5教程 《实用技巧》—让你的网站变成响应式的3个简单步骤
如今,一个网站只在桌面屏幕上好看是远远不够的,同时也要在平板电脑和智能手机中能够良好呈现.响应式的网站是指它能够适应客户端的屏幕尺寸,自动响应客户端尺寸变化.在这篇文章中,我将向您展示如何通过3个简单 ...
- 2019杭电多校第二场hdu6602 Longest Subarray(线段树)
Longest Subarray 题目传送门 解题思路 本题求一个最大的子区间,满足区间内的数字要么出现次数大于等于k次,要么没出现过.给定区间内的数字范围是1~c. 如果r为右边界,对于一种数字x, ...
- SpringBoot入门(二):日志及自定义属性
这一章主要说springboot中日志的配置.自定义属性的配置与读取.分环境的yml配置文件(如本地环境.测试环境.生产环境等).比较偏向实际开发,较为实用,前面一章的一些基本创建在这里就不多废话了. ...
- 使用vsftp与shell实现对进程与服务状态的监控
先说一下需求吧,公司开发了一款新的产品,新产品嘛,有着不得不出问题的理由,四个云机房,总共三百余台机器,需要实时的监控进程状态,虽然有zabbix来实现,但领导需求是脚本和zabbix一起做,zabb ...
- Git 从master拉取代码创建新分支
从master拉取新分支并push到远端 开发过程中经常用到从master分支copy一个开发分支: 1.切换到被copy的分支(master),并且从远端拉取最新版本 $git checkout m ...
- linux文本编辑vim命令
1.Vim Vim 是一个功能强大的全屏幕文本编辑器,是 Linux/UNIX 上最常用的文本编辑器,它的作用是建立.编辑.显示文本文件. Vim 没有菜单,只有命令 2.Vim 工作模式 3.插入 ...
- kube-scheduler源码分析
kubernetes集群三步安装 kube-scheduler源码分析 关于源码编译 我嫌弃官方提供的编译脚本太麻烦,所以用了更简单粗暴的方式编译k8s代码,当然官方脚本在编译所有项目或者夸平台编译以 ...