golang 应该如何选择 api 网关呢

158 天前
 RedBeanIce
公司基于 gin 开发了一个系统,目前是单体服务,基本上都是 Http 和前端交互。

由于业务发展,想转入微服务,我们想基于 eureka/Consul 做注册中心,引入一款网关作为负载均衡器。

所以请问一下,应该如何选择 api 网关呢。

(关于 gin 往注册中心注册,我们准备自己写。微服务之间的调用,也是准备自己写。)
当然准备是准备,,这个也说不准,看实际情况,
3715 次点击
所在节点    Go 编程语言
53 条回复
lasuar
158 天前
现在这些云厂商的负载均衡产品都可以作为网关使用了,代替 nginx 的角色。
coderxy
158 天前
@version 我猜你说的 grpc 负载均衡的坑是在 k8s 环境下,新伸缩出的节点与老节点负载不均的问题吧?
lesismal
158 天前
@coderxy

> #6 nginx->api gateway->grpc 服务,api gateway 用 go 自己写。

api gateway 自己写,你得先有 http handler 然后转成 grpc call 去请求原来的服务对吧?原来的 gin 服务得改造成 grpc server 、把以前的 gin handler 改成 grpc method 对吧?

> #18 一般 api gateway 写好了之后,后续增加接口只需要在 web 页面上配置一下 path+method 转发到哪个 service 的哪个 method

所以还得开发个 web 页面管理这个功能啊?
但是 grpc golang call 好像没有直接通过字符串调用方法的功能吧?所以你得首先生成了对应的 call 代码、然后再在你的 web 页面上配置才行吧,那么每次更新版本有新增、修改 grpc 协议相关,你都需要把 grpc gateway 也发版本、这也是运维成本
我看了下 grpc-gateway 也是要每次先按协议生成之后才能调用,按 proto 生成之后按道理就没必要自己再 web 页面上配置了、所以你说的 web 页面的开发和在上面人工配置的成本估计可以省掉,但每次改协议发版本也仍然是多余的浪费:
https://github.com/grpc-ecosystem/grpc-gateway?tab=readme-ov-file#4-generate-reverse-proxy-using-protoc-gen-grpc-gateway

另外,如果想全动态,当然也可以自己去把 grpc 协议格式弄出来自己去拼二进制的协议,也可以搞,但同样需要花不少时间去搞这个、而且这个一半的 CURDer 也搞不定。

另外,由于 grpc gateway 直接处理 client 的 http 请求,可能就难以避免偶尔对个别接口参数的定制,网关最好还是透明一些,grpc 用 pb 这种强类型定义相比于 json 没那么方便做到网关功能的透明
所以我持续抵制这种 to c 的 api 使用这种 api 转 rpc 的 gateway 的架构设计方案,微服务集群内部之间直接 rpc 就可以了也没太大必要加这种 gateway

> #18 还有,链路追踪这些跟微服务根本就没有啥必然关系,就算是单体服务,照样可以用链路追踪,它可以帮助你快速发现和排查问题。

这个我不是很同意:例如原本只有一个 gin server 的 api 流程(连网关、反代都不需要加)、只要查 gin server 日志就够了,没有多链路所以也无所谓链路追踪
但引入更多中间节点,链路就变长了、流程就变多了,当然也可以分散着各自去查各个节点的日志,但不够系统
当然,我也不是说必须增加,自己单独查 grpc gateway 日志也行


> #6 简单一点就是 nginx->业务服务

这句是好的建议
BinaryDH
158 天前
没人用过 traefik ? traefik 是 golang 原生实现的 api 网关, 支持 二进制、docker 、k8s 等部署方式.
https://github.com/traefik/traefik
coderxy
158 天前
@lesismal grpc 可以直接动态的完成 client 调用,grpcurl 可以看一下,grpc 协议也不是跟 protobuf 强绑定了,也可以用 json 作为编码格式。 链路追踪很多时候是用来记录 io 操作的,所以 redis mysql 等也会被记录进来,在开发和线上排查问题特别好用(例如线上一个接口比较慢,但看不出哪里阻塞的,链路追踪可以一眼看出症结)。 还有,绝大多数大一点的公司都有 api gateway 这一层的,它能做很多事情(接口配置、鉴权、限流、灰色发布、流量染色、数据清洗、编排等等等等),只不过目前你们还没感受到罢了。

