gRPC 网关
gRPC 网关
本指南有助于将 grpc 网关与 go-micro 服务结合使用.
grpc-gateway 是 protoc 的插件. 它读取 gRPC 的服务定义, 并生成将 RESTful JSON API 转换为 gRPC 的反向代理服务器.
我们可以使用 go-grpc 编写后端服务. Go-GRPC 是围绕 go-micro 和用于客户端和服务器的 grpc 插件的简单包装. 当调用 grpc.NewService 时, 它将返回一个 micro.Service.
代码
可以在这里找到示例代码 examples/grpc.
前提
这是一些先决条件
安装protobuf
mkdir tmp
cd tmp
git clone https://github.com/google/protobuf
cd protobuf
./autogen.sh
./configure
make
make check
sudo make install
安装插件
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/micro/protobuf/protoc-gen-go
Greeter 服务
在这个例子中, 我们使用 go-grpc 创建了一个 Greeter 的微服务. 这项服务非常简单.
原型如下:
syntax = "proto3";
package go.micro.srv.greeter;
service Say {
    rpc Hello(Request) returns (Response) {}
}
message Request {
    string name = 1;
}
message Response {
    string msg = 1;
}
服务如下:
package main
import (
    "log"
    "time"
    hello "github.com/micro/examples/greeter/srv/proto/hello"
    "github.com/micro/go-grpc"
    "github.com/micro/go-micro"
    "golang.org/x/net/context"
)
type Say struct{}
func (s *Say) Hello(ctx context.Context, req *hello.Request, rsp *hello.Response) error {
    log.Print("Received Say.Hello request")
    rsp.Msg = "Hello " + req.Name
    return nil
}
func main() {
    service := grpc.NewService(
        micro.Name("go.micro.srv.greeter"),
        micro.RegisterTTL(time.Second*30),
        micro.RegisterInterval(time.Second*10),
    )
    // optionally setup command line usage
    service.Init()
    // Register Handlers
    hello.RegisterSayHandler(service.Server(), new(Say))
    // Run server
    if err := service.Run(); err != nil {
        log.Fatal(err)
    }
}
gRPC 网关
grpc 网关使用与服务相同的协议, 并增加一个 http 选项
syntax = "proto3";
package greeter;
import "google/api/annotations.proto";
service Say {
    rpc Hello(Request) returns (Response) {
        option (google.api.http) = {
            post: "/greeter/hello"
            body: "*"
        };
    }
}
message Request {
    string name = 1;
}
message Response {
    string msg = 1;
}
proto 使用以下命令生成 grpc stub 和反向代理
protoc -I/usr/local/include -I.
  -I$GOPATH/src
  -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis
  --go_out=plugins=grpc:.
  path/to/your_service.proto
protoc -I/usr/local/include -I.
  -I$GOPATH/src
  -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis
  --grpc-gateway_out=logtostderr=true:.
  path/to/your_service.proto
我们使用下面的代码创建了 greeter 服务的示例 api. 将写入类似的代码来注册其他端点. 需要注意的是, 网关需要 greeter 服务的端点地址.
package main
import (
    "flag"
    "net/http"
    "github.com/golang/glog"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "golang.org/x/net/context"
    "google.golang.org/grpc"
    hello "github.com/micro/examples/grpc/gateway/proto/hello"
)
var (
    // the go.micro.srv.greeter address
    endpoint = flag.String("endpoint", "localhost:9090", "go.micro.srv.greeter address")
)
func run() error {
    ctx := context.Background()
    ctx, cancel := context.WithCancel(ctx)
    defer cancel()
    mux := runtime.NewServeMux()
    opts := []grpc.DialOption{grpc.WithInsecure()}
    err := hello.RegisterSayHandlerFromEndpoint(ctx, mux, *endpoint, opts)
    if err != nil {
        return err
    }
    return http.ListenAndServe(":8080", mux)
}
func main() {
    flag.Parse()
    defer glog.Flush()
    if err := run(); err != nil {
        glog.Fatal(err)
    }
}
运行示例
运行 greeter 服务. 指定服务发现为 mdns.
go run examples/grpc/greeter/srv/main.go --registry=mdns --server_address=localhost:9090
运行网关. 它将默认为端点 localhost:9090 的 greeter 服务.
go run examples/grpc/gateway/main.go
使用 curl 在 (localhost:8080) 网关上发起请求.
curl -d '{"name": "john"}' http://localhost:8080/greeter/hello
限制
grpc 网关的例子需要提供服务地址, 而我们自己的 micro api 使用服务发现, 动态路由和负载均衡. 这使得 grpc 网关的集成性稍差一些.
可参阅 github.com/micro/micro 了解更多
          
Go Micro 中文文档
            
            
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: