-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
如何在 Node.js 中更优雅地使用 gRPC:grpc-helper #86
Comments
好东西,感谢 @xizhibei 兄弟分享。学习了! |
有个问题,grpc服务端和客户端都需要知道protocol buffers接口结构,如何保证两端protocol buffers接口结构统一呢? |
不过,还是不确定你想问什么,给我点上下文? |
以 我也是最近才看 nodejs 的 rpc,看到 grpc 后才知道 protocol buffer,可能问的有点小白 请见谅 |
这是必须的,客户端的更新特性决定了它的数据结构不能完全跟服务器同步,服务器需要对客户端的协议进行兼容。在不兼容的场景下,两边为了保证数据不丢失,服务端需要先更新,同时兼容旧协议,然后等待客户端更新后才能把旧协议删掉。 其实你问的更像是个协作问题,而不是技术问题,因为即使你用 RESTful API 也会这样,两边必须要通过沟通(口头、文档等)来进行同步。 两边分开的弊端就会增加沟通成本,这没有办法,要么两边进行磨合,以后协作起来更默契,要么进行全栈开发,一个人都开发客户端与服务端。 |
请问我想在metadata里传值怎么操作呢 |
另外,目前官方已经放弃 grpc-node 了,你需要试试新的了:https://github.com/grpc/grpc-node/tree/master/packages/grpc-js 。 |
在上一篇的 gRPC 的介绍以及实践 中,而在文末,我简单介绍了给 Node.js 做的 grpc-helper,但是现在,我觉得得用一篇完整的博客来好好介绍,毕竟还是想要给大家用的,以下我会介绍我实现这个工具的过程,以及我的一些实现思路。
其实在这之前,我看了官方的讨论,而且也调研了当中提到一些帮助类工具,比如 grpc-caller,因该说我不太喜欢这种 API风格,不够简单明了,并且也没有我想要的一些高级功能。
另外就是 rxjs-grpc 了,只是它是基于 RxJS 来做的,如果你对它不熟悉,怕是也难以选择(当然,可以了解下,号称是可取代 Promise 的)。
因此我想了想,除了最重要的 Promise API 功能(毕竟 callback 的风格早就应该被淘汰了),我想要的功能主要有:
好了,相信你也应该看出来了,我想要的无非就是负载均衡加上 Promise API,因为上面的几点都是一个负载均衡器应该做的事情。
实现的话,还是用 TypeScript,不明白的可以看看我之前的介绍:使用 TypeScript 开发 NPM 模块。
Promise API
于是首先是需要提供一个非常简便的 Promise API 接口,我们都知道 grpc 以客户端以及服务端是否使用了流分成了四种风格的接口:
而在这四种接口中,只有 Unary 以及 Client stream 有返回值 callback 风格的接口,这从设计上也符合一致性的风格,只是我们不喜欢用而已。
因此,一开始,我是这么设计的:
将 callback 风格的
变为
但是我忽略了服务端返回的 status 以及 metadata,应该说大部分情况下,只是 response 就能满足大部分需求,但是我做的是一个比较基础的库,那就应该提供完整的功能,于是,我加入了下设计:
变为
这样也就非常简单明了了,实现起来也不难,我同时提供了
resolveFullResponse
参数,默认为 false,这样,大部分情况下,如果不需要 status 之类的返回值,只需要第一种设计,那基本上也不需要改动参数。同时,我还参考了 @murgatroid99 在官方讨论中的设计,将 Client stream 接口也改成了 Promise 风格的接口:
负载均衡
应该说这是一个现代的负载均衡器应该做的事情,我参考了 grpc-go 的设计,引入了 Resolver Watcher 以及 Balancer 几个抽象接口。
而在上次的文章中,我也提到了 grpc-node 中,现在还没有实现负载均衡能力,而且它目前的实现,还不能很方便的提供给我们很方便定制这个功能的接口,于是,目前能做的便是直接给每个服务端生成一个 client,然后在这个基础之上进行负载均衡的实现。
于是,最初的设计是:
但是显然这样不够简便,于是我直接在 helper 的 constructor 中加入了这些方法,使得初始化之后直接将方法绑定到 helper 上面:
于是,我们最终的 API 就很简单了:
其它的负载均衡功能限于篇幅不再详细介绍,可参考源码实现。
其它功能
主要是监控指标以及全局 deadline,我直接使用了 grpc-node 提供 interceptors,拿监控指标举例:
你也可以根据自己的需求,禁用默认的监控指标,创建 helper 的时候将
metrics
设置为false
,然后将自己实现的 interceptors 传入 grpcOpts 即可:总结
好了,总体来说,这个工具的实现不复杂,但是需要花费挺多精力去具体实现,同时我也觉得如果不在这里给这个工具好好宣传一下的话,很容易就会变成只有我自己使用的一个工具,一些问题也不会发现,工具本身也无法进一步发展。
同时,我也相信,我这个工具最终会被官方的功能所取代,但是如果官方能够采用或者参考我的设计的话,那也是不错的结果。
另外,工具现在正在我们的测试环境中使用,正式环境也有部分在使用,所以各位如果有机会也不妨试试。
最后,给个 Star 也是极好的 :P 。
The text was updated successfully, but these errors were encountered: