「小得101」REST 和 RPC 哪个更好?
在微服务架构下,必须要选择一种进程间服务通信的具体技术,流行的的做法是使用HTTP/JSON方式的REST或像Dubbo这样的私有协议/二进制的RPC框架,那到底REST和RPC哪个更好呢?
相对来说,REST更加简单、标准和开放,有着更丰富的生态,在运行时有SpringCloud这样的框架的支持,开发过程中有POSTMAN,Swagger等众多的工具可以使用,在《微服务设计》里,也用很大的篇幅在阐述,在服务之间,REST 方式的服务依赖要比 RPC 方式的依赖更为灵活;RPC的优点是有更好的易用性和性能。
易用性
就易用性来说,REST也许并不比RPC差很大,首先可以通过Swagger的文档生成客户端STUB的,其次,使用Feign这样的类库也可以大大简化客户端的使用,另外,由于HTTP协议本身和payload是基于文本而不是二进制的特点使得REST更容易调试。最近,我觉得REST也不比RPC难用的一个原因是我在尝试使用DDD的设计方法构建微服务,在DDD里,推荐下游要有一个防腐层(ACL),如果要构建ACL的话,RPC的易用的优势几乎就没有了。而使用使用[Feign][feign]反而是一种更自然的方式。
一个feign的例子防腐层(Anticorruption Layer):对于下游来说,需要根据自己的领域模型创建一个单独的层,该层作为上游系统的代理向你的系统提供功能。它在你自己的模型和他方模型之间进行翻译转换。
性能
那么REST和RPC相比性能到底差多少呢?
有人对Spring Cloud和Dubbo和做了性能测试,得出的结果响应时间基本上是三比一,这在一般情况还是可以接受的。
也有测试显示gRPC整体表现要比Dubbo要好,而gRPC使用的协议是HTTP2,那么如果REST使用HTTP2协议的话是否可以缩小和RPC之间的性能差距呢?
这就要明白为什么REST更慢的本质原因了。其实慢的原因主要是序列化和反序列化JSON/XML要比Protobuf慢很多。
REST服务的payload也不一定就非得是XML或JSON格式的数据,其实也可以是Protobuf,可以参考 《Spring REST API with Protocol Buffers》 这篇文章尝试将Protobuf用于REST了。
结论
如果性能不是问题的话,用REST的比RPC会更合适。BOB大叔的《整洁架构之道》里提到,想这些通信框架其实是实现细节的一部分,那是不是可以做到我可以低成本切换这些这些实现细节呢?我觉得是有可能,比如上面说的把Protobuf用于REST,或者现在阿里云上使用SpringCloud开发的应用在部署后可以选择是REST还是云平台提供的HSF这样的RPC框架了。你可以在开发环境用标准的REST,在运行时部分或全部使用一个RPC框架;或者在早期用REST,在遇到瓶颈时切换到RPC。
总之,对系统架构来说,很多情况下,细节并不重要。绝大多数情况下,决定成败的不是细节,而是细节可不可以被替换。
参考
-
Dubbo VS Spring Cloud性能测试大对决! http://www.cnblogs.com/chen110xi/p/6349580.html
-
分布式RPC框架性能大比拼 http://colobu.com/2016/09/05/benchmarks-of-popular-rpc-frameworks/
-
Is gRPC(HTTP/2) faster than REST with HTTP/2? https://stackoverflow.com/questions/44877606/is-grpchttp-2-faster-than-rest-with-http-2?noredirect=1&lq=1
-
Spring REST API with Protocol Buffers](http://www.baeldung.com/spring-rest-api-with-protocol-buffers
关注我