Dubbo的RPC测试

2021-12-22 16:25:58 浏览数 (1)

Dubbo具体由来和功能这里不做介绍了,推荐看apache提供的文档 http://dubbo.apache.org/zh-cn/index.html 这里提供一个Dubbo实现RPC功能的案例,方便大家理解。

Dubbo实现RPC

首先定义俩工程,一个功能是Dubbo的客户端远程调用,一个是服务器端的服务提供。

结构如图

其中api仅负责接口的创建,供两方使用。

下面贴上代码并介绍

api模块

提供的接口,负责供客户使用以及provider模块实现

代码语言:javascript复制
public interface ApiInterface {
    public String returnName(String name);
}

客户端使用provider模块的方法需要配置,并注册

provider模块

实现类

代码语言:javascript复制
public class ProviderImpl implements ApiInterface {
    @Override
    public String returnName(String name) {
        return "提供者方回显:" name;
    }
}

provider模块的xml配置,详细内容看内部注释。

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!--定义提供方信息,如名字,版本,定义者ower等-->
    <dubbo:application name="dubbo-server"/>
    <!--定义注册中心,N/A代表不要注册中心-->
    <dubbo:registry address="N/A"/>
    <!--配置协议、端口-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--指定对外发布的接口并链接到其实现类-->
    <dubbo:service interface="com.zyh.dubbo.ApiInterface" ref="dubboImp"/>

    <!--定义一个对外发布的实例,打包为bean-->
    <bean id="dubboImp" class="com.zyh.dubbo.ProviderImpl"/>
</beans>

加载配置文件并启动使其注册到Dubbo可供外部调用。

代码语言:javascript复制
public class Bootstrap {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("dubbo-server.xml");
        context.start();
        System.in.read();//阻塞当前进程,使提供者一直在线提供服务
    }
}

另外这里要注意一下provider模块的pom中,需要引入api模块供provider模块实现和使用,引入dubbo模块。

代码语言:javascript复制
        <dependency><!--引入被调用的api模块,使得provider模块可以实现api模块的接口-->
            <groupId>com.zyh.dubbo</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.3</version>
        </dependency>

启动后即会注册到dubbo

其中服务端启动后里面有个providers,看一下后发现其实就是一个url(把前面的乱码改成dubbo://这样) 一些协议

客户端配置
代码语言:javascript复制
public class App 
{
    public static void main( String[] args )
    {
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("dubbo-client.xml");
        ApiInterface apiInterface = (ApiInterface) context.getBean("cliRes");
        String res = apiInterface.returnName("zyh");
        System.out.println(res);
    }
}

客户端xml配置

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!--定义提供方信息,如名字,版本,定义者ower等-->
    <dubbo:application name="dubbo-client"/>
    <!--定义注册中心,N/A代表不要注册中心-->
    <dubbo:registry address="N/A"/>
    <!--服务器启动后提供的url-->
    <dubbo:reference id="cliRes" interface="com.zyh.dubbo.ApiInterface"
                     url="dubbo://192.168.106.1:20880/com.zyh.dubbo.ApiInterface"/>
</beans

客户端pom配置,dubbo毋庸置疑,还有一个呢就是我们的接口依赖库,这个可以通过idea install服务器端项目后,会有一个api依赖搞下来,就像下面的dependency。

代码语言:javascript复制
 <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.5.3</version>
    </dependency>
    <dependency><!--引入安装到本地的dubbo-api接口-->
      <groupId>com.zyh.dubbo</groupId>
      <artifactId>dubbo-api</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

客户端启动后,zk注册中心发现结点多了消费者

如果我们在客户端运行程序加了system.in.read()停一下,看看consumer发现会有消费端的地址端口维护。

总的来说看起来就是RPC了 客户端持有了一个api库,我们在provider模块对这个api库的接口方法都链接了相对的url远程地址,我们使用起来和自己调JAVA库差不多。

配置ZK为注册中心

当然Dubbo是可以自己配置注册中心的,这里我们可以用ZK配置注册中心。

服务端

首先更改配置里

代码语言:javascript复制
 <!--定义注册中心,配置zk的地址和端口->
    <dubbo:registry address="zookeeper://ipaddr:2181"/>

pom里引入zk包以及zkclient,dubbo内部封装了通过该zkclient创建结点功能

代码语言:javascript复制
 <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.10</version>
        </dependency>
客户端

首先更改xml配置,配置好zk注册中心,由于我们服务端provider模块已经对每个接口方法进行其实现类方法的关联了,因此我们就不需要自己像之前一样制定url了。

代码语言:javascript复制
 <!--定义注册中心-->
    <dubbo:registry address="zookeeper://ip:2181"/>

    <dubbo:reference id="cliRes" interface="com.zyh.dubbo.ApiInterface"/>

运行结果

引入zk后,其zk中心的/dubbo/接口/provider/url中url是临时结点,因为我们服务端的dubbo和zk是这里是基于session通信的。

还有个问题,如果每次进行调用,都需要一些拖拽流程找到真正url相比性能会下降不少,所以我们可以在客户端的注册中心配置file属性把地址缓存到本地用文件保存。如在zkclient配置

代码语言:javascript复制
<dubbo:registry address="zookeeper://ip:2181" file="d:/dubbo-address"/>

会发现D盘的dubbo-address文件存储的zk上provider的配置信息。(内容我稍微排版下)

如果我们的zookeeper宕机了,他也会利用缓存中的配置向dubbo进行请求

dubbo调用端也有内部定时器去定时主动刷新缓存,此外,我们的客户端实际上是对相关结点进行监听的,如果监听结点有所改变也会通知到我们的客户端。

0 人点赞