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

使用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 greetingrpc 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-gatewayprotoc -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-gatewayprotoc -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 mainimport ("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://www.hqwc.cn/news/781285.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PostgreSQL的查询详解

PostgreSQL的查询详解 1. 表表达式 表表达式计算一个表。该表表达式包含一个 FROM 子句,该子句后面可以根据需要选用 WHERE、GROUP BY 和 HAVING 子句。最简单的表表达式只是引用磁盘上的一个表,一个所谓的基本表,但是我们可以用更复杂的表表达式以多种方法修改或组合基本表…

zabbix采集器

zabbix采集器 环境介绍: 本例中安装zabbix开源软件和postgres,软件版本信息如下:软件 版本zabbix Zabbix6.4.0postgres 14.7zabbix-agent 6.4.17主机信息如下: Red Hat Enterprise Linux Server 7.9 (Maipo)主机名 主机地址 用途zib_server 192.168.101.238 zabbix的服务器…

Mermaid 赋能 VuePress:轻松绘制流程图、时序图,让博客内容更生动

聊聊如何让博客框架 VuePress 显示图表聊聊如何让博客框架 VuePress 显示图表 ‍ 什么是 mermaid 如果你还不了解,可以先看看我的 Markdown 教程——使用 Markdown 画图。 ‍ ‍ ‍ ‍ 安装依赖 相关插件有很多,我这里选择的是 vuepress-plugin-mermaidjs: ‍ npm i vuepres…

240704-物理存储结构

1. 物理存储结构 ​ Postgresql数据库目前不支持裸设备和块设备,在Postgresql数据库中表的数据时存放在一个或者多个物理的数据文件中。而相应的数据文件又分多个固定大小的数据块,数据就放在数据块中。 1.Postgresql数据库中术语 ​ Postgresql数据库与其他数据库不同,对于…

实模式、保护模式和长模式

个人一直对硬件、操作系统等底层技术感兴趣,无奈x86架构实在过于复杂,虽然国内外很多计算机通识教育已经将主要平台迁移至更简单的risc-v,但不可否认,很多优秀的参考资料依旧是基于x86的。当你打开这些资料,一大堆眼花缭乱的新名词直接砸到你脑袋上,什么实模式、保护模式…

Datawhale X 魔搭 2024年AI夏令营第四期AIGC方向 Task01

从零入门AI生图原理&实践是 Datawhale 2024 年 AI 夏令营第四期的学习活动(“AIGC”方向),基于魔搭社区“可图Kolors-LoRA风格故事挑战赛”开展的实践学习——适合想 入门并实践 AIGC文生图、工作流搭建、LoRA微调 的学习者参与学习内容提要:从通过代码实现AI文生图逐渐…

搭建PostgreSQL高可用集群(基于Patroni+Etcd)

搭建PostgreSQL高可用集群(基于Patroni+Etcd) 1.主机环境准备节点名称 主机名 网卡 IP地址 OS 安装软件 角色作用PGSQL1 pgsql1 ens33 192.168.198.162 CentOS7 PostgreSQL、ETCD、Patroni 主数据库PGSQL2 pgsql2 ens33 192.168.198.163 CentOS7 PostgreSQL、ETCD、Patroni 备…

Pytorch入门:tensor张量的构建

tensor数据结构是pytorch的基础与核心,本文主要介绍三种常用的tensor张量的构建方式。 1.从已有其他数据转换为tensor数据 常用方法有如下两种:torch.tensor torch.Tensor上述两种方法有细微的差别,具体通过示例来进行展示运行结果为首先,torch.tensor会对转换前容器内元素的…

Centos7安装Java8

1.查看目前环境 rpm -qa|grep jdk原有系统安装有jdk,如果对于jdk有要求,我们就需要重新安装jdk 2.卸载原有jdk环境 rpm -e --nodeps 上面显示的东西这里,我们就需要一个一个去卸载 如果有感觉麻烦,可以使用如下命令 yum remove *openjdk* 3.重新检查java -versionrpm -qa|g…

VDI/VDE 2643 Part3 2008:10

VDI/VDE 2643 2008:10 第三部分[!NOTE] 原始PDF链接:https://www.doc88.com/p-50359701027029.htmlOptical 3D-measuring systems Multiple view systems based on area scanning Preliminary note The content of this guideline has been developed in strict accordance wi…

026.Vue3入门,父页面给子页面传递数据,在子页面不能修改,只能改自己的data内容

1、App.vue代码:<template><Father/> </template><script setup> import Father from ./view/Father.vue </script><style> </style>2、Father.vue代码:<template><h3>父页面</h3><Child :FatherMsg="m…

025.Vue3入门,父页面给子页面传递数据,校验Props给出默认值

1、App.vue代码:<template><Father/> </template><script setup> import Father from ./view/Father.vue </script><style> </style>2、Father.vue代码<template><h3>父页面</h3><Child :FMsg="msg"…