自家所当铺子之品类是运基于Restful的微服务架构,随着微服务之间的关系更频繁,就期待可以做成用rpc来开内部的简报,对外仍然用Restful。于是就悟出了google的grpc。

使grpc的优点很多,二进制的数码可加速传输速度,基于http2的多路复用可以减掉服务中间的连日次数,和函数一样的调用方式为中的提升了开效率。

而使用grpc也会见面临一个题目,我们的微服务对外一定是使提供Restful接口的,如果内部调用使用grpc,在少数情况下如同时提供一个效能的点滴套API接口,这样就算不光降低了开发效率,也长了调剂的复杂度。于是便想方有没有发出一个转换机制,让Restful和gprc可以并行转化。

每当网上来看一个缓解方案,https://github.com/grpc-ecosystem/grpc-gateway,简单的说就算是产生一个网关服务器负责转化及代办转发。

如下图:
json 1

安装

率先使安装ProtocolBuffers 3.0及以上版本。

mkdir tmp
cd tmp
git clone https://github.com/google/protobuf
cd protobuf
./autogen.sh
./configure
make
make check
sudo make install

然后下go get获取grpc-gateway。

go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
go get -u github.com/golang/protobuf/protoc-gen-go

这里最将编译生成的二进制文件的目录在$PATH中,可以把$GOPATH/bin放入$PATH中。

示例

本示例是基于自身之上平等首博客《google的grpc在glang中之运用》中的示范,如果发生必要请先了解及同样首博客。

以身作则代码获取地址:https://github.com/andyidea/go-example。

代码文件结构如下

└── src
    └── grpc-helloworld-gateway
        ├── gateway
        │   └── main.go
        ├── greeter_server
        │   └── main.go
        └── helloworld
            ├── helloworld.pb.go
            ├── helloworld.pb.gw.go
            └── helloworld.proto

我们还是事先看一下商谈文件。helloworld.proto有局部改观,引入了google官方的api相关的扩大,为grpc的http转换提供了支撑。

切切实实改动如下:

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

import "google/api/annotations.proto";

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {
        option (google.api.http) = {
        post: "/v1/example/echo"
        body: "*"
    };
  }
}

// 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文件于,新的公文增加了

import "google/api/annotations.proto";

option (google.api.http) = {
        post: "/v1/example/echo"
        body: "*"

此地多了针对http的恢弘配置。

接下来编译proto文件,生成对应之go文件

cd src/grpc-helloworld-gateway

protoc -I/usr/local/include -I. \
-I$GOPATH/src \
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--go_out=Mgoogle/api/annotations.proto=github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api,plugins=grpc:. \
helloworld/helloworld.proto 

这里特别成了helloworld/helloworld.pb.go文件。

helloworld.pb.go是server服务用的,下同样步我们得运用protoc生成gateway需要的go文件。

cd src/grpc-helloworld-gateway

protoc -I/usr/local/include -I. \
-I$GOPATH/src  -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--swagger_out=logtostderr=true:. \
helloworld/helloworld.proto

此特别成了helloworld/helloworld.pb.gw.go文件。这个文件就是gateway用来之商谈文本,用来做grpc和http的商议转换。

协和文本处理完毕,就需写gateway代码了。

gateway代码如下:

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"

    gw "grpc-helloworld-gateway/helloworld"
)

var (
    echoEndpoint = flag.String("echo_endpoint", "localhost:50051", "endpoint of YourService")
)

func run() error {
    ctx := context.Background()
    ctx, cancel := context.WithCancel(ctx)
    defer cancel()

    mux := runtime.NewServeMux()
    opts := []grpc.DialOption{grpc.WithInsecure()}
    err := gw.RegisterGreeterHandlerFromEndpoint(ctx, mux, *echoEndpoint, 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)
    }
}

首先echoEndpoint存储了需要连接的server信息,然后拿这些消息以及新建的server用gw.go中的RegisterGreeterHandlerFromEndpoint进行一个报与绑定,这时低层就会连接echoEndpoint提供的长途server地址,这样gateway就当做客户端和远程server建立了连年,之后用http启动新建的server,gateway就作为劳务器端对外提供http的劳动了。

代码到者便做到了,我们测试一下。

先启动greeter_server服务,再启动gateway,这时gatway连接上greeter_server后,对外建立http的监听。

接下来我们就此curl发送http请求

curl -X POST -k http://localhost:8080/v1/example/echo -d '{"name": " world"}'

{"message":"Hello  world"}

流程如下:curl用post向gateway发送请求,gateway作为proxy将请转化一下通过grpc转发让greeter_server,greeter_server通过grpc返回结果,gateway收到结果后,转化成json返回给前端。

这般,就经过grpc-gateway完成了起http json到里头grpc的转发过程。

相关文章

网站地图xml地图