gRPC是什么?
一个高性能,开源,通用的RPC框架,将移动和HTTP/2放在首位(跟传统rpc定位不同),支持负载均衡、健康检查、身份验证。移动设备和浏览器可以直连,google开源。
前置知识:gRPC的数据序列化协议Protocol Buffers
简单使用:
安装
brew install protobuf
#go版本的protubuf插件
go get -v -u github.com/golang/protobuf/protoc-gen-go
协议简介
message SearchResponse {
/* 注释 */
message Result {
string url = 1; //1为字段标号
singular string title = 2; //singular0个或一个字段内容
repeated string snippets = 3; //repeated任意重复内容
}
repeated Result results = 1; //结构体嵌套
}
service SearchService {
rpc Search (SearchRequest) returns (SearchResponse); //定义服务方法
}
使用简介:
1、创建message.proto
syntax = "proto3";
package tutorial;
import "google/protobuf/timestamp.proto";
message Person {
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4; //实际会生成数组
google.protobuf.Timestamp last_updated = 5;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person people = 1;
}
2、生成stub
protoc -I=./ --go_out=./ ./message.proto
3、加密与解密
package main
import (
"github.com/golang/protobuf/proto"
"github.com/e421083458/test_grpc/proto_test/message"
"io/ioutil"
"log"
)
var (
fileName string = "message.buffer"
)
func main() {
peoples:=[]*message.Person{
&message.Person{
Name:"test",
},
}
book := &message.AddressBook{
People:peoples,
}
// Write the new address book back to disk.
out, err := proto.Marshal(book)
if err != nil {
log.Fatalln("Failed to encode address book:", err)
}
if err := ioutil.WriteFile(fileName, out, 0644); err != nil {
log.Fatalln("Failed to write address book:", err)
}
bts,err:=ioutil.ReadFile(fileName)
if err != nil {
log.Fatalln("Failed to read address book:", err)
}
newBook:=&message.AddressBook{
}
if err:=proto.Unmarshal(bts,newBook);err!=nil{
log.Fatalln("Failed to decode address book:", err)
}
log.Println(book)
log.Println(newBook)
}
proto encoding原理
查看加密文件
1、首先创建一个协议文件:
syntax = "proto3";
message Message {
int32 id = 1;
}
2、创建一个序列化程序
func main() {
m:=&message.Message{
Id:1,
}
out, err := proto.Marshal(m)
if err != nil {
log.Fatalln("Failed to encode address book:", err)
}
if err := ioutil.WriteFile("test.txt", out, 0644); err != nil {
log.Fatalln("Failed to write address book:", err)
}
}
3、写入文件后用二进制打开文件:
vim -b test.txt
:%!xxd
查看16进制:
0000000: 0896 01 ...
上面是啥意思?
要了解以上啥意思,首先要了解Varint
1、Varint 编码表示法
每个 byte 的最高位 bit 有特殊的含义,如果该位为 1,表示后续的 byte 也是该数字的一部分,如果该位为 0,则结束。其他的 7 个 bit 都用来表示数字。因此小于 128 的数字都可以用一个 byte 表示。大于 128 的数字,会用两个字节
例如整数1的表示,仅需一个字节:
0000 0001
例如300的表示,需要两个字节:
1010 1100 | 0000 0010
字节序采用 little-endian 的方式
ps:
大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。
小端字节序:低位字节在前,高位字节在后,即以0x1122形式储存。
https://www.cnblogs.com/gremount/p/8830707.html
2、key的定义:
(field_number << 3) | wire_type
0 000 1000 首位为标识位,后三位为wire_type:0
>>3
0 000 0001 数字标签为1
得出wire_type为0,右移3位得到,数字标签。
3、wire_type定义
4、解码96 01
96 01 = 1001 0110 0000 0001
→ 000 0001 ++ 001 0110 (drop the msb and reverse the groups of7 bits)
→ 10010110
→ 2 + 4 + 16 + 128 = 150
gRPC
rpc原理
grpc原理
1、客户端(gRPC Stub)调用 A 方法,发起 RPC 调用。
2、对请求信息使用 Protobuf 进行对象序列化压缩(IDL)。
3、服务端(gRPC Server)接收到请求后,解码请求体,进行业务逻辑处理并返回。
4、对响应结果使用 Protobuf 进行对象序列化压缩(IDL)。
5、客户端接受到服务端响应,解码请求体。回调被调用的 A 方法,唤醒正在等待响应(阻塞)的客户端调用并返回响应结果。
基本使用:
0、安装gRPC及依赖
安装gRPC,一定要在gopath里安装,因为需要安装执行文件
go get -v -u google.golang.org/grpc
1、 一元RPC普通用法
定义协议
syntax = "proto3";
packa