Go GRPC 实战入门系列


在前面 4 章我们已经从零开始编写了 Grpc 的服务端和客户端,并且还加上了认证功能以及客户端失败重试等特性。在第 3 篇和第 4 篇我们都是介绍如何使用 Interceptor 的,但是我们也仅仅是使用,在使用完前面的 Server 端和 Client 端的 Interceptor 之后,可能很多同学已经迫不及待得想知道 Interceptor 要怎么实现了,并且已经有了好几个自己想实现得 Feature 了。是的,我了解的,因为我刚看到的时候也是激动不已,恨不得马上重构一波,实现几个自己的 Interceptor,然而玩着玩着发现已经有很多现成的实现了,还需要自己写?

但是,无妨,既然现在还没有很恰当的时机来实现,不妨先看一下怎么实现呗,万一哪天就用上了呢?或者哪天别人的 Interceptor 暴 Bug 了,我们还是知道怎么定位的嘛。

在开始介绍如何实现之前,还是要知道一个前提的,那就是 Interceptor 是有分类的,可以横向纵向分为 4 类,这么看:

unary stream
server client

这里虽然还没有介绍 Stream,但是没关系,先记住它就好了,所以这里需要考虑这几种情形,但是,原理上都是一致的,所以我就以其他一个作为示例,就不纠结所有都示范一遍了。

这里我的目标是自己实现一个 Dump 请求和响应的 Interceptor,这个可能在我们 Debug 的时候有点用处,但是我不准备上来就写代码,不妨先来看看 GRPC 的文档,看下有什么好说的,我就挑 Server 端的 Unary 来看吧:

可以看到,在 GRPC 的定义中,这里所谓的 Interceptor 其实就是一个函数,那么这个函数是怎么用的呢?我们找一个用过的例子来看,就找之前 Server 端验证 JWT 的 Interceptor 吧,打开一看:

好,原来这里新建的 Interceptor 就是返回了一个函数,然后在函数内部进行判断,如果正常了,那么就调用业务处理函数,否则,那么就直接返回错误了。

那么这里我们就可以仿照着写一个:

写完之后,在自己的 Server 中试用一下,看看效果怎么样:

然后运行一下,我这里看到的出是:

看样子是正常运行啦,而且客户端也是正常响应的。但是,当我和前面介绍过的 Interceptor 进行集成的时候,问题就出现了,如何同时试用多个 Interceptor 呢,因为从我们的 Interceptor 的实现来看,明显这就是只能存在一个 Interceptor 的情况。

这个时候,我们来回顾一下之前是否有过多个 Interceptor 的情况,回顾了一圈,没有发现,所以这个时候还是应该回到之前使用过的 Repo 中查看一下,看他们是如何解决这个问题的,当我打开 Grpc-ecosystem 的 Repo 的时候,一切都这么自然,人家就放在 README 里面:

这里它将所有的 Interceptor 封装成了一个 Chain,所以我还需要看下 Chain 是怎么实现的,顺便看看我现在的实现能不能满足它的要求:

这么一看,我去,原来 Chain 是这么玩的,那这么一看就知道了,我们写的这个 Interceptor 不用做任何就可以直接使用了,并且,我们也可以看到,Chain 的执行顺序是根据注册顺序,从上到下注册的。

OK,本文就是关于 Interceptor 的介绍了,虽然只是介绍了 Server 端的实现,但是,对于 Client 端来说也是一样的,可以参考用过的一些实现来编写,这些都是很简单的啦,不过就是需要注意到一些业务上的处理,例如重试 Interceptor 中的是否幂等这些。