1、前言

surging内部使用的是高性能RPC远程服务调用,如果用json.net序列化肯定性能上达不到最优,所以后面扩展了protobuf,messagepack序列化组件,以支持RPC二进制传输.

在这里需要感谢白纸无字Zonciu,新增了messagepack序列化,让surging 性能上跨了一大步。此篇文章我们来谈谈messagepack、protobuffer、json.net ,并且性能做下对比

开源地址:https://github.com/dotnetcore/surging

2、序列化组件

2.1 surging 使用的是以下序列化组件:

json.net:surging 使用的是Newtonsoft.Json, 它是基于json格式的序列化和反序列化的组件.官方网站: http://json.codeplex.com/

protobuf:surging 使用的是protobuf-net, 它是基于二进制格式的序列化和反序列化的组件.官方网站: https://github.com/mgravell/protobuf-net

messagepack:surging 使用的是MessagePack-CSharp, 它是基于二进制格式的序列化和反序列化的组件.官方网站: https://github.com/neuecc/MessagePack-CSharp

2.2 各个组件的优点

json.net 有以下优点:

  • 侵入性:可以不添加attribute,就能进行序列化操作
  • 灵活性:可以灵活性配置,比如允许被序列化的成员自定义名字,屏蔽的非序列化属性成员
  • 可读性: 数据格式比较简单, 易于读写
  • 依赖性:可以序列化成JObject,无需依赖对象进行序列化和泛型化。

protobuf 有以下优点:

  • 性能高 序列化后体积相比Json和XML很小,适合RPC二进制传输
  • 跨语言:支持跨平台多语言
  • 兼容性:消息格式升级和兼容性还不错
  • 速度快 :序列化反序列化速度很快,快于Json的处理速速

messagepack有以下优点:

  • 性能高 序列化后体积相比JsonXML很小,适合RPC二进制传输
  • 跨语言:支持跨平台多语言
  • 兼容性:消息格式升级和兼容性还不错
  • 速度快 :序列化反序列化速度很快,快于Json的处理速度

针对于protobufmessagepack都是基于二进制格式的序列化和反序列化,优点都一样,但是基于messagepackMessagePack-CSharp组件侵入性更小,可以不需要加attribute,而且性能上更优.下一节来看看组件在surging 中的表现

3. 性能比较

服务端:

(注:如果不加UseProtoBufferCodecUseMessagePackCodec就是json.net序列化)

