中间件技术与实践
前端技术
后端技术
技术分享
看到的世界
✨dubbo与grpc详解以及跨语言调用方案
type
status
date
slug
summary
tags
category
icon
password
序言:
在程序开发时,尤其是后端,在微服务场景下会有很多的跨服务调用场景。在之前spring cloud的时候大家一般使用的是feign。不过在spring cloud alibaba后,springboot+dubbo的方式开始流行起来。各个服务之间通过dubbo的方式进行rpc调用。本文将会叙说我理解的rpc以及各个框架之前的优缺点选型以及坑和扩展,并在最后使用实际代码展示跨语言调用。以供大家参考。
什么是RPC
rpc即remote procedure call 远程过程调用。网络上很多文章喜欢对他做一系列的定义与长篇大论的描述,甚至拿他和REST去做比较。但在我看来,他只是一个想法,即调用其他节点的程序像调用本地程序一样。
在我看来他和其他的协议没有对比性,因为他是一种思想而不是一种协议。在此思想上进行落地的grpc、feign、dubbo等协议层,有实质性产物的,可以进行对比。
Spring Cloud Feign
首先我们先看下官方文档是如何描述的
Feign是一个声明式 Web 服务客户端。它使编写 Web 服务客户端变得更加容易。要使用 Feign,请创建一个接口并对其进行注释。它具有可插入注释支持,包括 Feign 注释和 JAX-RS 注释。Feign 还支持可插入编码器和解码器。Spring Cloud 增加了对 Spring MVC 注释的支持,并支持使用HttpMessageConverters
Spring Web 中默认使用的注释。Spring Cloud 集成了 Eureka、Spring Cloud CircuitBreaker 以及 Spring Cloud LoadBalancer,以便在使用 Feign 时提供负载平衡的 http 客户端。
通过这段描述,我们可以知道,首先Feign底层是基于http请求的。他的负载均衡是根据http地址进行的负载,其次Eureka是其集成的注册中心。通过spring 提供的这些框架我们能够很快的搭建起springboot的微服务工程。不过也正是因为他底层是http请求的,并且默认是http/1.1版本,所以他的性能不是很好。详细了解可以看下面这个文档,本文不做赘述。
HTTP/1.1 VS HTTP/2Spring Cloud Alibaba
说alibaba之前,我们先说下为什么spring cloud会有多个版本。spring从创立之初开始,目标就不是重复造轮子,而是整合现有框架让开发人员更容易的开发而已。而spring最开始选择的粘合框架则是Netflix全家桶,其中Eureka、Ribbon、Hystrix等框架其实底层都是netflix的。spring只是做了封装与集成而已。但是由于netflix宣布停止更新后,spring就应该另谋生态了。
而此时alibaba为了推广自身,开发了一套微服务架构,其良好的社区与版本维护使得当下再进行微服务构建时大部分都会选择alibaba了。
而Dubbo,正是该生态下的rpc框架
Dubbo
与feign不同的是,dubbo底层并没有使用http1.1,他是支持多协议的,例如dubbo、gpc,tri等。还是让我们先看下官方的描述
Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用 Dubbo 提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。Dubbo 被设计为高度可扩展,用户可以方便的实现流量拦截、选址的各种定制逻辑。
通过官方描述,基本上我们就能知道了,他其实是支持多语言的。理论上只要我们使用同一种协议,其实是可以通过暴露的端口号从而进行跨语言调用的。其次dubbo支持非常多的协议类型。让我们再看下官方的描述
Dubbo 框架提供了自定义的高性能 RPC 通信协议:基于 HTTP/2 的 Triple 协议 和 基于 TCP 的 Dubbo2 协议。除此之外,Dubbo 框架支持任意第三方通信协议,如官方支持的 gRPC、Thrift、REST、JsonRPC、Hessian2 等,更多协议可以通过自定义扩展实现。这对于微服务实践中经常要处理的多协议通信场景。 Dubbo 框架不绑定任何通信协议,在实现上 Dubbo 对多协议的支持也非常灵活,它可以让你在一个应用内发布多个使用不同协议的服务,并且支持用同一个 port 端口对外发布所有协议。
看到这我不禁感叹,dubbo真是太强大了。他的融合观念,让各个协议生态不再割裂,都可以通过它这个中转站来进行解析。下面将介绍一下我最常用的两种协议。
gRPC
grpc是google基于HTTP/2开发的通信协议。他允许我们通过编写.proto文件,之后使用proroc编译器以及各个语言的插件,例如gen-es gen-go等来生成对应语言的代码。与Dubbo不同gRPC是存粹的RPC框架,并不会参与微服务治理。所以选择Dubbo+gRPC是非常好的选择。
Triple
Triple是Dubbo3新推出的协议,它基于HTTP/2开发并且完全兼容gRPC,这意味着,我们可以在Dubbo中设置tri协议,来监听gRPC客户端发出的内容!这相对于http调用有更大的提升。并且对于跨语言rpc调用来说提供了更便利的方式。此外Triple还不止这些,Triple可以同时运行在HTTP/1 HTTP/2的传输协议上,允许客户端通过curl、浏览器的方式直接访问后端dubbo服务。这说明在未来,前后端调用的方式可能再也不是restful了!!!!
通过grpc方式,使用python语言调用java dubbo接口实现跨语言调用
下面是一个小例子,用来展示dubbo的Triple协议强大之处。我将会使用python语言,通过gRPC直接调用java的Dubbo接口。
首先我们需要编写grpc的.proto文件
通过protoc生成py与java代码
python可以在控制台通过命令实现
这里需要我们安装grpc_tools,通过pip3 install即可
代码生成后,我们会在./gen 路径下看到两个文件
RemoteService_pb2.py RemoteService_pb2_grpc.py
其中grpc后缀的代码负责客户端请求,不带后缀的则是我们定义好的类型。我们可以根据自己的逻辑调用其他的grpc/triple服务。下面是调用代码
java我们可以通过使用maven引入grpc插件来实现代码生成,以下是maven的配置
如果你使用的是IDEA,那么你可以通过maven图形化界面来生成代码,也可以通过mvn命令来生成
代码生成后,因为maven中我们选择了Dubbo的插件,所以会生成DubboXXXTriple的java类。通常只需要我们在写一个具体的实现类,注释上@DubboService,并且继承生成的Triple类即可。
接口配置完成启动spring boot即可。
服务调用
上述的代码配置完成后,双方服务启动即可进行调用。不过需要注意的是,如果进行跨语言调用,protobuf的Any类型如果存放的是java自身的类,python中会无法反序列化并且向下转型。即使向上转型时使用的类是proto文件中定义的,python中也无法向下转型。
所以,尽可能的不要进行转型。
Loading...
Last update: 2024-08-17
🎉个人博客独家爆料已上线🎉
--- 感谢您的支持 ---
👏这里没有复杂的概念👏
🤔这里有认真的思考🤔
🤖您可以通过评论表述不同的意见🤖
🦄所有回复都会以邮件的形式通知您🦄
😎让我们积极讨论,共同进步😎