最近在搞grpc这块的东西,需要帮自动化测试工具把grpc转成http,用到了这块东西,折腾了好几天最终搞定

可直接看分割线一下内容

1、GRPC概述

GRPC 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。

在 GRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,GRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 GRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。

2、特性

基于HTTP/2
HTTP/2 提供了连接多路复用、双向流、服务器推送、请求优先级、首部压缩等机制。可以节省带宽、降低TCP链接次数、节省CPU,帮助移动设备延长电池寿命等。gRPC 的协议设计上使用了HTTP2 现有的语义,请求和响应的数据使用HTTP Body 发送,其他的控制信息则用Header 表示。

IDL使用ProtoBuf
GRPC使用ProtoBuf来定义服务,ProtoBuf是由Google开发的一种数据序列化协议(类似于XML、JSON、hessian)。ProtoBuf能够将数据进行序列化,并广泛应用在数据存储、通信协议等方面。压缩和传输效率高,语法简单,表达力强。

多语言支持(C, C++, Python, PHP, Nodejs, C#, Objective-C、Golang、Java)
GRPC支持多种语言,并能够基于语言自动生成客户端和服务端功能库。目前已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go,其它语言的版本正在积极开发中,其中,grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等语言,grpc-java已经支持Android开发。

3、常见的grpc测试工具

为什么需要grpc测试工具?

目前大多数分布式服务之间的调用是基于http 1.*协议实现的,HTTP/1.* 是纯文本数据传输。而grpc框架的底层网络协议是HTTP2.0,在传输的过程中数据是二进制的,在目前的市面是还有没有比较完善和方便的测试grpc框架的测试工具,像是测试http1.*的postman这种下载就能使用的测试工具。

但是在开源社区已经有很多的贡献者给出解决方案,这些方案都是一个在grpc服务和传统的httpclient测试工具之间代建一个代理服务,将传统的http1.*的请求包装转化为grpc框架的HTTP2请求。

常用的grpc测试框架是有:

grpcc:https://github.com/njpatel/grpcc,grppc是nodejs技术实现的,一个命令行工具。

Omgrpc: https://github.com/troylelandshields/omgrpc, omgrpc是nodejs技术实现,运行一个客户端,读取解析一个protobuf文件,将message消息的结构体中的字段会映射到一张表单中,填写相关的测试数据就可以运行。

Grpc-json-proxy: https://github.com/jnewmano/grpc-json-proxy,go语言的技术实现,启动一个一个go程序做代理层,可以结合postman等流行httpclient测试工具使用。对go 语言开发的grpc服务支持较好。

4、什么是grpc-gateway?

grpc-gateway是ProtoC的插件。ProtoC是protobuf底层解析器,它读取GRPC服务定义,并生成一个反向代理服务器,将一个REST的JSON API转换成GRPC。这个服务器是根据您的GRPC定义中的自定义选项生成的。

它可以帮助您同时提供GRPC和REST风格的API。

它用许多编程语言生成API客户机和服务器存根,它快速、易用、带宽高效,其设计得到了Google的验证。但是,您可能还希望提供一个传统的REST API。原因可以是维护向后兼容性、支持gRPC不支持的语言或客户端,也可以是简单地维护RESTful体系结构所涉及的美学和工具。而GRPC Gateway仅生成go语言的代理,因此在搭建GRPC Gateway前需要搭建Go语言基本环境。 另外由于Go语言相关插件以及Github访问,可能需要代理才能访问。因此运行本手册建议先确保能使用代理服务器访问Golang、Github等网站

本项目旨在为您的GRPC服务提供HTTP+JSON接口。附加HTTP语义的服务中的少量配置就是使用该库生成反向代理所需的全部配置。

******************************************************************************************************************************************************

分割线

******************************************************************************************************************************************************

5、开始搭建:

5.1 搭建go语言环境

安装golang环境的官方文档,https://www.nats.io/documentation/tutorials/go-install/,有详细的说明,但是官方的网站,可能需要代理才能访问。

可以在https://studygolang.com/dl这里下载到所需资源,本例是win7的64位系统所以本例下载的是go1.9.2 windows/amd64的压缩文件,解压后的目录结构如下:

正确的配置GOROOT和GOPATH环境变量:

$GOROOT 指向golang安装之后的根目录,windows平台下默认为c:/go此处记得修改。本例中是D:\softo\go

$GOPATH 个人代码存放目录,本例中是D:\softo\go\third_party

在系统环境变量里面添加:window下,在我的电脑右键,点击属性->高级系统设置(window8)->高级->环境变量

在系统变量里添加GOPATH(你代码放的地方),如果msi安装的话,GOROOT(golang的安装目录),GOBIN(golang安装目录中bin文件夹)直接添加啦,zip安装这两个就需要自己配置

配置完成,打开cmd,输入go ,就可以看到go的命令

5.2 搭建Protobuf

Protobuf是grpc框架底层的序列化工具,所以再使用grpc框架时,一定需要安装protobuf工具。到https://github.com/protocolbuffers/protobuf/releases,下载所需要的版本(win32的我用的是这个版本protoc-3.6.1-win32.zip),本例中下载win版本的zip包,目录地址是D:\softo\protobuf, 解压下来目录结构是:

把bin目录写到系统环境变量里面,本例是:D:\softo\protobuf\bin,将其加入系统PATH变量中。

Protobuf的版本要求大于3.0.0-beta-3,另外protobuf的include目录,在后续步骤会采用。

5.3 grpc-gateway 依赖

grpc-gateway是一个开源的服务项目,在github上可以很轻松的获得。这是grpc-gateway的地址:https://github.com/grpc-ecosystem/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

下载资源的过程可能需要用到翻墙(因为有部分的google组件)

参考:https://grpc-ecosystem.github.io/grpc-gateway/docs/usage.html(官方的安装步骤)。

如果不想下载,或者环境不允许的情形下可以使用以下步骤实现

组件可以从下面链接访问下载:

http://git.orientsec.com.cn/projects/GRPC/repos/grpc-docs/browse/%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C/third_party.zip

将third_party.zip解压到D:\softo\go目录

目录结构为 

grpc-gateway 使用

在%GOPATH%/src目录下新建一个gw目录(名称可以任意),将grpc service端的*.protobuf的文件拷贝一份到目录下,本例的路劲如下:D:\softo\go\third_party\src\gw\greeter.proto,其内容如下:

syntax = "proto3";

option java_multiple_files = true;

option java_package = "com.orientsec.demo";

option java_outer_classname = "GreeterProto";

package com.orientsec.demo;

service Greeter {

rpc sayHello (GreeterRequest) returns (GreeterReply) {}

}

message GreeterRequest {

int32  no   = 1;

string name = 2;

bool sex = 3;

double salary = 4;

string desc = 5;

}

message GreeterReply {

bool success = 1;

string message = 2;

int32  no   = 3;

double salary = 4;

int64 total = 5;

}

修改greeter.proto文件:

syntax = "proto3";

option java_multiple_files = true;

option java_package = "com.orientsec.demo";

option java_outer_classname = "GreeterProto";

package com.orientsec.demo;

import "google/api/annotations.proto";

service Greeter {

// rpc sayHello (GreeterRequest) returns (GreeterReply) {}

rpc sayHello (GreeterRequest) returns (GreeterReply) {

option (google.api.http) = {

post: "/v1/sayHello"

body: "*"

};

}

}

message GreeterRequest {

int32  no   = 1;

string name = 2;

bool sex = 3;

double salary = 4;

string desc = 5;

}

message GreeterReply {

bool success = 1;

string message = 2;

int32  no   = 3;

double salary = 4;

int64 total = 5;

}

环境准备到此结束

编译

通过下面的命令生成grpc stub, 切换到目录 D:\softo\go\third_party\src\gw:

protoc -ID:\softo\protobuf\include -I. -I%GOPATH%/src -I%GOPATH%/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --go_out=plugins=grpc:. ./greeter.proto

D表示的是d盘

运行的结果,在D:\softo\go\third_party\src\gw生成一个greeter.pb.go文件。该文件主要是grpc stub文件,处理grpc 服务注册发现等问题。

通过下面的命令生成反向代理:

protoc -ID:\softo\protobuf\include -I. -I%GOPATH%/src -I%GOPATH%/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --grpc-gateway_out=logtostderr=true:. ./greeter.proto

运行的结果,在D:\softo\go\third_party\src\gw生成一个greeter.pb.gw.go文件。该文件的主要作用是生成代理服务,转化http包到rpc包格式等。

编译后生成如下:

运行

新建目录D:\softo\go\third_party\src, 目录下新建main.go文件,内容如下:

package main

import (

"flag"

"net/http"

"github.com/golang/glog"

"golang.org/x/net/context"

"github.com/grpc-ecosystem/grpc-gateway/runtime"

"google.golang.org/grpc"

gw "gw")

var (echoEndpoint = flag.String("echo_endpoint", "localhost:51001", "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(":9090", mux)

}

func main() {

flag.Parse()

defer glog.Flush()

if err := run(); err != nil {

glog.Fatal(err)

}

}

其中echoEndpoint = flag.String("echo_endpoint", "ip:51001", "endpoint of YourService"),ip:51001,是grpc 服务地址。gw.RegisterYourServiceHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts),其中红色部分需要收到修改一下, 本例修改为:gw.RegisterGreeterHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts),

注意:YourService应该是和你的proto文件里面定义的service 名字保持一致不然可能会报这种错误

http.ListenAndServe(":9090", mux) 这里地址是grpc-gateway提供服务的端口。

src目录如下

使用

可以使用postman工具进行测试,本例测试结果如图:

多proto执行文件参考如下

可新建gw2 gw3  gw4 gw5  gw6 gw7  gw8 gw9文件夹将分别将带有service 目录的proto分别复制到各个文件里,

并新建对应的main*.go启动文件,注意标红地方修改,监听端口不要和其他的main.go冲突

如果有依赖的公用proto文件一并复制到文件夹里,然后按照上面的编译方式进行编译,然后为每个可执行的proto

附录:编译生成可执行文件

引用文章https://blog.csdn.net/panshiqu/article/details/53788067内容如下:

Mac 下编译 Linux 和 Windows 64位可执行程序:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go

CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go12

Linux 下编译 Mac 和 Windows 64位可执行程序:

CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go

CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go12

Windows 下编译 Mac 和 Linux 64位可执行程序:

SET CGO_ENABLED=0

SET GOOS=darwin

SET GOARCH=amd64

go build main.go

SET CGO_ENABLED=0

SET GOOS=linux

SET GOARCH=amd64

go build main.go

GOOS:目标平台的操作系统(darwin、freebsd、linux、windows) GOARCH:目标平台的体系架构(386、amd64、arm) 交叉编译不支持 CGO 所以要禁用它