var host = new ServiceHostBuilder().RegisterServices(option =>{option.Initialize(); //初始化服务option.RegisterServices(); //依赖注入领域服务option.RegisterRepositories(); //依赖注入仓储option.RegisterModules(); //依赖注入第三方模块option.RegisterServiceBus(); //依赖注入ServiceBus}).RegisterServices(builder =>{builder.AddMicroService(option =>{option.AddServiceRuntime(); //// option.UseZooKeeperManager(new ConfigInfo('127.0.0.1:2181')); //使用Zookeeper管理option.UseConsulManager(new ConfigInfo('127.0.0.1:8500')); //使用Consul管理option.UseDotNettyTransport(); //使用Netty传输option.UseRabbitMQTransport(); //使用rabbitmq 传输option.AddRabbitMQAdapt(); //基于rabbitmq的消费的服务适配// option.UseProtoBufferCodec();//基于protobuf序列化传输option.UseMessagePackCodec(); //基于MessagePack序列化传输builder.Register(p => new CPlatformContainer(ServiceLocator.Current)); //初始化注入容器});}).SubscribeAt() //消息订阅.UseServer('127.0.0.1', 98)//.UseServer('127.0.0.1', 98,“true”) //自动生成Token//.UseServer('127.0.0.1', 98,“123456789”) //固定密码Token.UseStartup<Startup>().Build();using (host.Run()) {Console.WriteLine($'服务端启动成功,{DateTime.Now}。');}

客户端:

  /// <summary>/// 测试/// </summary>/// <param name='serviceProxyFactory'></param>public static void Test(IServiceProxyFactory serviceProxyFactory){Task.Run(async () =>{var userProxy = serviceProxyFactory.CreateProxy<IUserService>('User');await userProxy.GetUserId("user");do{Console.WriteLine("正在循环 1w次调用 GetUser.....");//1w次调用var watch = Stopwatch.StartNew();for (var i = 0; i < 10000; i){var a = userProxy.GetDictionary().Result;}watch.Stop();Console.WriteLine($"1w次调用结束,执行时间:{watch.ElapsedMilliseconds}ms");Console.ReadLine();} while (true);}).Wait();}

测试 0 object(注:测试无参数)

 /// <summary>/// 测试/// </summary>/// <param name='serviceProxyFactory'></param>public static void Test(IServiceProxyFactory serviceProxyFactory){Task.Run(async () =>{var userProxy = serviceProxyFactory.CreateProxy<IUserService>('User');await userProxy.GetUserId("user");do{Console.WriteLine("正在循环 1w次调用 GetUser.....");//1w次调用var watch = Stopwatch.StartNew();for (var i = 0; i < 10000; i){var a = userProxy.GetDictionary().Result;}watch.Stop();Console.WriteLine($"1w次调用结束,执行时间:{watch.ElapsedMilliseconds}ms");Console.ReadLine();} while (true);}).Wait();}

测试 1 object(注:测试参数传对象)

   /// <summary>/// 测试/// </summary>/// <param name='serviceProxyFactory'></param>public static void Test(IServiceProxyFactory serviceProxyFactory){Task.Run(async () =>{var userProxy = serviceProxyFactory.CreateProxy<IUserService>('User');await userProxy.GetUserId("user");do{Console.WriteLine("正在循环 1w次调用 GetUser.....");//1w次调用var watch = Stopwatch.StartNew();for (var i = 0; i < 10000; i){var a = userProxy.GetUser(new UserModel { UserId = 1 }).Result;}watch.Stop();Console.WriteLine($"1w次调用结束,执行时间:{watch.ElapsedMilliseconds}ms");Console.ReadLine();} while (true);}).Wait();}

测试 10 object(注:测试参数传List 集合对象)

/// <summary>/// 测试/// </summary>/// <param name='serviceProxyFactory'></param>public static void Test(IServiceProxyFactory serviceProxyFactory){Task.Run(async () =>{var userProxy = serviceProxyFactory.CreateProxy<IUserService>('User');await userProxy.GetUserId('user');var list = new List<UserModel>();for(int i=0;i<10;i ){list.Add(new UserModel { UserId = 1, Age = 18, Name = 'fanly' });}do{Console.WriteLine('正在循环 1w次调用 GetUser.....');//1w次调用var watch = Stopwatch.StartNew();for (var i = 0; i < 10000; i ){var a =userProxy.Get(list).Result;}watch.Stop();Console.WriteLine($'1w次调用结束,执行时间:{watch.ElapsedMilliseconds}ms');Console.ReadLine();} while (true);}).Wait();}

测试100 object(注:测试参数传List 集合对象)

/// <summary>/// 测试/// </summary>/// <param name='serviceProxyFactory'></param>public static void Test(IServiceProxyFactory serviceProxyFactory){Task.Run(async () =>{var userProxy = serviceProxyFactory.CreateProxy<IUserService>('User');await userProxy.GetUserId('user');var list = new List<UserModel>();for(int i=0;i<100;i )
{list.Add(, Age = , Name = 'fanly' });}do{Console.WriteLine('正在循环 1w次调用 GetUser.....');//1w次调用var watch = Stopwatch.StartNew();for (var i = 0; i < 10000; i )
{var a =userProxy.Get(list).Result;}watch.Stop();Console.WriteLine($'1w次调用结束,执行时间:{watch.ElapsedMilliseconds}ms');Console.ReadLine();} while (true);}).Wait();}

通过以上测试代码,我们得到了如下的测试结果

通过上图,可以发现messagepack不管是小数据量还是大数据量都保持比较稳定的性能,而json.net100object平均已经达到了1.1ms,和messagepack、protobuffer比差太多,而 protobuffer在此次测试中表现的极其不稳定只有在1 object100 object 性能比较不错,但是与messagepack比还是相差比较大。所以我建议还是使用messagepack,性能上更优,侵入性也非常低

我们来看看性能最优的messagepack 详细测试数据

o object:

1 object:

10 object:

100 object

测试环境

CPU:Intel Core i7-4710MQ

内存:16G

硬盘:1T SSD 512G HDD

网络:局域网

