GRPC入门小demo

gRPC

 


gRPC介绍

 

  1. gRPC是google开发的高性能、跨语言、跨平台的rpc框架

  2. gRPC 基于 HTTP2标准设计,有了性能上的提升

    1. 二进制传输 - 相比文本更通用、性能更高

    2. 多路复用 - 同一ip一次连接可以发送多个请求

    3. 头部压缩 - 新的压缩算法&只发送差异的header

    4. 推送 - server可以响应多个消息

 

gRPC的使用

gRPC同其他RPC框架思想一样,先定义一个服务,指定可以远端调用的方法以及参数和返回类型、gRPC默认使用protocol buffer作为接口定义语言

然后服务端和客服端根据定义分别编写自己的代码.

service HelloService {

    rpc SayHello (HelloRequest) returns (HelloResponse);

}

message HelloRequest {

    required string greeting = 1;

}

message HelloResponse {

    required string reply = 1;

}

 

 

gRPC允许定义的四种服务

1. 单项 RPC

rpc SayHello(HelloRequest) returns (HelloResponse){}

 

2. 服务端流式 RPC

 
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}

 

3. 客户端流式 RPC

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}

 

4. 双向流式 RPC

 

rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){}

 

protocol buffer介绍

protobuf是google的成熟的开源的数据结构序列化机制、类似于xml和json等

  1. 语言无关、平台无关。即 ProtoBuf 支持 Java、Go、C++、Python 等多种语言,支持多个平台
  2. 高效 序列化后的数据非常小、适用于网络传输和持久化
  3. 扩展性、兼容性好,可以新增数据结构,而不影响和破坏原有的旧程序

 

protobuf数据结构

syntax = "proto3";

option go_package = "pb;go_pb"

message Person {

required string name = 1;

required int32 id = 2;

optional string email = 3;

enum PhoneType {

MOBILE = 0;

HOME = 1;

WORK = 2;

}

message PhoneNumber {

required string number = 1;

optional PhoneType type = 2 [default = HOME];

}

repeated PhoneNumber phone = 4;

}

Service PersonService {

rpc teach(Person) returns (Person);

}

//required:必传 optional 0-1次 repeated 0-n次

 

protobuf的高性能

  1.  ProtoBuf序列化后所生成的二进制消息非常紧凑
  2.  ProtoBuf封解包过程非常简单
price=150

xml: 约36byte

<some>

<key>price</key>

<value>150</value>

</some>

json:约11byte

{

"price": "150"

}

protobuf:约3byte

message test {

optional int32 price = 1;

}

[08 96 01]

 

 

一个基于protobuf的grpc简单例子

 

  1. 定义服务数据结构,使用代码生成器生成对应go语言代码
  2. 实现服务器代码
  3. 实现客服端代码

 

1. protocol buffer编译器安

brew install protobuf //代码生成器

brew install protoc-gen-go //go语言依赖

 

2. 定义服务(.proto文件)

syntax = "proto3";

option go_package = "pb;go_proto";

package go_proto;

service hello {

rpc getInfo (helloRequest) returns (helloResponse);

}

message helloRequest {

string uId = 1;

}

message helloResponse {

string uId = 1;

string userName = 2;

string email = 3;

}

 

 

3. 使用代码生成器生成go代码

protoc --go_out=plugins=grpc:. *.proto 

 

 

*.pb.go内容

用于序列化和获取我们请求和响应消息类型的 protocol buffer 代码

客户端调用定义的服务的方法的接口类型(或者 存根 )

服务器使用定义的服务的方法去实现的接口类型(或者 存根 )

 

 在服务的实现rpc方法

type testServer struct {

}

func (s *testServer) GetInfo(ctx context.Context,req *go_proto.HelloRequest) (*go_proto.HelloResponse, error) {

log.Printf("request success, uId : %s",req.UId)

return &go_proto.HelloResponse{

UId: req.UId,

UserName: "myName",

Email: "myName123@qq.com",

}, nil

}

const port = ":2333"

func main() {

server:= grpc.NewServer()

go_proto.RegisterHelloServer(server, &testServer{})

listen, err := net.Listen("tcp", port)

if err != nil {

log.Fatalf("failed to listen : %s", err)

}

_ = server.Serve(listen)

}

 

 在客户端调用rpc方法


const address = "localhost:2333"

func main() {

//建立连接

conn, err := grpc.Dial(address,grpc.WithInsecure())

if err != nil {

log.Fatalf("did not connect: %v", err)

}

defer conn.Close()

client := go_proto.NewHelloClient(conn)

response,err := client.GetInfo(context.TODO(), &go_proto.HelloRequest{UId: "12821"})

data,err := json.Marshal(response)

fmt.Print(string(data))

}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值