上面的命令编译 64 位可执行程序,你当然应该也会使用 386 编译 32 位可执行程序 很多博客都提到要先增加对其它平台的支持,但是我跳过那一步,上面所列的命令也都能成功,且得到我想要的结果,可见那一步应该是非必须的,或是我所使用的 Go 版本已默认支持所有平台。

番外篇:Nginx设置

可用于多proto,代理转发到不同的grpc-gateway端口

1.下载nginx

http://nginx.org/en/download.html,以nginx/Windows-1.15.8为例,

下载后解压,解压后如下

双击nginx.exe,访问localhost:80查看是否安装成功

进入conf文件修改nginx.conf

如下

通过postman工具测试图

grpc-gateway搭建相关推荐

  1. Grpc+Grpc Gateway实践二 有些复杂的Hello World

    Hello World 在上一节中我们已经完成了对环境的基本配置 这节将开始编写一个复杂的Hello World,涉及到许多的知识,建议大家认真思考其中的概念 需求 由于本实践偏向Grpc+Grpc ...

  2. Grpc+Grpc Gateway实践一 介绍与环境安装

    介绍与环境安装 假定我们有一个项目需求,希望用Rpc作为内部API的通讯,同时也想对外提供Restful Api,写两套又太繁琐不符合 于是我们想到了Grpc以及Grpc Gateway,这就是我们所 ...

  3. 2 GateWay工作流程+GateWay搭建

    GateWay工作流程+GateWay搭建 核心流程图如下: 核心概念: 客户端向 Spring Cloud Gateway 发出请求.如果Gateway Handler Mapping确定请求与路由 ...

  4. grpc+gateway使用说明

    文章目录 grpc+gateway 使用说明(MAC版) 1. 安装 1.1 安装golang 1.2 安装protoc 1.3 安装grpc相关脚本 2. 编写protoc文件 2.1 添加prot ...

  5. grpc gateway malformed header: missing HTTP content-type

    前言 当go-micro版本是v4时,使用curl.postman等工具调用grpc gateway http接口时,会出现如下错误: malformed header: missing HTTP c ...

  6. 使用springcloud gateway搭建网关(分流,限流,熔断)

    Spring Cloud Gateway Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 ...

  7. 微服务升级_SpringCloud Alibaba工作笔记0007---spring gateway搭建

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 可以看到gateway在整个微服务中的位置,看这个还需要,有一定的springcloud的,经验的 ...

  8. QT+GRPC环境搭建

    链接:https://www.cnblogs.com/MakeView660/p/11532192.html 遇到的问题: 1.下面这两个可以不安装: pacman -S mingw-w64-x86_ ...

  9. 快速搭建一个网关服务,动态路由、鉴权看完就会(含流程图)

    [文章来源]https://sourl.cn/tcbSPi 前 言 本文记录一下我是如何使用Gateway搭建网关服务及实现动态路由的,帮助大家学习如何快速搭建一个网关服务,了解路由相关配置,鉴权的流 ...

