找回密码
 立即注册
查看: 322|回复: 0

Android 性能优化10 --- 网络优化02(probuffer编码)

[复制链接]
发表于 2022-4-10 08:55 | 显示全部楼层 |阅读模式
一. TCP三次握手与四次挥手


image.png

二. HTTP1.0

1.请求行


{请求方法} + {URL字段} + {HTTP协议版本} 们用空格分隔。
例如,GET /index.html HTTP/1.1。
HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
2.请求头部


由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
User-Agent:产生请求的浏览器类型。
Accept:客户端可识别的内容类型列表。
Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。
请求头说明Host接受请求的服务器地址,可以是IP:端口号,也可以是域名User-Agent发送请求的应用程序名称Connection指定与连接相关的属性,如Connection:Keep-AliveAccept-Charset通知服务端可以发送的编码格式Accept-Encoding通知服务端可以发送的数据压缩格式Accept-Language通知服务端可以发送的语言
3.请求数据


请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length
三. HTTP1.1

HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。 主要区别主要体现在:
1.缓存处理


在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
2.带宽优化及网络连接的使用


HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
3.长连接


HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启*Connection: keep-alive*,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
四. HTTP2.0

超文本传输协议第二版,2015年2月17日被批准。
与HTTP1.1区别:
1.采用二进制格式而非文本格式。


比起超文本协议,二进制协议解析起来更加高效,更紧凑,更重要的时错误更少。
二进制分帧:所有HTTP 2.0通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。每个数据流以消息的形式发送。而消息由一或多个帧组成,而这些帧可以乱序发送,然后再根据每个帧首部流标识符重新组装。
2.多路复用


HTTP1.x一个连接只能提交一个请求,效率比较高,但是多了就会变慢。
多路复用能很好的解决此问题。能同时处理多个消息的请求和响应。
3.报头压缩


多个请求,多个头部。HTTP2.0可以压缩头部,节省开销。
第一次需要传完整的请求头部,后面只要穿与第一次不一样的头部消息就ok
4.服务器推送


HTTP2.0让服务器可以将响应主动推送到客户端缓存中。
五. HTTP3.0

由于TCP和UDP两者在运输层存在一定差异,TCP的传递效率与UDP相比有天然劣势,于是Google基于UDP开发出了新的协议QUIC(Quick UDP Internet Connections),希望取代TCP提高传输效率,后经过协商将QUIC协议更名为HTTP/3。
谷歌决定在UDP基础上改造一个具备TCP协议优点的新协议也就顺理成章了,这个新协议就是QUIC协议。
六. Protobuffer存储原理

可变长编码。Protobuf 序列化后所生成的二进制消息非常紧凑,这得益于 Protobuf 采用的非常巧妙的 Encoding 方法。考察消息结构之前,让我首先要介绍一个叫做 Varint 的术语。
Varint 是一种紧凑的表示数字的方法。它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数。这能减少用来表示数字的字节数。
比如对于 int32 类型的数字,一般需要 4 个 byte 来表示。但是采用 Varint,对于很小的 int32 类型的数字,则可以用 1 个 byte 来表示。当然凡事都有好的也有不好的一面,采用 Varint 表示法, 大的数字则需要 5 个 byte 来表示。从统计的角度来说,一般不会所有的消息中的数字都是大数,因此大多数情况下,采用 Varint 后,可以用更少的字节数来表示数字信息。

优点:
1.性能方面


a.体积小
b.序列化速度快
c.传输速度快
2.使用方面


a.使用简单,proto编译器自动进行序列化和反序列化
b.维护成本低,多平台仅需维护一套协议文件(.proto)
c.向后兼容性好,不必破坏旧的数据格式,就可以对旧的数据格式进行更小。
d.加密性好,http抓包只能看到字节,不能看到真实数据。
3.使用范围方面。


a.跨平台
b.跨语言
c.可扩展性
缺点:
1.功能方面


不适用基于文本的标记文档建模。
2.其它方面


通用性差,如果需要与外部项目交互,建议不要使用。
自解释性差,以二进制流数据进行存储,需要通过proto文件才能看到。
总结:
protobuffer比xml,json更小更快,使用简单,维护简单,但就是行业通用性差。
七.例程

#Persion.protosyntax ="proto3";option java_package="com.maniu.protobufferdemo";option java_outer_classname="Person";import "Adress.proto";message _Person{    string name=1;    int32 id=2;    string eamil=3;  bool isCheck=4;  enum _PhoneType{    MOBILE=0;    HOME=1;    WORK=2;  }  message  _PhoneNumber{    string number=1;    _PhoneType type=2;  }    string card=5;    repeated _PhoneNumber  phone=6;    _Adress adress=7;}public class MainActivity extends AppCompatActivity {    private static final String TAG = "david";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);//        序列化  本身已经是序列化        Person._Person._PhoneNumber.Builder phoneNumberBuld = Person._Person._PhoneNumber.                newBuilder().setNumber("110");        Person._Person.Builder personBuild=Person._Person.newBuilder().setCard("红色的汽车")                .setEamil("105191735@qq.com").setIsCheck(true).addPhone(phoneNumberBuld).setName("david");        Person._Person person = personBuild.build();        Log.i("david", " name  " + person.toString());//        反序列化  反序列化过程        byte[] bytes =    person.toByteArray();//        反序列化        try {            Person._Person  person1 =Person._Person.parseFrom(bytes);            Log.i("david", " name  " + person1.toString());            Log.i(TAG, "onCreate4: "+person1.getCard());        } catch (InvalidProtocolBufferException e) {            e.printStackTrace();        }     }}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-5-8 04:10 , Processed in 0.135327 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表