首页 > 其他分享 >grpc-gateway:grpc转换为http协议对外提供服务

grpc-gateway:grpc转换为http协议对外提供服务

时间:2024-08-11 15:15:55浏览次数:19  
标签:http grpc helloworld server go gateway

使用grpc的优点很多,二进制的数据可以加快传输速度,基于http2的多路复用可以减少服务之间的连接次数,和函数一样的调用方式也有效的提升了开发效率。

不过使用grpc也会面临一个问题,我们的微服务对外一定是要提供Restful接口的,如果内部调用使用grpc,在某些情况下要同时提供一个功能的两套API接口,这样就不仅降低了开发效率,也增加了调试的复杂度。于是就想着有没有一个转换机制,让Restful和gprc可以相互转化。

在网上看到一个解决方案,https://github.com/grpc-ecosystem/grpc-gateway,简单的说就是有一个网关服务器负责转化和代理转发。

如下图:
image

安装

首先要安装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 \
--grpc-gateway_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的转化过程。

标签:http,grpc,helloworld,server,go,gateway
From: https://www.cnblogs.com/596014054-yangdongsheng/p/10803351.html

相关文章

  • Haproxy实现https
    haproxy可以实现https的证书安全,从用户到haproxy为https,从haproxy到后端服务器用http通信,但是基于性能考虑,生产中证书都是在后端服务器比如nginx上实现。配置HAProxy支持https协议,支持ssl会话:bind*:443sslcrt/PATH/TO/SOME_PEM_FILE指令crt后证书文件为PEM格式,......
  • python asyncio grpc
    1.准备环境python3.11-mvenvvenvsourcevenv/*/activatepipinstallgrpcio-tools#包含了grpcio和protobufpipinstalltypes-protobufgrpc-stubs#可选安装,用于mypy静态检查2.编写msg.protosyntax="proto3";//这是注释,同时也是类文档serviceMsgService{......
  • git clone 网络太差总是失败:error: RPC 失败。curl 92 HTTP/2 stream 5 was not close
    ❯gitclonehttps://github.com/Almamu/linux-wallpaperengine.git.正克隆到'.'...remote:Enumeratingobjects:6271,done.remote:Countingobjects:100%(1447/1447),done.remote:Compressingobjects:100%(628/628),done.error:RPC失败。curl92HTT......
  • Java工具类封装微服务间HTTP通信
    在微服务架构中,服务之间通常通过HTTP协议进行通信。为了简化这一过程,我们可以创建一些工具类来封装HTTP请求的发送逻辑。本篇文章将介绍如何使用Java来创建这样的工具类,并分别演示使用ApacheHttpClient和SpringFramework中的RestTemplate来发送HTTPGET请求的方法。1.引言......
  • 使用go+gin编写日志中间,实现自动化收集http访问信息,错误信息等,自动化生成日志文件
    1.首先在logger包下点击查看代码packageloggerimport( "fmt" "io" "net/http" "os" "path" "runtime/debug" "time" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus&q......
  • http.sys 是 IIS 的底层组件,负责高效、安全地处理 HTTP 请求,而 IIS 则提供了更高层次
    IIS(InternetInformationServices)和http.sys是MicrosoftWindows操作系统中的两个相关组件,它们一起工作来处理和管理HTTP请求。以下是它们的关系和功能:IIS:Web服务器:IIS是Microsoft的Web服务器软件,提供了用于托管和管理Web应用程序的功能,包括网站、应用程序......
  • http协议中url中的解码和解码
    问题引出当我们进入百度页面:此时的域名是:www.baidu.com当我们搜索aaa+@///+bbb时此时的域名是:https://www.baidu.com/s?wd=aaa%2B%40%2F%2F%2F%2Bbbb&rsv_spt=1&rsv_iqid=0xc051be38000e103b&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_p......
  • next.js本地开发https实现
    很奇怪的需求,本地开发一般都是http://localhost:3000,但有些情况需要https://localhost:3000来debug,这类需求估计比较少,我看使用next.js的中文教程也比较少,这里记录一下。网上很多找到的教程都是自己去转一堆软件和依赖,还要分Mac和Windows,看着就头疼,这个实现方式是官方给的,通过NEX......
  • 手写Redis缓存系统,第一章:基于http协议实现的缓存系统
    关系描述关系图文本描述main包依赖cache包依赖http包流程:main包的main函数调用cache.New("inmemory")创建一个缓存实例。main包的main函数将缓存实例传递给http.New(c)创建一个Server实例。Server实例调用Listen方法启动HTTP服务器......
  • HTTP协议基础知识【后端 4】
    HTTP协议基础知识HTTP(HyperTextTransferProtocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,它定义了客户端(如浏览器)与服务器之间数据传输的格式和规则。无论是浏览网页、在线购物还是使用各种Web应用,HTTP都扮演着至关重要的角色。本文将深入解析HTTP协议的基......