目前公司对外的 api 都要经过统一 http 网关,但一些内部的 rpc 服务想要对外服务的话,我们得专门写个 http 接口暴暴露给网关,但这样要维护两套代码有点麻烦,我想在网关这层做一道转换,把外部的 http 的 json 报文转换成内部的 rpc 调用。现在有两种方案:
想知道下大厂是不是也有在网关层 json 转 rpc 的需求,你们是怎么做的呢?这两种方案你哪个好一些,有啥坑吗
1
DefoliationM 241 天前 via Android
strings.Contains(r.Header.Get("Content-Type"), "application/grpc")
用 content-type 判断一下 |
2
DefoliationM 241 天前 via Android
@DefoliationM 外面直接发 grpc 请求
|
3
ducuducu OP @DefoliationM 也是个法子🥹
|
4
GenericT 241 天前
@DefoliationM grpc 是 http2 的,他这网关看起来就不支持的样子
|
5
lambdaq 241 天前
grpc 本来就是 h2 直接透传。谁不接住解析谁就是孙子就完事了。。。
|
6
luozic 241 天前
看你们的网关支持啥啊。已有网关是个不支持 h2 的,你这传了有啥用。 看别的网关有啥,是准备切换别的网关了?
|
7
coderxy 241 天前
还可以用 json 作为 grpc 的传输协议,http 网关不需要了解 pb 的内容。 最好要在网关做一个映射配置列表,不然全自动映射把内部重要接口泄漏了就 G 了
|
8
ducuducu OP @GenericT 想让外部调用者直接能用 http json 报文调用。或者我可以把 proto 文件他们,让外部调用方用 grpc 方式调网关,这样,,也行
|
10
Daath 241 天前
像 k8s 的 ingress-nginx 代理 http 和 grpc 服务?如果是的话,用路径匹配,分别指向不同的服务
|
11
rrfeng 241 天前
grpc 用 http2 传输的,让我看看哪家网关还不支持 http2 ……
|
13
pinne 241 天前
实现过第二种,不过只在内部做定时调用使用过。做法是将 proto 文件内容上传到一个地方,然后网关处解析。不过这样的问题是每次 proto 更新,都要重新上传。想法是可以直接暴露接口给网关,网关自动获取 pb 内容。
|
14
seth19960929 241 天前
第一个就错了吧, 不需要在 rpc 容器内启动 HTTP 服务,
你就另起服务作为 gateway, 然后穿透给 rpc 就好了. 就是你说的 grpc-gateway 不就挺好? |
15
poltao 241 天前
结合注册中心,搞个统一网关管理平台,由网关负责转发 http 请求就可以了
|
16
macscsbf 241 天前
|
18
mind3x 241 天前
敝司是写了个简单的 HTTP bridge 给一些作 gRPC 调用比较麻烦的 client 用,大概就是 header 里传 service 和 method 名,payload 和 response 都转 JSON 。
|
19
layxy 240 天前 1
感觉你们网关还是不健全,网关一个很重要的基础能力就是协议转换,对外统一都是 http(s),但是内部服务有 springcloud,dubbo,grpc 等,不可能让内部服务再封装 http 再在网关注册,这样所有接入方的工作量会大上不少,而且也浪费资源
|
21
dhb233 240 天前
GRPC 记得有一个功能是 Server Reflection ,是把自己支持的接口暴露出来,具体参考 https://github.com/fullstorydev/grpcurl 的文档
|
22
dhb233 240 天前
但是感觉这个 Server Reflection 直接对外的话,有点不安全。。。如果 GRPC 只对 gateway 开放应该还好
|
23
sophos 240 天前
协议转换这块是 cpu 密集型场景,apisix 等 nginx+lua 的方案,目前的实现方案性能最差(基于 lua 做的协议转换)
根据这边的落地经验,出于性能考虑,推荐以下两种: - 基于 grpc-gateway 另起一个 http server 用于转发 grpc 请求,每次调整需要重新发布代码,性能可用,无需引入新的中间件 - 基于 envoy 配置 protoset 和 filter ,每次调整只需要更改配置,性能相对较高,需要引入新的中间件 |
24
SmiteChow 240 天前
搞复杂了,网关直接根据 http 请求组装一个 general 的 grpc 消息,grpc 有一个统一入口二次分发,并不是说网关直接就 touch 到业务层级去根据 proto 组装业务 grpc 数据
|
25
MelodYi 240 天前
先报下网关选型吧,不然也不好说你能有哪些方案。
常见的方式有 grpc2grpc ,直接过网关透传,网关正常解 ssl 之类的。envoy 之类的技术选型天然支持。 http2grpc ,网关做协议转换,kong 之类的网关有插件做。这类一般比较耗 cpu ,机器开大点。如果 protobuf 和 json 的银蛇关系非常基础、标准,可以用。这类插件遇到复杂一些的报文拼装逻辑基本歇菜。 服务自己开个 http 口子。咋说呢,用 grpc 的服务不多的话,这个方案其实最省事,啥也不用折腾,毕竟网关改个配置搞错了还影响别的业务。 |
26
nevermoreluo 240 天前
c#的话 我记得用过微软自己有一套 引入库直接在 grpc 文件里面定义 api 就好了
两个端口 一个 grpc 一个 http 调用 ``` import "google/api/annotations.proto"; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) { option (google.api.http) = { get: "/v1/greeter/{name}" }; } } ``` 详细的看看微软的文档吧 https://learn.microsoft.com/en-us/aspnet/core/grpc/browser?view=aspnetcore-8.0 还有 go 的 grpc gateway https://github.com/grpc-ecosystem/grpc-gateway |
27
gvison 240 天前
在 grpc 服务中增加一个 http 服务对现有系统影响是最小的,也就是一个微服务中同时提供了 http 和 grpc 两种调用(不是 grpc-gateway 方式),共用一套业务逻辑,B 站开源的微服务框架 kratos 是支持 http 和 grpc 的,我猜 B 站应该是这样的方案。
|
28
lemon1997 239 天前
可以参考下这个 https://github.com/lemon-1997/dynamic-grpc
会监听 grpc 服务,服务更新会利用反射读取最新的协议,无需手动去生成代码或者上传 proto ,采用跟 grpc-gateway 同样的 proto http 注解 |