最新文章

  1. opencv meanStdDev
  2. hdu4772 水模拟
  3. flex 关键词过滤 2.5.35
  4. Arrays.asList()使用时的注意事项,这个结论同可适用于Stream.of()___Arrays.stream和Stream.of
  5. Python学习 :格式化输出
  6. 很久以前的C语言笔记
  7. 深入理解Spring系列之四:BeanDefinition装载前奏曲
  8. 关于jacob 无法创建ActiveXCompnent对象的几种可能性
  9. C#读取数据库返回泛型集合(DataSetToList)
  10. mysql-备份和还原(普通还原和binlog还原)
  11. python中sticky_Python stickymeta包_程序模块 - PyPI - Python中文网
  12. C#异步加载数据:BackgroundWorker的使用
  13. 仿美洽客服系统-gin框架内核独立自主源码开发在线客服系统
  14. RiceQuant和 JoinQuant合成月k线、周k线的极简公式
  15. Git Bash/GUI Here “找不到应用程序问题” 的解决方案
  16. CSP难度的经典题目/有趣的思维题选讲(一)
  17. 造型简约的机箱,安装简单兼容性好,安钛克P20C体验
  18. 年薪40W的程序员需要掌握怎样的技术(Java程序员高薪必看)
  19. 【Java字符串分割[split()]和截取[substring()]】
  20. java 错误:The public type *** must be defined in its own file***

热门文章

  1. 接口的Mock测试及Mockito使用
  2. 【转载】传统蓝牙协议栈 串口协议SPP
  3. 6-3 工作汇报-有效展现业绩-项目成功与失败时的汇报方式
  4. 启信宝牵手国家队,征信服务进化再加速
  5. java多线程-爬电影天堂上的电影下载地址
  6. stm32控制超声波测距模块HC-SR04
  7. 桂花林上,再读“六项精进”
  8. linux网络编程学习笔记——epoll
  9. 多元线性回归推导过程
  10. Unity EasyAR Coloring3D AR绘图原理