gRPC 服务要加 HTTP 接口?

go-zero 给大家带来极简的 RESTful 和 gRPC 服务开发体验的同时,社区又给我们提出了新的期望:

  • 我想只写一次代码
  • 既要 gRPC 接口
  • 也要 HTTP 接口
  • 既要。。。也要。。。

也有道理嘛!你看用户怎么说:

用户A:一套逻辑,api和rpc一起

用户B:go-zero要是能简化这一步我感觉会成为go生态中最好的微服务框架没有之一

于是,我陷入了深深的思考:用户从来是不会错的,但是我们要不要提供呢?

于是,你看到了这篇文章。。。

我们先提供 gRPC 服务

对于这种服务,我们太熟了。新建一个目录,就叫 grpc-restufl 吧,里面放个 sum.proto 文件

syntax = "proto3";

package sum;
option go_package="./pb"; message Numbers {
int64 a = 1;
int64 b = 2;
} message SumRequest {
Numbers numbers =1;
} message SumResponse {
int64 result = 1;
} service Sum {
rpc Add(SumRequest) returns (SumResponse) {}
}

一键生成,你懂的。。。

$ goctl rpc protoc --go_out=. --go-grpc_out=. --zrpc_out=. sum.proto

看看都有了啥

.
├── etc
│   └── sum.yaml
├── go.mod
├── internal
│   ├── config
│   │   └── config.go
│   ├── logic
│   │   └── addlogic.go
│   ├── server
│   │   └── sumserver.go
│   └── svc
│   └── servicecontext.go
├── pb
│   ├── sum.pb.go
│   └── sum_grpc.pb.go
├── sum
│   └── sum.go
├── sum.go
└── sum.proto

实现一下业务逻辑,将 internal/logic/addlogic.go 里的 Add 方法修改如下:

func (l *AddLogic) Add(in *pb.SumRequest) (*pb.SumResponse, error) {
return &pb.SumResponse{
Result: in.Numbers.A+in.Numbers.B,
}, nil
}

可以跑了,业务逻辑也是有了的(虽然很简单,演示嘛。。。)

$ go mod tidy && go run sum.go
Starting rpc server at 127.0.0.1:8080...

对于熟悉 go-zero 的同学来说,至此无亮点(新知识),接下来 GET 新技能~

提供 HTTP 接口

更新 go-zero

首先,我们更新 go-zero 至 master 版,因为 gateway 还没正式发版,八月初会正式跟大家见面

$ go get -u github.com/zeromicro/go-zero@master

修改 proto 文件

修改 sum.proto,我新建了一个 sum-api.proto,如下:

syntax = "proto3";

package sum;
option go_package="./pb"; import "google/api/annotations.proto"; message Numbers {
int64 a = 1;
int64 b = 2;
} message SumRequest {
Numbers numbers =1;
} message SumResponse {
int64 result = 1;
} service Sum {
rpc Add(SumRequest) returns (SumResponse) {
option (google.api.http) = {
post: "/v1/sum"
body: "*"
};
}
}

生成 proto descriptor 文件

protoc --include_imports --proto_path=. --descriptor_set_out=sum.pb sum-api.proto

修改配置文件

修改后的 internal/config/config.go 如下(部分):

type Config struct {
zrpc.RpcServerConf
Gateway gateway.GatewayConf
}

修改后的 etc/sum.yaml 如下:

Gateway:
Name: gateway
Port: 8081
Upstreams:
- Grpc:
Endpoints:
- localhost:8080
ProtoSet: sum.pb

修改 main 函数

创建 gateway 并用 ServiceGroup 来管理 gRPC servergateway server,部分代码如下:

    gw := gateway.MustNewServer(c.Gateway)
group := service.NewServiceGroup()
group.Add(s)
group.Add(gw)
defer group.Stop() fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
fmt.Printf("Starting gateway at %s:%d...\n", c.Gateway.Host, c.Gateway.Port)
group.Start()

大功告成

让我们来启动服务

$ go run sum.go
Starting rpc server at 127.0.0.1:8080...
Starting gateway at 0.0.0.0:8081...

curl 测试一下

$ curl -i -H "Content-Type: application/json" -d '{"numbers":{"a":2,"b":3}}' localhost:8081/v1/sum
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Traceparent: 00-ad5b7df7a834a1c05ee64999e3310811-195ba1f4f9956cc4-00
Date: Mon, 18 Jul 2022 14:33:11 GMT
Content-Length: 20 {
"result": "5"
}

再看我们的 gatewaygRPC 的日志里的链路信息和客户端收到的都能对应上,赞!

{"@timestamp":"2022-07-18T22:33:11.437+08:00","caller":"serverinterceptors/statinterceptor.go:76","content":"127.0.0.1:61635 - /sum.Sum/Add - {\"numbers\":{\"a\":2,\"b\":3}}","duration":"0.0ms","level":"info","span":"b3c85cd32a76f8c9","trace":"ad5b7df7a834a1c05ee64999e3310811"}
{"@timestamp":"2022-07-18T22:33:11.438+08:00","caller":"handler/loghandler.go:197","content":"[HTTP] 200 - POST /v1/sum - 127.0.0.1:61662 - curl/7.79.1","duration":"0.7ms","level":"info","span":"195ba1f4f9956cc4","trace":"ad5b7df7a834a1c05ee64999e3310811"}

