专业的编程技术博客社区

网站首页 > 博客文章 正文

服务器对网络传输协议(json和protobuf)权威对比(java)

baijin 2024-08-27 11:08:43 博客文章 4 ℃ 0 评论

在多年工作中,游戏的前端、后端的消息传输传输协议中,最常见的是json和probobuf,作为服务器人员,在打架整体服务器架构时候,一定要知道,自己项目适合于选择哪种协议,我们今天就用具体数据来说明他们之间的优缺点。

包体长度来对比:

proto文件

message data{
 required string title = 1 ; //App名字
 required string author = 2; //作者
}
message data1{
 repeated ListData data=1;
 message ListData{
 required string title = 1 ; //App名字
 required string author = 2; //作者
 }
}

java代码:

//json数据封装
JSONObject data=new JSONObject();
data.put("title","今日头条");
data.put("author","北京字节跳动科技有限公司");
System.out.println("json 包体长度:"+data.toString().getBytes().length);
System.out.println("**********************分割线******************************");
//protobuf数据封装
GameMessage.data.Builder data1=GameMessage.data.newBuilder();
data1.setTitle("今日头条");
data1.setAuthor("北京字节跳动科技有限公司");
System.out.println("proto 包体长度:"+data1.build().toByteArray().length);

打印结果:

json 包体长度:72
**********************分割线******************************
proto 包体长度:52

为了公平性,json和protobuf封装的消息我们都是打印了二进制流的长度,从上面的打印结果我们可以看出protobuf协议比json协议少28%的io量。意味着可以节约用户流量和服务器socket缓存内存使用量。

执行效率对比

java代码:

int length=100000;
//json数据封装
long jsonEncoderStartTime= System.currentTimeMillis(); //json开始封装协议的开始时间
JSONArray data=new JSONArray();
for (int i=0;i<length;i++) {
 JSONObject data1=new JSONObject();
 data1.put("title", "今日头条");
 data1.put("author", "北京字节跳动科技有限公司");
 data.put(data1);
}
byte[] jsonBody=data.toString().getBytes();
long jsonEncoderEndTime=System.currentTimeMillis(); //封装结束时间
long jsonEncoderTime=jsonEncoderEndTime-jsonEncoderStartTime; //封装耗时
System.out.println("json封装数据时间:"+jsonEncoderTime+"ms");
System.out.println("json长度:"+jsonBody.length);
System.out.print("\n");
long jsonDecStartTime=System.currentTimeMillis(); //解析开始
JSONArray readJsonData=new JSONArray(data.toString());
for (int i=0;i<readJsonData.length();i++){
 JSONObject readOne=readJsonData.getJSONObject(i);
 String title=readOne.getString("title");
 String author=readOne.getString("author");
}
long jsonDecEndTime=System.currentTimeMillis(); //解析开始
long jsonDecTime=jsonDecEndTime-jsonDecStartTime; //解析耗时
System.out.println("json解析数据时间:"+jsonDecTime+"ms");
System.out.println("\n**********************分割线******************************\n");
//protobuf数据封装
long protoEncoderStartTime= System.currentTimeMillis(); //json开始封装协议的开始时间
GameMessage.data1.Builder data1=GameMessage.data1.newBuilder();
for (int i=0;i<length;i++) {
 GameMessage.data1.ListData.Builder dataOne=GameMessage.data1.ListData.newBuilder();
 dataOne.setTitle("今日头条");
 dataOne.setAuthor("北京字节跳动科技有限公司");
 data1.addData(dataOne);
}
byte[] protoBody=data1.build().toByteArray();
long protoEncoderEndTime=System.currentTimeMillis(); //封装结束时间
long protoEncoderTime=protoEncoderEndTime-protoEncoderStartTime;
System.out.println("proto封装数据时间:"+protoEncoderTime+"ms");
System.out.println("proto包体长度:"+protoBody.length);
System.out.print("\n");
long protoDecStartTime=System.currentTimeMillis(); //解析开始
try {
 GameMessage.data1 proReaddate = GameMessage.data1.parseFrom(protoBody);
 for (int i=0;i<proReaddate.getDataCount();i++){
 GameMessage.data1.ListData dataone=proReaddate.getData(i);
 String title=dataone.getTitle();
 String author=dataone.getAuthor();
 }
}catch (InvalidProtocolBufferException i){
}
long ptotoDecEndTime=System.currentTimeMillis(); //解析开始
long protoDecTime=ptotoDecEndTime-protoDecStartTime; //解析耗时
System.out.println("proto解析数据时间:"+protoDecTime+"ms");

打印结果:

json封装数据时间:348ms
json长度:7300001
json解析数据时间:489ms
**********************分割线******************************
proto封装数据时间:143ms
proto包体长度:5400000
proto解析数据时间:374ms

从打印结果来看,在封装和解析方面,protobuf都有一定优势。

从测试结果来看,无论是socket内存,带宽,cpu性能方面,protobuf协议是比json协议有明显的优势,所有在一些要求比较高的项目时候最好使用protobuf协议传递,比如游戏服务器(简单h5小游戏排除哈)、电商数据服务器等。这里并不是说json不好,json也有自己优势,那就是相对于protobuf来说,使用简单,更多编程语言支持(包括很多前端脚本语言),而proto官方支持java,c++等,所以在通用性方面json比protobuf更好。

最后感谢json和protobuf ,还要感谢我的那几十个粉丝支持。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表