技术,简单的场景有简单的方案,复杂的场景有复杂的方案。 我个人认为,技术人员,不应该让自己抵触某种技术,毕竟不会跟会但是不用是两码事。 至少面试的时候别人会让你回答怎么造飞机。
zl8723
158 天前
能单体就单体吧,别搞太复杂
ganbuliao
158 天前
k8s + istio
eijnix
158 天前
我最近也在搞这些东西,刚好看到这篇帖子,从楼上学习到了。
version
158 天前
@coderxy 记得是 18 年的时候.Envoy 还能勉强正常.新老节点相对稳定...那时候大部分中间件都不支持.要不就是内存泄漏要不就压力大连接不会重用...现在大部分企业多少业务会有 grpc 的遗留项目或者那班架构师还在..没办法.曾经吹得那么火..中台.GRPC.等等..都是坑
oom
158 天前
自己写一个咯
lesismal
158 天前
@coderxy #25

> grpc 可以直接动态的完成 client 调用,grpcurl 可以看一下,grpc 协议也不是跟 protobuf 强绑定了,也可以用 json 作为编码格式。

那这个开发动态的可以方便些,但是 json 也更慢了一点。
而且不管开发怎么方便,仍然是新的成本,使用 api gateway 相比于 nginx 也未必是优势。

> 链路追踪很多时候是用来记录 io 操作的,所以 redis mysql 等也会被记录进来,在开发和线上排查问题特别好用(例如线上一个接口比较慢,但看不出哪里阻塞的,链路追踪可以一眼看出症结)。

这可不只是记录 io 哦,重要的业务,也会带上业务信息,例如电商订单 ID ,可以按订单 ID 查询所有相关流程日志、快速定位问题。

> 还有,绝大多数大一点的公司都有 api gateway 这一层的,它能做很多事情(接口配置、鉴权、限流、灰色发布、流量染色、数据清洗、编排等等等等),只不过目前你们还没感受到罢了。

这些用 nginx 好像也可以搞吧?
所以这并不是我们自己感受不感受的问题,而是选型上我们就不认为这个相比于传统方案具有优势。
别说的好像不自己定制开发就活不下去了似的


> 技术,简单的场景有简单的方案,复杂的场景有复杂的方案。

咱别凭空把自己认为的优势就是优势,至少把原因讲出来,我前面抵触这种 gateway 都是带了说明的、而且是说明具体原因,而不是像你这样说大公司都有拿来背书,好像大公司有就是好的、别人没有就是不好的一样,劣币驱逐良币也好、推广力度不同造成用户数量不同的事情多了去了,所以不同的事物对比、可别拿 xxx 都在用这种逻辑来辩论、这可不是直接的因果关系啊。
当然,如果我家业务确实需要定制,那我也会去定制开发,但绝大多数团队,没必要,包括很多大公司的项目多加这一层也是画蛇添足

> 我个人认为,技术人员,不应该让自己抵触某种技术,毕竟不会跟会但是不用是两码事。 至少面试的时候别人会让你回答怎么造飞机。

不管会不会,我倒是无所谓被面试官欺负,反正习惯了自己造。至于 grpc 我到底会不会,我得说明一下。

