grpc初体验

为什么使用grpc?

grpc可以实现远程调用,比如实现一个go程序远程调用python程序。这不是闲着蛋疼吗?直接全部用go或者全部用python来写不用吗?确实如此,但是假如在这样的一个场景中,我们的项目有多个不同的功能,根据功能的不同拆分成了几个微服务,不同的功能完全分离开来,这样的话大大降低了代码的耦合度。

grpc官网链接

什么是protobuf协议?

grpc初体验_第1张图片

grpc使用步骤

下载
  1. 到github下载protoc用于编译proto文件 ==> 下载链接

  2. 然后在将下载完毕后的bin目录配置到环境变量中

3.安装需要的包:

go install google.golang.org/protobuf/cmd/[email protected]
go install google.golang.org/grpc/cmd/[email protected]

这里有个坑:安装的时候需要将go env中的GOOS设置为windows(使用go env -w GOOS=windows),否则GOPATH/bin下不会有如下的两个.exe文件
在这里插入图片描述

编写proto文件
syntax = "proto3";

//踩坑:这里的包名一定要和服务端的包名一致
package test

//.表示生成go文件的存放位置 proto表示生成的go文件所属的包,可以任意
option go_package = ".;proto";
// 定义一个服务
service Greeter {
  // 定义一个方法,接受HelloRequest消息并返回HelloReply消息
  rpc SayHello (HelloRequest) returns (HelloReply) {}

  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

根据编写的proto文件使用命令生成两个go文件用于后续的操作

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello.proto

go_out:.pb指定输出文件路径
go_opt:.pb指定参数,比如--go_opt=paths=source_relative就是表明生成文件输出使用相对路径。

另一个同理用于指定_grpc.pb的

hello.proto指定生成的文件名

生成的两个文件:
grpc初体验_第2张图片

这两个文件是proto自动生成的go语言代码,接下来我们只需要基于生成的这两个文件进行编写即可。

我的目录结构
grpc初体验_第3张图片

编写一个go服务

服务端

package main

import (
	"context"
	"google.golang.org/grpc"
	"net"
	"test/proto"
)

type server struct {
	/*
		踩坑:服务定义的方法实际由UnimplementedGreeterServer实现
		而原来的GreeterServer中新增了一个mustEmbedUnimplementedGreeterServer,这是不允许导出的私有变量
	*/
	*proto.UnimplementedGreeterServer
}

func (s *server) SayHelloAgain(ctx context.Context, in *proto.HelloRequest) (*proto.HelloReply, error) {
	return &proto.HelloReply{Message: "Hello again " + in.GetName()}, nil
}

func (s *server) SayHello(ctx context.Context, in *proto.HelloRequest) (*proto.HelloReply, error) {
	return &proto.HelloReply{Message: "Hello  " + in.GetName()}, nil
}

func main() {

	g := grpc.NewServer()
	proto.RegisterGreeterServer(g, &server{})
	listen, err := net.Listen("tcp", ":8002")
	if err != nil {
		panic("failed to listen:" + err.Error())
	}
	err = g.Serve(listen)
	if err != nil {
		panic("failed to start grpc:" + err.Error())
	}
}

客户端

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"test/proto"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:8002", grpc.WithInsecure())
	if err != nil {
		panic("conn fail" + err.Error())
	}
	c := proto.NewGreeterClient(conn)
	r, err := c.SayHello(context.Background(), &proto.HelloRequest{Name: "小番茄"})
	if err != nil {
		panic(err)
	}
	fmt.Println(r.Message)
}

在这里插入图片描述

如果要调用其它服务就改一下端口号就行了。

报错信息:
1.
在这里插入图片描述
解决:
修改包名:
https://github.com/techschool/pcbook-go/issues/3

2.找不到protoc命令
需要添加go/binGOPATH中。

你可能感兴趣的:(java,linux,开发语言)