dubbo开发案例

作者: spilledyear | 来源:发表于2017-10-19 23:53 被阅读259次

本文主要介绍了 dubbo是什么,使用dubbo需要什么前提条件以及怎么使用。

Dubbo架构

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。额,感觉专业术语有点多,那么按照我自己的理解,dubbo其实就是一个方便我们管理服务的框架。那么可能又有人在想什么是服务,至少我一开始的时候是这样的,什么是服务?感觉这个词太专业,陌生的东领域是容易让人有点虚。怎么定义我不知道,1000个人有1000种想法那就有1000种定义,更何况随着知识的不断积累,我们对之前所学又有了不同的领悟。不过在使用dubbo之后你应该会对服务这个概念有个初步的体会,实际上,服务就是服务嘛。Dubbo中包括以下几个主要概念:服务注册中心、服务提供方、服务消费方。当然还有其他的,但是我水平有限,这篇文章的主要目的也是一个dubbo上手教程。按照官方的给出的架构图,是这样子的:

image.png

Zookeeper

在解释dubbo的注册中心之前,这里先补充一个概念:Zookeeper。因为Zookeeper在很多情况下作为dubbo的注册中心,用我的理解它的作用就是维护各个服务的元信息,比如某个服务的服务名,所属节点啥的。Zookeeper是一种为分布式的开源协调服务,它提供了分布式锁服务。后来逐渐出现了其他使用方法:配置维护、组织服务、分布式消息队列、分布式通知/协调等。 ZooKeeper与标准的文件系统相似,都是采用树形结构,树中的每个节点被称为Znode,其中每个Znode又可以拥有子Znode。但也有不同之处:在引用方式上,Zonde通过绝对路径引用;并且Znode节点具有文件和目录的双重两种特点;同时,每个znode可分为临时节点和永久节点并在其上面设置监听器。监视器也被称为watch,可以监视节点的一些状态。当节点的状态发生改变时,将会触发此对象上watch所对应的事件。

注册中心

按照网上说的,dubbo提供了4种注册中心,不过我在示例中使用的就是zookeeper,对其他的也不太清楚。那么什么是注册中心?注册中心就像是dubbo服务的管理中心。可以把dubbo服务想象成学校里的一个学生,并且对应有一个学号,zookeeper则是想象成一个教务网管理系统。我们可以通过教务网管理系统,查找到对应的学生。我们首先通过注册入学,将学生和学号对应绑定。比方说项目是一个分布式的项目,web层与 service层被拆分了开来, 部署在不同的tomcat中, 我在web层 需要调用 service层的接口,但是两个运行在不同tomcat下的服务无法直接互调接口,那么就可以通过zookeeper和dubbo实现。注册中心保存了服务提供方和服务消费方的的URI(dubbo自定义的一种URI),服务消费方找到zookeeper,向zookeeper要到服务提供方的URI,然后就找到提供方,并调用提供方的服务。dubbo的服务提供者会在zookeeper上面创建一个临时节点,表明自己的ip和端口,当消费者需要使用服务时,会先在zookeeper上面查询,找到服务提供者,做一些负载的选择(比如随机、轮流),然后按照这些信息,访问服务提供者。

提供方和消费方

服务提供方,也就是提供服务的一方。比如说:比如说我有一个服务,这个服务的功能是买票,你需要买票,那你就调用我的这个服务,那个这买票的服务就是一个服务提供方,而你调用我的服务,你就是作为一个服务消费方。当然服务提供方也可以是服务消费方面,比如这个买票的服务它调用了别的服务,拿它这时候的角色就是一个服务消费方。同理,服务消费放也可以是服务提供方,他们之间负责的调用关系,都是通过dubbo帮我们管理的(应该是注册中心帮我们管理的吧)。

接下来通过一个实例来了解Dubbo。

创建父module

在IDEA下创建一个maven工程,命名 dubbo。该maven工程的作用仅仅是为了方便管理接下来创建的三个maven子工程。至于创建maven工程的具体流程,这里就不做过多说明了。
pom.xml 配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hand.sxy</groupId>
    <artifactId>dubbo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>api</module>
        <module>provider</module>
        <module>consumer</module>
    </modules>
</project>

创建api module

当然这个工程好像并不是必须的,它的作用就是管理接口,最终发布成工一个jar包,然后在 服务提供方和服务调用方module中引用。可以这样讲,这个maven工程的目的就是为了管理接口。我们需要发布一个服务的时候,先在api中添加该服务的接口,然后在服务提供方中实现,然后子啊服务调用方中调用。
pom.xml 配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo</artifactId>
        <groupId>com.hand.sxy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>api</artifactId>
</project>

创建provider module

也是一个maven工程,也就是服务提供方。在该工程中,实现了api module中定义的接口,也就是实现了这些服务。在该工程中,除了主要的pom.xml配置文件和spring配置文件,还有就是dubbo的配置文件。考虑的pom.xml配置文件太长,这里截取主要的部分:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.8.4</version>
</dependency>
<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>${javassist_version}</version>
</dependency>
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty</artifactId>
    <version>${netty_version}</version>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>${zookeeper_version}</version>
</dependency>
<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>${zkclient_version}</version>
</dependency>

配置好pom.xml文件之后,接下里配置dubbo配置文件

<!-- 定义应用名称 -->
<dubbo:application name="provider"/>