grpc 我个人不怎么用,我用自己的:
https://github.com/lesismal/arpc
这是 benchmark 对比,但这个只是性能 benchmark ,arpc 性能还可以,至少比 grpc 强很多,因为谁叫 grpc 爹非要选 http2 做网络层呢,对于内网之间的 rpc 、http2 就显得比较多余和浪费了、直接 tcp 性能好得多:
https://colobu.com/2022/07/31/2022-rpc-frameworks-benchmarks/
不只是性能,实际使用上 arpc 还有很多便利:
比如不只是 server 之间可以用、client 也可以请求 server
比如 server 也可以直接推送数据给 client 、client 也可以只推送数据不需要 server response
比如可以做的业务类型也不限于微服务,游戏、IM 、推送各种业务都可以做
比如 arpc 不限制序列化方式,相同或者不同的 method 的每次请求都可以是不同的序列化,甚至也可以直接使用一段 buffer
中间件之类的也都支持,而且是支持两个维度的中间件:编解码、路由,用户可以自己定制、扩展更多东西

grpc 对我而言性能和易用性都太弱,复杂点的业务、功能它实现起来很麻烦
我也不只是做 web 这种相对简单的服务,所以我个人一是不稀罕用 grpc 因为性能差、二是它确实无法满足我的需求,即使用它、仍然要引入更多轮子来实现它搞不定的业务功能
因为不怎么用 grpc 、所以我也确实对 grpc 只了解基本使用而已、不像你们那样对它那么熟悉

确切地说,我不只是抵触 grpc gateway ,我连 grpc 都抵触的 😇😂
monkeyWie
158 天前
建议不要为了微服务而微服务,微服务说实话没什么用,提升了项目复杂度不说还降低了性能,做 web 开发最大的性能瓶颈基本都是在 mysql 这边,微服务唯一能解决的痛点就是大型项目多人协作问题,其它情况都是画蛇添足,不如直接 monorepo + 单体服务
lesismal
158 天前
@coderxy
即使我自己的 arpc ,我都不允许自家内部服务之间乱引入 rpc 的,能减少 rpc 调用就减少 rpc 调用,#16 里我举例子那些合理场景、或者其他一些合理的场景下才用
架构设计遵循奥卡姆剃刀,less is more ,我这个 id 也是根据 less is more 演化出来的,就不喜欢那种都没论证清楚成本与收益就随便引入更多内容到架构里的,有多少公司跟风微服务然后搞的一团糟的
uber 当年吹微服务凶,后来又发帖说试验宏服务,aws 前几个月也有个团队说把某些功能改成单体还是啥了之后各种成本降低了维护便利性提升了之类的。
我不是完全反对微服务,毕竟单体能力有限,但也就 web 娱乐圈整天搞新概念新名词然后炒作,微服务本质仍然是分布式,分布式早就有了,只是早期那个年代只有游戏行业比较注重分布式的说法因为 mmorpg 之类的游戏服务确实性能问题不好突破确实需要分布式上的很多优化,那个年代 web 的业务量还没那么性能紧缺,等到后来互联网发达了 web 服务性能瓶颈多了的时候微服务开始火起来,结果就各种妖魔化。很多中小团队根本不需要微服务、搞成微服务后基本都是软硬件成本增加、人员成本增加、维护成本增加、问题排查难度增加,这些中小团队的技术管理者都是属于盲目跟风的,自己连点架构设计能力都没有。当然,倒是学习了一些基础知识,然后对于他们去参加面试把自己忽悠进你所谓的大厂之类的有些帮助,但这仍然无法否认这个事实:他们不具备优秀的架构设计、具体问题具体分析的能力
coderxy
158 天前
@lesismal 你抵触 grpc 我觉得没问题,但你抵触 api gateway 我就无话可说了, 因为 api gateway 这个东西怎么说呢,稍微大点的公司里面都有的,它是证明了自己的价值的。 还有,为啥要抵触呢?特别是你也是想自己做 rpc 的,更应该看一下现有的几个比较出名的 rpc 方案的优缺点,这样才能集大成于一体,而不是闭门造车,不是吗?
还有 grpc 用的广有一个很重要的原因是因为它名气大,适配的语言也多,遇到问题网上现成的答案也多,rpc 方案里能与它竞争的也只有 thrift ,在未公司项目做技术选型时选择一门成熟的、名气大的、适配语言多的、社区活跃的也是一个很重要的原因,它能帮你规避很多坑。
能自己手撸 rpc 协议乃至 7 层协议的很多,不稀奇,但是在微服务领域,一般除非是顶尖大厂(顶尖大厂为了规避法律风险、漏洞等未知风险、极致性能等原因),绝大多数都是用现成的,因为好维护、组建团队都比较方便。
lesismal
158 天前
@coderxy