结束语

你看,给我们的 gRPC 服务加上 HTTP 接口是不是五分钟就可以完成了?是不是?

另外,不要小看这个简单的 gateway,配置里如果是对接后面的 gRPC 服务发现的话,会自动负载均衡的,并且还可以自定义中间件,想怎么控制就怎么控制。

是不是有点心动了呢?

对了,这个示例的完整代码在:

https://github.com/kevwan/grpc-restful

项目地址

https://github.com/zeromicro/go-zero

欢迎使用 go-zerostar 支持我们!

微信交流群

关注『微服务实践』公众号并点击 交流群 获取社区群二维码。

五分钟给你的 gRPC服务 加上 HTTP 接口的更多相关文章

  1. 十分钟学会Golang开发gRPC服务

    gRPC是Google发起的一个开源RPC框架,使用HTTP/2传输协议,使用Protocol Buffers编码协议,相比RESTful框架的程序性能提高不少,而且当前流行的编程语言基本都已经支持. ...

  2. 在过去五分钟内,TypeScript语言服务以外终止了5次

    这个问题困扰了我两次...第一次重装了VS CODE 具体的原意找到之后我直接想骂娘....... 各位如果碰到这个问题....请打开你的360安全卫士!!! 注意看看您家360的防护日志有木有贴心帮 ...

  3. [分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例)

    [分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例) 踏雁寻花 发表于 2015-8-23 23:31:28 https://www.itsk.com/thread-35 ...

  4. 【转】在服务器上排除问题的头五分钟&常用命令

    转自:https://blog.csdn.net/l821133235/article/details/80103106(在服务器上排除问题的头五分钟) 遇到服务器故障,问题出现的原因很少可以一下就想 ...

  5. 五分钟DBA:浅谈伪分布式数据库架构

    [IT168 技术]12月25日消息,2010互联网行业技术研讨峰会今日在上海华东理工大学召开.本次峰会以“互联网行业应用最佳实践”为主题,定位于互联网架构设计.应用开发.应用运维管理,同时,峰会邀请 ...

  6. 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

    这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...

  7. 转帖:用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

    用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树 这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托 ...

  8. 《sed的流艺术之四》-linux命令五分钟系列之二十四

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  9. 《sed的流艺术之三》-linux命令五分钟系列之二十三

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

随机推荐

  1. 服务器脚本搭建国基北盛openstack平台

    @ 目录 基础环境搭建 控制节点网卡配置 计算节点网卡配置 主机映射 3,关闭防火墙和selinux以及NetworkManager 设置yum源 计算节点分区 配置openrc.sh环境变量 平台组 ...

  2. K8S面试应知必回

    目录 面试不要不懂装懂,不会就是不会,不可能每个人都接触过所有的知识! 1. 基础问题 1.1 Service是怎么关联Pod的?(课程Service章节) 1.2 HPA V1 V2的区别 1.3 ...

  3. zabbix 添加监控交换机温度item

    首先需要获取到交换机温度对应的OID,可以官方文档进行查询(多为私有OID),以盛科为例 官方文档查询到温度节点对于的OID为 10.0.3.102 1.3.6.1.4.1.27975.37.1.3. ...

  4. 【算法】插入排序(Insertion Sort)(三)

    插入排序(Insertion Sort) 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相 ...

  5. TypeScript 学习的随笔

    TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准 安装TypeScript npm install -g typescript 编译 tsc app.t ...

  6. 关于JNPF3.4版本的三大改变,你真的了解了吗?

  7. 2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP详细版

    2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP 题目描述 蓝桥学院由21栋教学楼组成,教学楼编号1到21.对于两栋教学楼a和b,当a和b互质时,a和b之间有一条走廊直接相连,两个方向皆可通 ...

  8. Node.js精进(2)——异步编程

    虽然 Node.js 是单线程的,但是在融合了libuv后,使其有能力非常简单地就构建出高性能和可扩展的网络应用程序. 下图是 Node.js 的简单架构图,基于 V8 和 libuv,其中 Node ...

  9. C#实现[移除文件名中的非中文字符]

    更新记录: 2022年5月28日 从程序中抽出方法复用. 处理财务文件时写的一个小函数.用于移除文件名中的非中文字符. /// <summary> /// 移除文件名中的非中文字符 /// ...

  10. 第六章、PXE高效网络装机、Kickstart无人值守安装

    目录 一.部署PXE远程安装服务 1PXE定义 2PXE服务优点 3搭建网络体系前提条件 4PXE实现过程讲解 二.搭建PXE远程安装服务器 三.Kickstart无人值守安装 一.部署PXE远程安装 ...