go grpc压缩_了解gRPC一篇就够了

本文详细介绍了gRPC,一个高性能的RPC框架,强调其在移动设备和HTTP/2上的应用。文章涵盖了gRPC的基本使用,包括协议文件的创建、stub生成以及Proto编码原理。重点讨论了Varint编码,解释了如何解码96 01。此外,还概述了gRPC的RPC原理,客户端和服务端的交互流程,并探讨了其负载均衡、鉴权认证等特性。文章还涉及了gRPC生态,包括grpc-gateway的使用,并比较了gRPC与Thrift的差异,强调gRPC在移动领域的专注和使用HTTP/2的优势。
摘要由CSDN通过智能技术生成

9ef6656a3cbda7eab92bac8f2c0ac44a.png

713e304e2c0c487e14c7c12ec1575945.png

6ef7e3c12797071245f41c3e57c3a4ee.png

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 的方式

9f24e8f04c9bffe9a85f14083f9ccea4.png

ps:

大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。

小端字节序:低位字节在前,高位字节在后,即以0x1122形式储存。

https://www.cnblogs.com/gremount/p/8830707.html

0bbdbb053d7c70a06dcce8091d304819.png

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定义

3edc945117fd1dc7ed1fc40a338c5f2f.png

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原理

d5fb82d5b89b6af11e4ea27e5a39d03e.png

grpc原理

9cdc7837ded82318c2f07d98f40ff30d.png

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值