当年造出 RPC 这个概念的人、以及 HTTP 作者,他们这些大佬本身对互联网发展做出了巨大贡献,但是单就这俩玩意而言,造成了很多开发者对网络只知道或者只会用 request-response 这种模式。
而实际业务种这种单一的 request-response 模式无法满足复杂需求。网络交互本质就是相互发数据,对于 client 、server 两个点而言,就是 c->s 和 s->c 两个方向,发数据也不一定要对方响应,不需要回复可以叫 notify 或者 push 、只发不收,需要响应的可以叫 request and response 。
2 个方向*是否响应 2 种=4 种交互,但 RPC 和 HTTP 都只搞了一种,HTTP2 的 stream 都是后话了、而且使用方式仍然局限。

arpc 本质上其实不是 RPC ,而是更广义的网络交互库,支持 c->s 和 s->c 两个方向上的 notify 和 request and response ,就是相当于上面说的 2*2=4 种交互,所以能用来实现各种业务。

对比之下,传统的 RPC 框架,模式局限、也主要是 server 之间的,用起来感觉就像是被阉割过、老觉得裤裆一紧。
所以,我是真的不喜欢那些传统 RPC 框架,太弱太难用了,可能 web 圈主流只有这些所以你们只能用这些吧。。。
tangtang369
158 天前
grpc 我之前也用 后来我为啥不用了
我的 mac 执行了一次 brew update 后问题就来了 版本升级了 新版本生成的文件兼容不了老版本
coderxy
158 天前
@lesismal
比如不只是 server 之间可以用、client 也可以请求 server
-你这个指的是 grpc 编译生成 client?
比如 server 也可以直接推送数据给 client 、client 也可以只推送数据不需要 server response
-grpc 的双向数据流模式
比如可以做的业务类型也不限于微服务,游戏、IM 、推送各种业务都可以做
-grpc 一样做吧,这个业务场景跟协议没啥关系。IM 都可以用 grpc 的双向数据流模式写,如果你想的话。
比如 arpc 不限制序列化方式,相同或者不同的 method 的每次请求都可以是不同的序列化,甚至也可以直接使用一段 buffer
-grpc 的自定义编码集
中间件之类的也都支持,而且是支持两个维度的中间件:编解码、路由,用户可以自己定制、扩展更多东西
-grpc 的 Interceptor?

或者这么说吧,正常大家能想到的常用的场景,grpc thrift 这种级别的项目基本上都已经有了,都不用想的。 所以,切勿闭门造车。
lesismal
158 天前
@coderxy #34
不是 100%的纯抵触,而是,用它和不用它对比之下,它可能没有带来真正的优势。只有在我确认它能带来提升的时候我才会去搞它,OP 这种场景,我觉得没必要,甚至即使改造成微服务,如果数据量不是很大,我都不建议在微服务中引入任何 RPC 。
因为相比于直达、RPC 是纵向链条新增了一层,新增一层对于开发、维护、问题排查,就新增了一个复杂度,这个复杂度可能不是+1 ,而是+N 。
coderxy
158 天前
@lesismal 兄弟,你说的这个就是 grpc 的双向数据流模式啊,你去看看文档吧。。唉,闭门造车说的一点不假。 你这要是跟别人技术交流的时候这么讲,就要被人喷了。
darklost
158 天前
consul 挺不好用的 可能我用的姿势不对
更喜欢 ETCD

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1001257

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX