基于.NET CORE框架Surging
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有以下优点:
- 性能高 序列化后体积相比
Json
和XML
很小,适合RPC
二进制传输 - 跨语言:支持跨平台多语言
- 兼容性:消息格式升级和兼容性还不错
- 速度快 :序列化反序列化速度很快,快于
Json
的处理速度
针对于protobuf
和messagepack
都是基于二进制格式的序列化和反序列化,优点都一样,但是基于messagepack
的MessagePack-CSharp
组件侵入性更小,可以不需要加attribute
,而且性能上更优.下一节来看看组件在surging
中的表现
3. 性能比较
服务端:
(注:如果不加UseProtoBufferCodec
和UseMessagePackCodec
就是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.net
在100object
平均已经达到了1.1ms
,和messagepack、protobuffer
比差太多,而 protobuffer
在此次测试中表现的极其不稳定只有在1 object
和100 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相关推荐
- 基于.NET CORE微服务框架 -谈谈surging API网关
1.前言 对于最近surging更新的API 网关大家也有所关注,也收到了不少反馈提出是否能介绍下Api网关,那么我们将在此篇文章中谈谈surging Api 网关 开源地址:https://gith ...
- 基于.NET CORE微服务框架 -谈谈surging的服务容错降级
一.前言 对于不久开源的surging受到不少.net同学的青睐,也受到.net core学习小组的关注,邀请加入.NET China Foundation 以方便国内.net core开源项目的推广 ...
- 基于.NET CORE微服务框架 -谈谈Cache中间件和缓存降级
1.前言 surging受到不少.net同学的青睐,也提了不少问题,提的最多的是什么时候集成API 网关,在这里回答大家最近已经开始着手研发,应该在1,2个月内会有个初版API网关,其它像Token身 ...
- 软件著作权 开源框架_开源软件分享-基于.net core 3.1的快速开发框架
曾几何时.NET们很羡慕JAVA的生态,java开源生态里面你用得着的几乎都有开源的实现.比如大数据.微服务.以及各种各样的快速开发框架,特别是spring boot出来以后,简化了SSM那套繁琐的配 ...
- 基于DotNet Core的RPC框架(一) DotBPE.RPC快速开始
0x00 简介 DotBPE.RPC是一款基于dotnet core编写的RPC框架,而它的爸爸DotBPE,目标是实现一个开箱即用的微服务框架,但是它还差点意思,还仅仅在构思和尝试的阶段.但不管怎么 ...
- Delphi Web前端开发教程(2):基于TMS WEB Core框架
简介 Delphi是软件行业的传奇编程语言之一,该产品于1995年2月14日情人节在美国San Francisco(旧金山)正式发布,她是软件开发历史的基石.今天随着IT科技的飞速发展,各种新平台和框 ...
- Delphi Web应用开发B/S框架推荐:《Delphi Web前端开发教程——基于TMS WEB Core框架》
使用TMS WEB Core 发现Delphi软件开发的无限潜能-- 二十多年来,编程语言Delphi 以对 Windows 应用程序的快速可视化编程而闻名于世.尤其是轻松开发桌面数据库应用程序和快捷 ...
- Abp框架从零开始(基于.Net Core 2.2) 小记(五) 将服务器部署在IIS上
这一篇,我们尝试将我们的Abp项目部署到IIS上. 首先回顾下Abp框架从零开始(基于.Net Core 2.2) 小记(一) 为Swagger接口页添加详细注释这篇文章,为我们的接口添加上详细的注释 ...
- 【ASP.NET CORE】 Surging 分布式微服务框架学习笔记(1)
2019年02月24日,终于完成之前的项目.发现多年的工作开发节奏有点脱节了,刚好有时间多学一下,同时在这里记录一下爬坑遇到的问题.之前一直使用WEB API 做单点服务端开发,其中涉及到 ASP.N ...
最新文章
- 北漂经历 | 我在北京这几年
- 2016 版 Laravel 系列入门教程(一)
- .NET智能客户端(SmartClient)
- 多而杂不会成为重点-丰收节贸易会:未来农业的发展方向
- 追求代码质量: 用 AOP 进行防御性编程
- deepin linux深度ISO镜像下载地址
- 微型计算机硬件技术基础答案,计算机硬件技术基础_万晓冬_习题
- 一起谈.NET技术,ASP.NET 请求处理流程
- 机器学习训练营_如何不运行学习代码训练营
- centos关闭邮件提醒
- mysql 变量被引号括住_【已解决】mysql中操作表的字段名时是否一定要用反引号括起来...
- 95-130-346-源码-source-kafka相关-KafkaConsumerThread
- 卷积神经网络的前世今生
- 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第3节 线程同步机制_8_解决线程安全问题_Lock锁...
- 在Visio里加上、下标方法
- linux下ntp服务配置
- 免费开源网站系统html,全CMS开源系统
- Deep Gait Recognition: A Survey 阅读笔记
- php计数器归零,php计数器lt;?/*-一个简单的计数器*/functio 爱问知识人
- Welcome Here