前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >gRPC介绍

gRPC介绍

作者头像
阿兵云原生
发布2023-02-16 10:37:48
5180
发布2023-02-16 10:37:48
举报
文章被收录于专栏:golang云原生new
  • gRPC介绍

  • gRPC是什么?

  • RPC和RESTful的区别是什么?
    • gRPC的特性是什么?
    • gRPC的数据交互模式是怎么样的?
  • 数据的序列化方式 - protobuf
    • 简单介绍protobuf的结构定义包含的3个关键字
  • 一个DEMO

gRPC

gRPC介绍

gRPC是什么?

RPC和RESTful的区别是什么?

RPC的消息传输可以是TCP,可以是UDP,也可以是HTTP,当RPC消息传输是HTTP时,它的结构与RESTful的架构类似

RPC和RESTful有什么不同呢:

  • 操作的对象不一样的,RESTful会更加灵活

RPC操作的是方法对象, RESTful操作的是资源

RPC的客户端和服务器端是紧耦合的,客户端需要知道服务端的函数名字,参数类型、顺序等,才能远程过程调用。

RESTful基于 http的语义操作资源,参数的顺序一般没有关系

  • RCP更适合定制化 RESTful执行的是对资源的操作,主要都是CURD(增删改查)的操作,若需要实现一个特定的功能,如计算一个班级的平均分,这个时候使用RPC定义服务器的方法(如:Stu.CalAvg)供客户端调用则显得更有意义

gRPC的特性是什么?

  • gRPC是可以跨语言开发的

在gRPC客户端可以直接调用不同服务器上的远程程序,使用姿势看起来就像调用本地过程调用一样,很容易去构建分布式应用和服务。客户端和服务端可以分别使用gRPC支持的不同语言实现。

  • 基于HTTP2标准设计,比其他框架更优的地方有
    • 支持长连接,双向流、头部压缩、多复用请求
    • 节省带宽降低TCP链接次数节省CPU使用延长电池寿命
    • 提高了云端服务和Web应用的性能
    • 客户端和服务端交互透明
    • gRPC默认使用protobuf来对数据序列化

gRPC的数据交互模式是怎么样的?

请求应答式

客户端发出一次请求,可以从服务端读取一系列的消息

客户端写一系列消息给到服务端,等待服务端应答

客户端和服务端都可以通过读写数据流来发送一系列消息

数据的序列化方式 - protobuf

protobuf 是一个对数据序列化的方式,类似的有JSON,XML等

简单介绍protobuf的结构定义包含的3个关键字

  • 以.proto做为后缀,除结构定义外的语句以分号结尾
  • 结构定义可以包含:message、service、enum,三个关键字
  • rpc方法定义结尾的分号可有可无

Message命名采用驼峰命名方式,字段是小写加下划线

代码语言:javascript
复制
 message ServerRequest {
      required string my_name = 1;
  }

Enums类型名采用驼峰命名方式,字段命名采用大写字母加下划线

代码语言:javascript
复制
 enum MyNum {
      VALUE1 = 1;
      VALUE2 = 2;
  }

Service与rpc方法名统一采用驼峰式命名

代码语言:javascript
复制
service Love {
  // 定义Confession方法
  rpc MyConfession(Request) returns (Response) {}
}

关于prtobuf的安装可以看看之前写的一个安装步骤《5个步骤搞定PROTOBUF的安装

在proto文件中使用package关键字声明包名,默认转换成go中的包名与此一致,可以自定义包名,修改go_package即可:

test.proto

代码语言:javascript
复制
syntax = "proto3"; // proto版本

package pb; // 指定包名,默认go中包名也是这个

// 定义Love服务
service Love {
  // 定义Confession方法
  rpc Confession(Request) returns (Response) {}
}

// 请求
message Request {
  string name = 1;
}

// 响应
message Response {
  string result = 1;
}

安装好protoc环境之后,进入到proto文件的目录下,(例如打开window git)执行如下命令,将proto文件编译成pb.go文件

代码语言:javascript
复制
 protoc --go_out=plugins=grpc:. test.proto

转换结果:

代码语言:javascript
复制
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0
// 	protoc        v3.13.0
// source: test.proto

package test

import (
	context "context"
	proto "github.com/golang/protobuf/proto"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type Request struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}


type Response struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Result string `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"`
}

// LoveServer is the server API for Love service.
type LoveServer interface {
	Confession(context.Context, *Request) (*Response, error)
}

一个DEMO

目录结构为:

代码语言:javascript
复制

-------------------------------
| mygrpc
| ---------pb
| -------------test.proto
| ---------client.go
| ---------srv.go
-------------------------------

client.go

代码语言:javascript
复制
package main

import (
    "context"
    "log"

    "mygrpc.com/pb"

    "google.golang.org/grpc"
)

func main() {
    // 连接grpc服务
    conn, err := grpc.Dial(":8888", grpc.WithInsecure())
    if err != nil {
        log.Fatal(err)
    }
    // 很关键
    defer conn.Close()

    // 初始化客户端
    c := pb.NewLoveClient(conn)

    // 发起请求
    response, err := c.Confession(context.Background(), &pb.Request{Name: "小魔童哪吒"})
    if err != nil {
        log.Fatal(err)
    }

    log.Println(response.Result)
}

server.go

代码语言:javascript
复制
package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    "mygrpc.com/pb"
)

// 定义Love服务
type Love struct {
}

// 实现Love服务接口
func (l *Love) Confession(ctx context.Context, request *pb.Request) (*pb.Response, error) {
    resp := &pb.Response{}
    resp.Result = "your name is " + request.Name
    return resp, nil
}

func main() {
    // 监听8888端口
    listen, err := net.Listen("tcp", ":8888")
    if err != nil {
        log.Fatal(err)
    }

    // 实例化grpc server
    s := grpc.NewServer()

    // 注册Love服务
    pb.RegisterLoveServer(s, new(Love))

    log.Println("Listen on 127.0.0.1:8888...")
    s.Serve(listen)
}

下一次介绍关于gRPC的认证

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是小魔童哪吒,欢迎点赞关注收藏,下次见~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 阿兵云原生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • gRPC
    • gRPC介绍
      • gRPC是什么?
    • RPC和RESTful的区别是什么?
      • gRPC的特性是什么?
      • gRPC的数据交互模式是怎么样的?
    • 数据的序列化方式 - protobuf
      • 简单介绍protobuf的结构定义包含的3个关键字
    • 一个DEMO
    相关产品与服务
    文件存储
    文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档