<!--zk注册中心的地址-->
<dubbo:registry address="zookeeper://192.168.1.6:2181"/>

<!-- 用dubbo协议在21000端口暴露服务 -->
<dubbo:protocol name="dubbo" port="21000"/>

<bean class="com.hand.sxy.StudyServiceImpl" id="studyService"/>

<!-- 配置服务接口 -->
<dubbo:service interface="com.hand.sxy.StudyService" ref="studyService"/>

主要就是配置zk注册中心地址和 服务接口,可以看到服务接口就是在api模块中的那个接口。同时,在该配置文件中引入我们的服务实现类。实现类代码很简单,仅仅是实现接口的studing方,接收一个字符串然后返回。实现类代码如下:

/**
 * Created by spilledyear on 2017/7/2.
 */
package com.hand.sxy;

import com.hand.sxy.StudyService;
import org.springframework.stereotype.Service;

@Service("studyService")
public class StudyServiceImpl implements StudyService {

    public String studing(String object) {
        return object;
    }
}

至此,服务提供方基本配置完成,接下来激素hi启动服务提供方的。注意,服务提供方必须在服务消费放之前启动,这个想想也很正常。除此在外,刚刚在配置文件中看到的zk注册中心地址,这个是我本地的虚拟机地址,也就是说,在启动服务提供方之前,必须要先安装并启动zookeeper。至于zookeepr的安装,其实很简单,因为这里仅仅是测试而已,并不涉及到zookeeper的集群部署,所以,直接下载、解压、启动就好了,所有配置默认就行。启动zookeeper之后,接下里编写一个测试类,用来启动我们的这个服务:StartProvider

/**
 * Created by spilledyear on 2017/7/2.
 */
package com.hand.sxy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.support.
ClassPathXmlApplicationContext;


public class StartProvider {
    private static final Log log = LogFactory.getLog(StartProvider.class);

    public static void main(String[] args) {
        try {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-context.xml");
            context.start();
        } catch (Exception e) {
            log.error("== DubboProvider context start error:", e);
        }
        synchronized (StartProvider.class) {
            while (true) {
                try {
                    StartProvider.class.wait();
                } catch (InterruptedException e) {
                    log.error("== synchronized error:", e);
                }
            }
        }
    }
}

内容也很简单,就是启动这个spring应用,也就是服务提供方,因为现在这个应用就是一个服务提供方。
启动之后,观察日志,以下是一部分截图:

image.png

好了,服务提供方至此完事,接下来就是服务消费方了。

创建consumer module

服务消费方也是一个maven工程,当然其实这也不是必须的。创建好maven工程之后,然后配置pom.xml配置文件和dubbo配置文件。pom.xml配置文件没什么好说说明的,主要就是spring的那个包和日志包吧,要注意的是需要引入那个api 接口包。

<dependency>
    <groupId>com.hand.sxy</groupId>
    <artifactId>api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

配置好pom.xml配置文件之后,接下来配置 dubbo 消费方配置文件:

<!-- 定义应用名称 -->
<dubbo:application name="dubbo-consumer"/>
<!--zk注册中心的地址-->
<dubbo:registry address="zookeeper://192.168.1.6:2181"/>

<!-- 用dubbo协议在21000端口暴露服务 -->
<dubbo:protocol name="dubbo" port="21000"/>

<!-- 引用服务提供接口的路径 -->
<dubbo:reference interface="com.hand.sxy.StudyService" id="studyService" check="false" />

注册中心地址和服务提供方相同。配置好之后,接下来生成服务消费方启动类:StartConsumer 也就是说,要在这个类中调用我们刚刚发布的那个服务。

/**
 * Created by spilledyear on 2017/7/2.
 */
package com.hand.sxy;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.support.
ClassPathXmlApplicationContext;


public class StartConsumer {
    private static final Log log = LogFactory.getLog(StartConsumer.class);

    public static void main(String[] args) throws InterruptedException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-context.xml");
        context.start();
        StudyService studyService = (StudyService) context.getBean("studyService");
        String objcet = studyService.studing("English");
        System.out.println("打印  " + objcet);

        Thread.sleep(1000);
    }

}

至此,服务消费方配置完成,接下来就是启动消费端调用服务提供方了,启动之后,观察日志,可以发现调用成功,我们传入的 English 已经被打印在控制台上:

image.png

观察ZK节点的变化

以上已经调通了整个流程,接下来我们看看在 zookeeper中的节点发生了什么变化。首先利用zk命令行工具连接到zk服务器:

bin/zkCli.sh -server 127.0.0.1:2181

连接成功之后,在 zk 命令行下查看 zk节点

ls /
image.png

可以看到有一个 dubbo节点,接下来看看 dubbo节点下有什么内容

Ls /dubbo
image.png

看到了吗?这不是我们刚刚看到的那个服务吗。是不是有点激动,嗯,我也很激动
我们还可以继续往下看,看看 com.hand.sxy.StudyService 这个节点下面有什么

image.png

通过这个例子,可以看到整个流程已经走通了。当然,这只是一个最简单的例子,dubbo中还有很多高大上的内容,比如:路由、负载均衡啥的,嗯,慢慢学习吧。

相关文章

网友评论

    本文标题:dubbo开发案例

    本文链接:https://www.haomeiwen.com/subject/imfmuxtx.html