go grpc
ddatsh
message.proto
syntax = "proto3";
package pb;
// The greeter service definition.
service Greeter {
// Sends a greeting
rpc SayHello (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;
}
protoc编译工具
https://github.com/google/protobuf 会跳 https://github.com/protocolbuffers/protobuf
--cpp_out=OUT_DIR Generate C++ header and source.
--csharp_out=OUT_DIR Generate C# source file.
--java_out=OUT_DIR Generate Java source file.
--javanano_out=OUT_DIR Generate Java Nano source file.
--js_out=OUT_DIR Generate JavaScript source.
--objc_out=OUT_DIR Generate Objective C header and source.
--php_out=OUT_DIR Generate PHP source file.
--python_out=OUT_DIR Generate Python source file.
--ruby_out=OUT_DIR Generate Ruby source file.
protoc能生成那么多语言的代码,但居然本身没有产生go的代码,需要调用如protoc-gen-go这样的插件!!!
set GOPROXY=https://goproxy.io
mkdir demo
cd demo
go mod init demo
rem protoc的 --go_out 插件
go get -u github.com/golang/protobuf/protoc-gen-go
go get -u google.golang.org/grpc
github.com/golang/protobuf/protoc-gen-go 会编译出 protoc-gen-go
要是先 google.golang.org/grpc,在其go mod也会把前者(github.com/golang/protobuf)一并给下载了,protoc-gen-go还是要自行编译下才出来
go mod 也不用 go get google.golang.org/grpc,在go build里也会自行下载
可选
//gogo
go get -u github.com/gogo/protobuf/protoc-gen-gogo
//gofast
go get -u github.com/gogo/protobuf/protoc-gen-gofast
即protoc-gen系列 3 个
- protoc-gen-go
- protoc-gen-gogo
- protoc-gen-gofast
go.mod
module demo
go 1.14
require (
github.com/golang/protobuf v1.3.5
google.golang.org/grpc v1.28.1
)
gRPC-go
grpc原是google内部项目,归属golang,放在google.golang.org下,后来对外开放迁移到github
https://github.com/grpc/grpc-go
梳理
-
protoc
https://github.com/google/protobuf 会跳 https://github.com/protocolbuffers/protobuf
之前在google内部时是 goprotobuf
go get -u code.google.com/p/goprotobuf/{proto,protoc-gen-go}
-
protoc-gen-go
github.com/golang/protobuf/protoc-gen-go
编译的可执行文件作前者 go序列化插件用
-
gRPC-go
https://github.com/grpc/grpc-go
源码引用或go get是 google.golang.org/grpc
protoc --go_out=. message.proto
protoc --go_out=plugins=grpc:. message.proto
第二个产生的则除了第一个的PB序列化和反序列化代码外,还增加服务器和客户端通讯、实现的公共库代码
github.com/gogo/protobuf
- protoc-gen-gogo
- protoc-gen-gofast
完全兼容google protobuf,主要extend了一些option
可以修饰field/enum/message/package(即对整个文件都有效)
protoc --gofast_out=plugins=grpc:. message.proto
code
server
package main
import (
"net"
"log"
"google.golang.org/grpc"
"demo/pb"
"context"
)
// server is used to implement helloworld.GreeterServer.
type server struct{}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
s.Serve(lis)
}
client
package main
import (
"google.golang.org/grpc"
"log"
"demo/pb"
"context"
)
func main() {
conn, err := grpc.Dial("localhost:50051",grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)
r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: "dd"})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Message)
}
gRPC HTTP协议转换
coreos的博客,转载了grpc官方博客gRPC with REST and Open APIs
etcd3改用grpc后为了兼容原来的api,同时要提供http/json方式的API
为满足这需求,要么开发两套API,要么实现一种转换机制,他们选择了后者
协议转换的网关grpc-gateway,接收客户端请求,然后决定直接转发给grpc服务还是转给http服务,当然,http服务也需要请求grpc服务获取响应,然后转为json响应给客户端