Dubbo大白话系列-服务暴露的本质

604

前言

在我不了解一项技术时,我特别痛恨技术文档里那些故弄玄虚的词,因为他会打击我学习的积极性 。在我掌握了一项技术后,我发现他们都是纸老虎 。在我深入理解一项技术后,我发现这些词并不是在故弄玄虚,因为没有比它更简洁的表达。这个系列会用最白话的方式来阐述dubbo里的方方面面

1. 什么是服务暴露

先来看一段 dubbo provider 的配置

<bean id=“xxxService” class=“com.xxx.XxxServiceImpl” /> //spring 中一个普通的java bean
<dubbo:service interface=“com.xxx.XxxService” ref=“xxxService” /> //将spring中普通的java bean 转化为dubbo provider

这是一段很常见spring dubbo 配置(基于注解、API编程也是等价的),在很多分析dubbo原理的文章里,在分析这段配置背后的逻辑时,经常会蹦出来一个词 —— 服务暴露

2. 用大白话解释下 “服务暴露”

先允许我把你们当做刚入门的小白,我们先从源头说起 ……

本地方法调用 vs 远程方法调用(RPC)

public class Test {
    @Autowired
    UserService userService ;
    
    public void addUser(){
        User user = new User();
        userService.addUser(user); 
    }
}

这是一段很简单的代码吧,userServiceaddUser 方法负责增加用户

那么请问 userService.addUser(user); 这行代码中的 userService 对象是在哪儿呢? 有可能就是在当前JVM 堆里,也有可能他只是个傀儡,真正的执行是在远程,比如在美国的一台电脑上

如果userService就是在当前JVM里,那么这行代码就是最普通的调用——本地方法调用

如果userService真正的逻辑执行是在远程,本地的只是个傀儡,那么这行代码就是远程方法调用

dubbo 里的方法调用方式就是这一类RPC远程调用,比如: userService.addUser(user); 如果这里的 userService 是dubbo 的consumer ,那么本质上userService就是个傀儡,真正 addUser(user) 这个动作是要在远程执行的

本地的dubbo consumer 执行 userService.addUser(user); 的时候,首先会收集所需的各种信息(userService 这个class, addUser 方法,user对象信息等),在把这些收集到的信息序列化成 byte 字节流,userService 这个傀儡会负责把字节流通过网络传输到远程,远程收到这些信息后,会反序列化还原这些信息。于是乎远程那个真正的userService就知道要去调哪个类的哪个方法,入参是什么等,远程就真正执行 addUser(user) 这个逻辑

问题的出现

看完上面一段叙述,突然发现一个问题: 本地的userService 这个傀儡怎么知道这个所谓的 远程 在哪里啊?最起码他要知道远程的 ip地址和端口号吧,不然怎么发起网络连接呢,怎么传输收集到的字节流呢?

一个最简单的思路 ,首先远程那个真正的userService需要把自己暴露给外界他需要在远程监听一个ip、端口号,然后把这个ip、端口号放到一个公共的地方(所有人都能访问),这样本地的傀儡在发起网络连接的时候,可以先到这个公共的地方查一下,根据查到的ip、端口发起网络连接

3. 暴露的本质

综上,得出暴露的本质就是: dubbo provider端监听一个ip、端口号,并注册到公共地方(zk)

知道这个本质了,看源码还不简单么,下一篇带你一起读源码