了解了解grpc
Posted johopig
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解了解grpc相关的知识,希望对你有一定的参考价值。
了解了解grpc
了解了解grpc
前言
http2
protocol buffer
grpc 的设计与实现
grpc使用优化
refer
前言
前一段时间因为练车所以没什么时间看文章做笔记,现在车练完了,刚好毕业设计后端的接口大部分都写完了,也刚好后端用的是微服务框架,rpc框架是用grpc,所以就写一篇文章,加深一下印象
使用场景
grpc是由谷歌开发的高性能、开源、通用的rpc框架。grpc的使用场景很多,最常用的是后端服务之间的调用,除此之外,还有移动端、grpc-web,之前实习的公司前后端交互全部都是通过niginx将请求转发到grpc服务端
grpc的组成部分
-
http2作为网络协议 -
ptotobuf作为高性能的数据包序列化协议 -
protoc grpc插件生成客户端、服务端易用的sdk
RTT
RTT ( round trip time ) 可以理解为请求一去一反消耗的时间开销。在无缓存的情况下,一个http请求会经过很多的RTT,例如
1、DNS的请求和应答为一个RTT
2、对http服务器进行tcp连接还需要三次握手的两个RTT
3、http跳https又要三次握手的RTT
4、TLS 的2次RTT
不过上面说到的无缓存和未优化的场景开销,正常都是会有一定缓存和优化的
http2
几个版本的比较
grpc基于http2,在此之前需要顺便提一下http的几个版本的发展。http 1.0、http 1.1、http 2.0
-
http 1.0
缺点
-
短连接 -
http 1.1
优点
相比于 1.0 增加了持久化连接、缓存、更多的header支持、accept-range
缺点
-
「Head-Of-Line」HOL队头阻塞(no pipelining)
http 1.1 的问题就在于队头阻塞,一个连接只能跑一个请求,在请求没返回数据之前,其他请求不能够占用这个连接。如果你进到页面之后有N个并发请求,那么就需要N个连接,但浏览器对连接数有限制(二级域名、一级域名都有限制)
就算不对conn进行控制,也依旧有几个问题,新的连接要3次握手,tls也要握手,之后还要「经历tcp拥塞控制下的慢启动」。这些连接启动后是否要一直保持?那么保持这些连接对比客户端和服务端都有一定的负担
Http2.0
-
definition
最小单位是frame,一个请求需要header frame、data frame两个帧。stream是http2抽象的流,每个stream都有id,通过id来区分并发过来的请求
-
二进制分帧层(压缩)
将header和data进行压缩
-
多路复用
http2最大的特点就是多路复用。这里的复用不是指传统类似epoll对tcp连接的服用,而是在「协议层的多路复用」,把一个个请求封装成stream流,这些流是可以并发交错请求的,这样就解决了http1.1的队头阻塞的问题
-
hpack 算法
-
客户端与服务端根据 RFC 7541 的附录A,维护一份共同的静态字典(Static Table),其中包含了常见头部名及常见头部名称与值的组合的代码;通过传递索引号节省Header头部空间 -
客户端和服务端根据先入先出的原则,维护一份可动态添加内容的共同动态字典(Dynamic Table); -
客户端和服务端根据 RFC 7541 的附录B,支持基于该静态哈夫曼码表的哈夫曼编码(Huffman Coding) -
Head-of-line Blocking 队头阻塞
虽然说http2解决了htpp1.1由于多个请求都需要顺序的从一个连接发出引发的HOL问题,「但其实http2.0还是会遇到另一种类型的HOL问题」(TCP协议的拥塞控制)
❝HTTP/2 runs over a TCP connection; and due to TCP's congestion control, one lost packet in the TCP stream makes all streams wait until that package is re-transmitted and received.
❞
而解决方法就是使用UDP,这就是HTTP/3协议的QUIC protocol所做的事情,这里就不讲了因为我也没去看过
protocol buffer
protobuf是什么?
「Protocol Buffers」是一种序列化数据结构的协议。对于透过管道(pipeline)或存储资料进行通信的程序开发上是很有用的。这个方法包含一个接口描述语言,描述一些数据结构,并提供程序工具根据这些描述产生代码,用于将这些数据结构产生或解析资料流
为什么选择protobuf?
-
json
浪费空间、丢失了数据类型、不安全、效率低
-
thrift
额,grpc、protobuf都是谷歌的,生态较好,thrift来自脸书....(还有个问题是thrift不是基于http2的,现在主流的proxy都要支持http2)
protobuf 类型
类型名称 | 值类型 | 举例 |
---|---|---|
enum | string | "BOOK_ON_SALE" |
map<K,V> | object | {"k": v, ...} |
Repeated V | array | [v, ...] |
bool | True, false | true,false |
string | string | "hello word" |
bytes | base64 string | "shadasohdosadopw" |
Int32,fixed32,uint32 | number | 1,-10,0 |
Int64,fixed64,uint64 | string | 1,-10 |
float,double | Number | 1.1,-10.9.0,NaN,Infinity |
Any | Object | Url,f |
Timestamp | string | 1972-01-01T10:00:20.021Z |
Duration | string | 1.000340012s |
Struct | object | {...} |
Wrapper types | Various types | |
FieldMask | string | |
ListValue | array | [foo,bar,...] |
Value | value | |
NullValue | null | |
Empty | Object | {} |
grpc 的设计与实现
grpc workflow
grpc request
grpc deep request
-
Header frame -
metadata in header -
Service/method in header -
Data frame -
protobuf
grpc的四种类型
-
unary
一去一回
-
Client streaming
客户端单边推送数据
-
Server streaming
服务端单边推送数据
-
Bidi streaming
双向推送流数据
Interceptor 拦截器
一般的微服务框架在使用rpc时基本都有相应的拦截器
Middleware (third party): unary、stream interceptor
client balancer 客户端负载均衡
-
Rate limiter 限流 -
circuit breaker 熔断 -
log wrapper 日志 -
auth wrapper 认证 -
try catch recovery
其他特性
-
metadata、keepalive、reflection -
grpc client -
withbalancer 负载均衡 -
withblock -
withinsecure -
waitforready -
... -
grpc server -
MaxConcurrentStreams -
IinitialWindowSize -
InitialConnWindowSize -
UnknownServiceHandler -
CustomCodec -
...
protoc的使用
protoc --go_out=plugins=grpc:. greeter.proto
grpc 微服务
grpc使用优化
打开多个连接时一定一定一定要使用连接池!!复用连接!
refer
-
https://community.akamai.com/customers/s/article/How-does-HTTP-2-solve-the-Head-of-Line-blocking-HOL-issue?language=en_US -
https://zh.wikipedia.org/wiki/HTTP/2 -
http://xiaorui.cc/archives/7054 -
https://zh.wikipedia.org/wiki/Protocol_Buffers
以上是关于了解了解grpc的主要内容,如果未能解决你的问题,请参考以下文章