grpc同时支持rpc以及http服务

假定我们有一个项目需求,希望用Rpc作为内部API的通讯,同时也想对外提供Restful Api,写两套又太繁琐不符合

于是我们想到了Grpc以及Grpc Gateway,这就是我们所需要的
在这里插入图片描述

准备环境

假设以及安装好go环境以及grpc所需的组件

  • Golang
  • Grpc
  • Protoc Plugin
  • Protocol Buffers
  • Grpc-gateway

准备构建所需组件

// +build tools

package tools

import (
    _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway"
    _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger"
    _ "github.com/golang/protobuf/protoc-gen-go"
)

运行go mod tidy以解决版本。通过运行安装

 go install \
    github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway \
    github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger \
    github.com/golang/protobuf/protoc-gen-go

这将在$GOBIN目录中放置三个二进制文件;

  • protoc-gen-grpc-gateway-
  • protoc-gen-swagger
  • protoc-gen-go

对原有的RPC服务进行改造

your_history_service.proto:

syntax = "proto3";
package example;
message StringMessage {
    
    
  string value = 1;
}

service YourService {
    
    
  rpc Echo(StringMessage) returns (StringMessage) {
    
    }
}

your_new_service.proto:

 syntax = "proto3";
 package example;
+
+import "google/api/annotations.proto";
+
 message StringMessage {
    
    
   string value = 1;
 }

 service YourService {
    
    
-  rpc Echo(StringMessage) returns (StringMessage) {
    
    }
+  rpc Echo(StringMessage) returns (StringMessage) {
    
    
+    option (google.api.http) = {
    
    
+      post: "/v1/example/echo"
+      body: "*"
+    };
+  }
 }

您将需要向protoc编译器提供所需的第三方protobuf文件。它们包含在此存储库中的third_party/googleapis文件夹下,建议将它们复制到protoc生成文件结构中。如果您已按照Buf样式指南的要求来构造原型文件,则可以将文件复制到顶级./google文件夹中。

上述话是官方文档中所介绍,我将下述目录下的复制粘贴到protoc文件的根目录下
E:\GOPATH\pkg\mod\github.com\grpc-ecosystem\[email protected]\third_party\googleapis
在这里插入图片描述
在这里插入图片描述

生成rpc存根

1.这是生成RPC存根serveric.pd.go的命令

protoc -I. --go_out=plugins=grpc,paths=source_relative:./gen/go/ your/service/v1/your_service.proto

2.使用生成反向代理 protoc-gen-grpc-gateway

protoc -I. --grpc-gateway_out=logtostderr=true,paths=source_relative:./gen/go \
 your/service/v1/your_service.proto

示例代码

/*
@Time : 2020/6/8 10:21
@Author : zhb
@File : serviceHttp
@Software: GoLand
*/
package main

import (
	"context"
	"flag"
	"github.com/golang/glog"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	pb "grpcDemo/protoc"
	"net/http"
)

var (
	// command-line options:
	// gRPC server endpoint
	grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:9090", "gRPC server endpoint")
)

type SearchServiceHttp struct{
    
    }

func (s *SearchServiceHttp) Search(ctx context.Context, r *pb.SearchRequest) (*pb.SearchResponse, error) {
    
    
	return &pb.SearchResponse{
    
    Query: r.GetQuery() + " Server"}, nil
}

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

	// Register gRPC server endpoint
	// Note: Make sure the gRPC server is running properly and accessible
	mux := runtime.NewServeMux()
	//opts := []grpc.DialOption{grpc.WithInsecure()}
	err := pb.RegisterSearchServiceHandlerServer(ctx, mux, &SearchServiceHttp{
    
    })
	if err != nil {
    
    
		return err
	}

	// Start HTTP server (and proxy calls to gRPC server endpoint)
	return http.ListenAndServe(":8081", mux)
}

func main() {
    
    
	flag.Parse()
	defer glog.Flush()

	if err := run(); err != nil {
    
    
		glog.Fatal(err)
	}
}

完整代码示例

猜你喜欢

转载自blog.csdn.net/weixin_39998006/article/details/106614111
今日推荐