基于.NET CORE框架Surging相关推荐

  1. 基于.NET CORE微服务框架 -谈谈surging API网关

    1.前言 对于最近surging更新的API 网关大家也有所关注,也收到了不少反馈提出是否能介绍下Api网关,那么我们将在此篇文章中谈谈surging Api 网关 开源地址:https://gith ...

  2. 基于.NET CORE微服务框架 -谈谈surging的服务容错降级

    一.前言 对于不久开源的surging受到不少.net同学的青睐,也受到.net core学习小组的关注,邀请加入.NET China Foundation 以方便国内.net core开源项目的推广 ...

  3. 基于.NET CORE微服务框架 -谈谈Cache中间件和缓存降级

    1.前言 surging受到不少.net同学的青睐,也提了不少问题,提的最多的是什么时候集成API 网关,在这里回答大家最近已经开始着手研发,应该在1,2个月内会有个初版API网关,其它像Token身 ...

  4. 软件著作权 开源框架_开源软件分享-基于.net core 3.1的快速开发框架

    曾几何时.NET们很羡慕JAVA的生态,java开源生态里面你用得着的几乎都有开源的实现.比如大数据.微服务.以及各种各样的快速开发框架,特别是spring boot出来以后,简化了SSM那套繁琐的配 ...

  5. 基于DotNet Core的RPC框架(一) DotBPE.RPC快速开始

    0x00 简介 DotBPE.RPC是一款基于dotnet core编写的RPC框架,而它的爸爸DotBPE,目标是实现一个开箱即用的微服务框架,但是它还差点意思,还仅仅在构思和尝试的阶段.但不管怎么 ...

  6. Delphi Web前端开发教程(2):基于TMS WEB Core框架

    简介 Delphi是软件行业的传奇编程语言之一,该产品于1995年2月14日情人节在美国San Francisco(旧金山)正式发布,她是软件开发历史的基石.今天随着IT科技的飞速发展,各种新平台和框 ...

  7. Delphi Web应用开发B/S框架推荐:《Delphi Web前端开发教程——基于TMS WEB Core框架》

    使用TMS WEB Core 发现Delphi软件开发的无限潜能-- 二十多年来,编程语言Delphi 以对 Windows 应用程序的快速可视化编程而闻名于世.尤其是轻松开发桌面数据库应用程序和快捷 ...

  8. Abp框架从零开始(基于.Net Core 2.2) 小记(五) 将服务器部署在IIS上

    这一篇,我们尝试将我们的Abp项目部署到IIS上. 首先回顾下Abp框架从零开始(基于.Net Core 2.2) 小记(一) 为Swagger接口页添加详细注释这篇文章,为我们的接口添加上详细的注释 ...

  9. 【ASP.NET CORE】 Surging 分布式微服务框架学习笔记(1)

    2019年02月24日,终于完成之前的项目.发现多年的工作开发节奏有点脱节了,刚好有时间多学一下,同时在这里记录一下爬坑遇到的问题.之前一直使用WEB API 做单点服务端开发,其中涉及到 ASP.N ...

最新文章

  1. 北漂经历 | 我在北京这几年
  2. 2016 版 Laravel 系列入门教程(一)
  3. .NET智能客户端(SmartClient)
  4. 多而杂不会成为重点-丰收节贸易会:未来农业的发展方向
  5. 追求代码质量: 用 AOP 进行防御性编程
  6. deepin linux深度ISO镜像下载地址
  7. 微型计算机硬件技术基础答案,计算机硬件技术基础_万晓冬_习题
  8. 一起谈.NET技术,ASP.NET 请求处理流程
  9. 机器学习训练营_如何不运行学习代码训练营
  10. centos关闭邮件提醒
  11. mysql 变量被引号括住_【已解决】mysql中操作表的字段名时是否一定要用反引号括起来...
  12. 95-130-346-源码-source-kafka相关-KafkaConsumerThread
  13. 卷积神经网络的前世今生
  14. 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第3节 线程同步机制_8_解决线程安全问题_Lock锁...
  15. 在Visio里加上、下标方法
  16. linux下ntp服务配置
  17. 免费开源网站系统html,全CMS开源系统
  18. Deep Gait Recognition: A Survey 阅读笔记
  19. php计数器归零,php计数器lt;?/*-一个简单的计数器*/functio 爱问知识人
  20. Welcome Here

热门文章

  1. 【电量计芯片】鼎盛合分享手机电量显示电量芯片技术
  2. c语言void形式的函数,C语言的void类型
  3. void* 作为函数参数,函数返回值的用法
  4. 2015爱奇艺暑期实习生面试
  5. Bitmap Index Scan
  6. [DForm]我也来做自定义Winform之另类标题栏重绘
  7. 计算机组成原理——辅助存储器
  8. Java高级编程架构——Spring实战:Spring初探
  9. 793291696 txttoserver
  10. java 过滤器过滤特殊字符