go之gRPC入门

gRPC 是一个高性能、开源和通用的 RPC 框架,基于HTTP2.0实现,具体原理及其他不再多说,百度/google有很多文章,这里主要分享一下如何搭建grpc环境以及如何用插件自动生成*.pb.go代码(以下分享均基于CentOs7)

下文中如果echo $GOPATH为空,则请用绝对路径代替GOPATH

一、gRPC开发环境搭建

1、安装golang:

        yum install -y golang(安装成功后输入go version可以看到对应版本号)

2、创建工程目录:

        mkdir -p $GOPATH/src/learn/vendor/github.com/golang

        mkdir -p $GOPATH/src/learn/vendor/golang.org/x

        mkdir -p $GOPATH/src/learn/vendor/google.golang.org

3、从git上拉取项目依赖库:

        由于git上这些仓库都被墙了,拉的很慢或者经常失败,在gitee上将相关仓库同步了一份,方便开发学习                                                                    

git与gitee仓库对照表
git仓库地址 gitee仓库地址 存放文件夹地址
https://github.com/grpc/grpc-go.git  https://gitee.com/it-monkey/grpc-go.git vendor/google.golang.org/grpc(需要将grpc-go重命名为grpc)
https://github.com/google/go-genproto.git  https://gitee.com/it-monkey/go-genproto.git  vendor/google.golang.org/genproto(需要将go-genproto重命名为genproto)
https://github.com/golang/protobuf https://gitee.com/it-monkey/protobuf.git vendor/github.com/golang/protobuf
https://github.com/protocolbuffers/protobuf-go.git https://gitee.com/it-monkey/protobuf-go.git vendor/google.golang.org/protobuf(需要将protobuf-go重命名为protobuf)
https://github.com/golang/net.git https://gitee.com/it-monkey/net.git github.com/golang/net
https://github.com/golang/sys.git https://gitee.com/it-monkey/sys.git  github.com/golang/sys
https://github.com/golang/text.git https://gitee.com/it-monkey/text.git github.com/golang/text

        下面是我的目录树结构

        |-- github.com
        |   `-- golang
        |       `-- protobuf            //grpc的依赖库
        |-- golang.org
        |   `-- x                            //grpc的依赖库
        |       |-- net
        |       |-- sys
        |       `-- text
        `-- google.golang.org
            |-- genproto              //
protoc-gen-go-grpc的源码
            |-- grpc                     //grpc源码
            `-- protobuf              //
protoc-gen-go的源码

4、gRPC Demo

其实刚才拉的仓库里已经有了广泛的demo,就在vendor/google.golang.org/grpc/examples/helloworld,将vendor/google.golang.org/grpc/examples/helloworld拷贝出来测试

拷贝helloworld Demo : cp  -r  $GOPATH/src/learn/vendor/google.golang.org/grpc/examples/helloworld  $GOPATH/src/learn/

进入server端编译&运行:     cd $GOPATH/src/learn/helloworld/greeter_server

                                              go build main.go

                                               ./main

再开一个窗口编译运行client:   cd $GOPATH/src/learn/helloworld/greeter_client

                                                 go build main.go

                                                 ./main

 


protoc + protoc-gen-go + protoc-gen-go-grpc

        下面是介绍编译proto文件&自动生成*.pb.go的工具protoc + protoc-gen-go-grpc  (老版本用的是protoc-gen-go,我试过,最新的grpc只用老版本生成的.pb.go少很多东西,无法使用,网上查了一下,说是现在官方在工具这一块变动较大)

1、先下载protoc

https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/protoc-3.14.0-linux-x86_64.zip

下载之后解压,将其中的bin目录下的protoc文件放到$GOPATH/bin目录下

再给与可执行权限chmod a+x protoc

将$GOPATH/bin加入PATH: export PATH=$PATH:$GOPATH/bin

2、安装protoc-gen-go

go install $GOPATH/src/learn/vendor/google.golang.org/protobuf/cmd/protoc-gen-go

3、安装protoc-gen-go-grpc

        其实上面我们已经将protoc-gen-go-grpc的源码下载下来了(vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc),现在只需要编译安装到$GOPATH/bin下即可

        运行如下命令即可安装

        go install $GOPATH/src/learn/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc

要确保$GOPATH/bin下有如下3个文件

接下来简单写一个proto文件

syntax = "proto3";
package calc;

message CalcRequest{
    int32 a = 1;
    int32 b = 2;
}

message CalcReply{
    int32 ans = 1;
}

service Calc{
    rpc Add(CalcRequest) returns (CalcReply){}
}

很简单,里面只有一个Add方法,内容就不多介绍了,下面用protoc-gen-go-grpc生成一下试试

go之gRPC入门_第1张图片

能生成calc_grpc.pb.go以及calc.pb.go即为成功


下面再顺带把自己写的测试的server以及client贴出来(参照官方的helloworld写的)

先贴一下的的工程目录

|-- calc
|   |--- calc_grpc.pb.go
|   |--- calc.pb.go
|   `--- calc.proto
|-- calcClient
|   `--- main.go
`-- calcServer
    `--- main.go

server端代码

package main

import (
    "learn/gRpcTest/calc"
    "context"
    "google.golang.org/grpc"
    "log"
    "net"
)

const (
    port = ":10024"
)

type server struct{
    calc.UnimplementedCalcServer
}

func main(){
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    calc.RegisterCalcServer(s, &server{})
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

func (s *server)Add(ctx context.Context, in *calc.CalcRequest)(*calc.CalcReply, error){
    log.Printf("server Add called, param1:%d, param2:%d", in.A, in.B)
    return &calc.CalcReply{
        Ans: in.A + in.B,
    }, nil
}

func (s *server)mustEmbedUnimplementedCalcServer() {}

client端代码

package main

import (
    "learn/gRpcTest/calc"
    "context"
    "google.golang.org/grpc"
    "log"
    "time"
)

const(
    address     = "localhost:10024"
)

func main(){
    conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    client := calc.NewCalcClient(conn)
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    ans, err := client.Add(ctx, &calc.CalcRequest{
        A: 10,
        B: 20,
    })
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("10+20 = %d", ans.GetAns())
}

大家可以运行一下试试

 

你可能感兴趣的:(go)