Dubbo 的设计思想,真优秀!
点击关注公众号,Java干货及时送达
作者:叁滴水
博客:https://blog.csdn.net/qq_30285985/
本文来自作者「叁滴水」投稿,谢谢分享,也欢迎爱好技术分享的各位技术朋友向「Java技术栈」投稿,让更多人看到,投稿方式:关注公众号「Java技术栈」在后台回复:投稿。
起源
如果在一个项目中有两个service
。userService
和orderService
。我们想要其中一个service调用另一个。
![](https://filescdn.proginn.com/2c2606af10147b053760c67de2c6b8fc/93fec9b043549ae3bc4be154224012ac.webp)
public class userService{
private orderService orderService;
public User getOrder(Long orderId){
return orderService.getOrder(orderId);
}
}
随着业务的逐渐复杂,在开发中肯定会有业务拆分。初步是通过maven进行模块的拆分。
![](https://filescdn.proginn.com/dd035f279e036ea3d8f31b68dfdaee66/c035e81e9a3c31ff5a1a929490032e6b.webp)
不管maven如何拆分,都始终是在一个jvm中运行, 这样只是在代码开发时会清楚方便一点。但是,某一个service
在有较大压力的情况下,没有办法单单对此service
做出调整。最终,我们是想要userService
和orderService
在不同的jvm中运行,如果orderService
访问较多,我们可以只对它进行扩容。
如下图,才是我们最终想要的方案,对于这种方案,orderService
端,我们称之为服务提供者,调用orderService
的端,我们称之为服务消费者。这种思想,也为dubbo的出现埋下了伏笔。
![](https://filescdn.proginn.com/a4d775fcd695102c190290e6b8c32e4f/dfcd45dcca5642d9fea27d79984de2b6.webp)
jvm的userService如何调用orderService呢?
在java远程调用多年的沉淀,一个接着一个框架的出现,在一点点的优化这个调用的过程。Java 核心技术教程和源码已上传:https://github.com/javastacks/javastack
首先是socket调用。在orderService
中开放socket服务,在userService
中进行远程调用。
优点:解决了单机调用的问题。 缺点:代码复杂,不易于扩展。
这可能是最初的一个远程调用解决方案,笔者不曾遇到过纯socket调用的框架。另外,Dubbo 系列面试题和答案全部整理好了,微信搜索Java技术栈,在后台发送:面试,可以在线阅读。
如何跨语言调用?
我们发现,在java的对象是不可以直接通过socket进行传输的,需要有一个序列化的过程。而且java的默认的序列化,是无法被其他语言解析的。这样导致如果有其他语言提供的服务,是无法通过java调用。因此对于socket进行了升级,通过http+xml
进行信息的传输。这就出现了webservice。
Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。
Web Service虽然早期很多人使用,但是到现在看来,这是一种过时的框架。因为,同样的一些数据,通过json会比xml少很多。通过json会更少的占用带宽。如下面数据。
{
"id": 12312,
"userName": "12312"
}
<id type="number">12312</id>
<userName type="string">12312</userName>
http协议是应用层的一种协议,对于开放给外部系统时,是一个很好的选择,它可以实现跨语言调用。如果是自己的java服务内部调用时,使用http协议,就有点浪费资源。
![](https://filescdn.proginn.com/d4eb97f8909fba616b7e6fb5a95b2843/6342925935d3e7847cac4c8b4f741ebb.webp)
如上图,http协议在交互之前需要进行tcp三次握手,握手成功之后进行数据传输。一个http交互下来,有请求头、请求体、响应头、响应体。这些数据,在内部调用时,很多无关紧要的数据。也许可以自定义协议,简化传输数据。这就出现了dubbo协议,一种内部调用的协议。
dubbo协议追求的是数据量小,小则快,协议的设计也符合dubbo框框架的理念,适用与内部服务之间的数据交互。安全性就没有https做的那么好,但是也不需要,毕竟dubbo协议设计的初衷就是内部使用的。
![](https://filescdn.proginn.com/2e3e7b06013e7f0cff6c16727aa5832d/507790713490ae0029160df9c749ec9d.webp)
spring cloud的feign组件内部使用http协议,内部调用可能有一些资源的浪费,但是http协议可以实现跨语言调用。
RPC框架
对于一个RPC框架来说,只是能完成远程调用,并不算完美。
![](https://filescdn.proginn.com/e3138e0d0b2560da8a442113b03562bc/8bb13aa543718a2ee1a1eccc276c4d3b.webp)
一般开发一个服务需要多个机器进行部署,为了防止出现单点故障。对于一个较为完善的RPC框架来说,在多个机器提供同样的一个服务的时候,需要自动做出选择。好比上图,userServuce
在调用orderService
的时候,需要自动识别集群信息,并且自动选择机器进行调用。
目前,orderService
只有一个服务,三台机器,也许可以在userServuce
中配置三个ip,然后自行编写路由规则即可。但是随着业务的复杂,机器的变化,也许,我们起初无法得知机器的ip信息。
![](https://filescdn.proginn.com/64bc108694827d0990f23f5fa89123dd/71d398028835188aa6112dff3868d357.webp)
为了实现动态的机器添加与移除。最终,添加了一个机器的协调者,所有开放服务的机器在这个协调者中添加自己的开放服务的信息,这个协调者中会有哪些机器开放了哪些服务。这样看来这个协调者类似一个"通讯录"。我们称这个"通讯录"为注册中心。
这样一个较为完善的RPC框架,就有了雏形。
服务提供者启动之后向注册中心,提交自己提供服务的信息。 服务消费者,在消费时,去注册中心查询是否有机器提供对应的服务。例如调用 orderService
时,可以发现有192.168.1.1
和192.168.1.2
机器有提供对应的服务。消费者可以根据随机、轮训等规则选择调用哪个服务。在有服务上线或者下线时,注册中心可以对修改的信息进行通知。
这样一套流程下来,就完美的实现的服务的动态部署,可以任意部署服务。
作为协调者的注册中心,占据着一个重要地位。这样来看,注册中心主要实现了临时数据存储的功能。可以有多种选择数据库、redis、zookeeper、eureka、nacos、或者自己实现。
期初dubbo框架官方推荐使用zookeeper为注册中心,出现nacos之后,逐渐从zookeeper转为nacos。
其中的原因有很多,有兴趣的小伙伴可以微信搜索Java技术栈在历史文章中搜索阅读。
为什么zookeeper转为nacos?结论为:zookeeper在大数据计算时做注册中心是一个好的选择,但是在服务调用时,也许数据不需要超强的一致性。nacos是目前来说很友好的一个注册中心,他提供了CP+AP
。还有可视化界面,还有配置中心等功能。功能相当完善。
springcloud与dubbo的历史
笔者不才,在17年时,这两个词才进入我的视线。当时还有一个超级火的springboot。那个时候招聘,几乎每个岗位都要求会springboot。分享:Spring Boot 学习笔记。一时间,成为了一个java开发的必备功底。
Spring Boot 基础教程可以看这个,教程和源码非常全:https://github.com/javastacks/spring-boot-best-practice
由于springboot在大大开发了开发的速度,而且springcloud的各个组件都比较完善,feign、网关、配置中心、熔断等等。spring、springcloud和springboot明显是一家人。这让一个孤身的dubbo有点不好立足,一些公司从dubbo框架转为springcloud全家桶。
2018年7月份,eureka停止更新。就目前来说eureka的功能单单作为注册中心,已经足够优秀了。但是对于节奏如此快的互联网时代,停止更新,就意味着会慢慢的消失。
2019 年 7 月 24 日晚,Spring Cloud 官方发布公告Spring Cloud Alibaba 即将毕业。提供了很多组件,对于大部分开发者而言,nacos、dubbo、seata
应该是较为常用的组件。
nacos:注册中心。 dubbo:一个基于Java的高性能开源RPC框架。 seata:一种高性能且易于使用的分布式事务解决方案,可用于微服务架构。
nacos
是一个新推出的注册中心,其中最亮眼的功能是提供了可视化界面,而且还附带配置中心。瞬间dubbo就找到了家人。这些组件的出现让dubbo又崛起了起来。而且dubbo本来扩展性就很好。可以进行协议扩展、调用拦截扩展、引用监听扩展、集群扩展等等。
另外dubbo3.0主力使用Triple
协议。完整兼容 gRPC over HTTP/2。推荐使用 protobuf
作为默认序列化,在性能和跨语言上的效果都会更好。
结束语
就目前来看,dubbo框架是一个目前位置非常优秀的RPC框架, 一个必须要学的一个框架。也许以后它会更加优秀,也许会落寞。但是其设计思想,非常值得开发者去学习。
最后,关注公众号Java技术栈,在后台回复:面试,可以获取我整理的 Java/ Dubbo 系列面试题和答案,非常齐全。
![](https://filescdn.proginn.com/31a693d10ffcb70b3eae9f0fffbe113a/e5a31feed92b8f708fedf4064dce2b4a.webp)
![](https://filescdn.proginn.com/88c10d9e5aafa34f31838e7eb9f10f65/d1ffccf06083c29b8f0c18f26ffb8892.webp)
![](https://filescdn.proginn.com/d20390477f4dddeaa2d29e00e60711d7/ce43d654e3eb8d8a27d89dd043cd48ce.webp)
![](https://filescdn.proginn.com/2841f8b6b166f1b579f098355a80e873/8e3c1de372194fb806972cc6e625987c.webp)
![](https://filescdn.proginn.com/71b791ad9c1b982b6598e97148d7eccc/1ca6ddff258bdd1b5eafb666d9c0b1c5.webp)
关注Java技术栈看更多干货
![](https://filescdn.proginn.com/fdcd7d19328c43177e7f90745bb59fad/d276df2b867f6d896ba2d84710c01674.webp)