无缝连接 dubbo-go 与 gRPC
最近我们dubbogo
社区里面,呼声很大的一个feature
就是对grpc
的支持。在某位大佬的不懈努力之下,终于弄出来了。
今天我就给大家分析一下大佬是怎么连接dubbogo
和grpc
。
grpc
先来简单介绍一下grpc
。它是google
推出来的一个RPC
框架。grpc
是通过IDL(Interface Definition Language)
——接口定义语言——编译成不同语言的客户端来实现的。可以说是RPC
理论的一个非常非常标准的实现。
因而grpc
天然就支持多语言。这几年,它几乎成为了跨语言RPC
框架的标准实现方式了,很多优秀的rpc
框架,如Spring Cloud
和dubbo
,都支持grpc
。
server端
在go
里面,server
端的用法是:
它的关键部分是:s := grpc.NewServer()
和pb.RegisterGreeterServer(s, &server{})
两个步骤。第一个步骤很容易,唯独第二个步骤RegisterGreeterServer
有点麻烦。为什么呢?
因为pb.RegisterGreeterServer(s, &server{})
这个方法是通过用户定义的protobuf
编译出来的。
好在,这个编译出来的方法,本质上是:
也就是说,如果我们在dubbogo
里面拿到这个_Greeter_serviceDesc
,就可以实现这个server
的注册。因此,可以看到,在dubbogo
里面,要解决的一个关键问题就是如何拿到这个serviceDesc
。
client端
client
端的用法是:
这个东西要复杂一点:
- 创建连接:
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
- 创建
client
:c := pb.NewGreeterClient(conn)
- 调用方法:
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
第一个问题其实挺好解决的,毕竟我们可以从用户的配置里面读出address
;
第二个问题就是最难的地方了。如同RegisterGreeterServer
是被编译出来的那样,这个NewGreeterClient
也是被编译出来的。
而第三个问题,乍一看是用反射就能解决,但是我们打开SayHello
就能看到:
结合greetClient
的定义,很容易看到,我们的关键就在于err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...)
。换言之,我们只需要创建出来连接,并且拿到方法、参数就能通过类似的调用来模拟出c.SayHello
。
通过对grpc
的简单分析,我们大概知道要怎么弄了。还剩下一个问题,就是我们的解决方案怎么和dubbogo
结合起来呢?
设计
我们先来看一下dubbogo
的整体设计,思考一下,如果我们要做grpc
的适配,应该是在哪个层次上做适配。
我们根据前面介绍的grpc
的相关特性可以看出来,grpc
已经解决了codec
和transport
两层的问题。
而从cluster
往上,显然grpc
没有涉及。于是,从这个图里面我们就可以看出来,要做这种适配,那么protocol
这一层是最合适的。即,我们可以如同dubbo protocol
那般,扩展出来一个grpc protocol
。
这个grpc protocol
大体上相当于一个适配器,将底层的grpc
的实现和我们自身的dubbogo
连接在一起。
实现
在dubbogo
里面,和grpc
相关的主要是:
我们直接进去看看在grpc
小节里面提到的要点是如何实现的。
server端
这样看起来,还是很清晰的。如同dubbogo
其它的protoco
一样,先拿到service
,而后通过service
来拿到serviceDesc
,完成服务的注册。
注意一下上图我红线标准的ds, ok := service.(DubboGrpcService)
这一句。
为什么我说这个地方有点奇怪呢?是因为理论上来说,我们这里注册的这个service
实际上就是protobuf
编译之后生成的grpc
服务端的那个service
——很显然,单纯的编译一个protobuf
接口,它肯定不会实现DubboGrpcService
接口:
那么ds, ok := service.(DubboGrpcService)
这一句,究竟怎么才能让它能够执行成功呢?
我会在后面给大家揭晓这个谜底。
client端
dubbogo
设计了自身的Client
,作为对grpc
里面client
的一种模拟与封装:
注意看,这个Client
的定义与前面greetClient
的定义及其相似。再看下面的NewClient
方法,里面也无非就是创建了连接conn
,而后利用conn
里创建了一个Client
实例。
注意的是,这里面维护的invoker
实际上是一个stub
。
当真正发起调用的时候:
红色框框框住的就是关键步骤。利用反射从invoker
——也就是stub
——里面拿到调用的方法,而后通过反射调用。
代码生成
前面提到过ds, ok := service.(DubboGrpcService)
这一句,面临的问题是如何让protobuf
编译生成的代码能够实现DubboGrpcService
接口呢?
有些小伙伴可能也注意到,在我贴出来的一些代码里面,反射操作会根据名字来获取method
实例,比如NewClint
方法里面的method := reflect.ValueOf(impl).MethodByName("GetDubboStub")
这一句。这一句的impl
,即指服务的实现,也是protobuf
里面编译出来的,怎么让protobuf
编译出来的代码里面含有这个GetDubboStub
方法呢?
到这里,答案已经呼之欲出了:修改protobuf
编译生成代码的逻辑!
庆幸的是,在protobuf
里面允许我们通过插件的形式扩展我们自己的代码生成的逻辑。
所以我们只需要注册一个我们自己的插件:
然后这个插件会把我们所需要的代码给嵌入进去。比如说嵌入GetDubboStub
方法:
还有DubboGrpcService
接口:
这个东西,属于难者不会会者不难。就是如果你不知道可以通过plugin
的形式来修改生成的代码,那就是真难;但是如果知道了,这个东西就很简单了——无非就是水磨工夫罢了。
欢迎加入 dubbo-go 社区
目前 dubbo-go 已经到了一个比较稳定成熟的状态。在接下来的版本里面,我们将集中精力在云原生上。下一个版本,我们将首先实现应用维度的服务注册,这是一个和现有注册模型完全不同的新的注册模型。也是我们朝着云原生努力的一个关键版本。
dubbo-go 钉钉群 23331795 欢迎你的加入。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
PHP算法:斐波那契数列的N种算法
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 前言 前段时间,遇到优化计算斐波那契数列的常规递归方法,但是一时间并没有及时想到很好的方法,所以后面查找了相关资料,总结了多种计算解法,所以分享出来,和大家一起交流学习。 斐波那契数是什么 斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)。 知道了斐波那契数,那么下面我们就用多种不同的方法来计算获取第N位斐波那契数。 普通递归 这种方法是最常规的,直接根据定义F(n)=F(n - 1)+F(n - 2)递归计算即可,但是性能是最低的。 /** * 普通递归 * @param int $n * @return int */ function...
- 下一篇
CVE-2020-9484 tomcat session反序列化漏洞分析
本文借助CVE-2020-9484 Tomcat漏洞详细的介绍了本地和远程调试Tomcat 源码。分析漏洞成因以及补丁修补情况,以及分析ysoserial反序列化链。 0x01 漏洞简介 Apache Tomcat发布通告称修复了一个源于持久化Session的远程代码执行漏洞(CVE-2020-9484)。漏洞条件比较苛刻: tomcat必须启用session持久化功能FileStore tomcat/lib或者WEB-INF/lib目录下的依赖存在可用的gadget 在服务器上存在已知路径文件内容可控 0x02 影响范围 Apache Tomcat 10.x < 10.0.0-M5 Apache Tomcat 9.x < 9.0.35 Apache Tomcat 8.x < 8.5.55 Apache Tomcat 7.x < 7.0.104 0x03 漏洞依赖条件 从官网下载tomcat 8.5.30 0x1 配置session持久化 conf/context.xml <Manager className="org.apache....
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS关闭SELinux安全模块
- CentOS6,7,8上安装Nginx,支持https2.0的开启