Dubbo源码-从HelloWorld开始

Dubbo简介

Dubbo,相信做后端的同学应该都用过,或者有所耳闻。没错,我就是那个有所耳闻中的一员。

公司在好几年前实现了一套自己的RPC框架,所以也就没有机会使用市面上琳琅满目的RPC框架产品。

之所以想好好看看Dubbo,有以下几个原因

  • 公司内部的框架一直在做迭代更新,配置越来越简洁,性能越来越好。但是作为使用者,它就像一个黑盒子,我们无法感知其内部的改动以及实现的原理

  • 现在使用的框架,因为使用了thrift,让平时的开发显得格外的蹩脚,常常在各种model的转换中迷失自我,耗尽了耐心

  • 阿里团队从去年开始重新维护Dubbo,并在春节之际进入Apache孵化器,在开源的道路上又猛跨一大步,其背后定然有我们值得学习借鉴的地方,更何况有阿里技术的背书

  • 开源项目是很好的学习素材,希望借助学习Dubbo代码,了解序列化、分布式、网络通讯等方面的知识

Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。

GitHub:https://github.com/apache/incubator-dubbo

官网:http://dubbo.apache.org/

中文用户手册:http://dubbo.io/books/dubbo-user-book/

HelloWorld之前的两个小问题

1.没有Dubbo之前,我们是什么样的工作方式

Dubbo代表的是一类RPC框架,类似的产品还有鼎鼎大名的gRPC。

没有Dubbo之前是什么样的,可以回想下我们学生时代做的项目。

一台电脑既是服务器又是客户端,估计当时也没有想过我调用的这个接口是哪台电脑上,我是不是可以多部署几台电脑,怎么样充分利用这几台电脑好让调用的效率更高。

因为即使想了,也搞不了,因为没钱!

即使我们在自己的PC上把项目做好了,需要部署到服务器上,那么我们只要记住那台服务器的IP,使用Socket通讯,就很简单的实现了服务的调用和通讯了。

2.Dubbo有什么用

接着学生时代的项目说,那时候我们做个图书管理系统,学籍管理系统,其访问量和并发量一般不会太高,准确说,是非常低。

但是如果还是一个服务端,大量的用户请求,达到高并发的场景,那么问题就来了,一台机子显然承受不住,这时候需要考虑分布式。

Dubbo的产生于微服务联系紧密,我们一方面想着借助微服务的思想,实现各个服务或者模块之间的解耦。那么我们另一方面就不能忽视服务之间的通讯,这时候Dubbo一类的RPC框架就应运而生。

我们需要考虑扩展性,比如为了防止访问过载,服务所在机器需要进行水平扩展,同时也要考虑不断增加的服务调用方。

我们需要考虑负载均衡,怎么样才能将服务集群的威力发挥到最大。

我们需要考虑如何自动的注册服务以及更新服务,如果做好异常情况下,比如注册中心宕机时,服务方和调用方之间的服务调用。

如此种种,都是催生Dubbo的重要因素。

HelloWorld的准备工作

  • 打开命令行,执行git clone https://github.com/apache/incubator-dubbo.git命令,将远程项目拉到本地

  • 导入项目进IDE,使用mvn clean compile在项目目录下编译

Dubbo源码-从HelloWorld开始_第1张图片

  • 下载安装zookeeper,在命令行执行brew install zookeeper

Dubbo源码-从HelloWorld开始_第2张图片

相应的启动zk和关闭zk服务的命令分别是zkServer startzkServer stop

Dubbo源码-从HelloWorld开始_第3张图片

运行HelloWorld

导入Dubbo项目并且完成编译后,可以看到Dubbo项目的目录结构如下

Dubbo源码-从HelloWorld开始_第4张图片

今天要介绍的是dubbo-demo,该子模块包括

  • dubbo-demo-api(提取出公共接口)

  • dubbo-demo-consumer(服务调用方)

  • dubbo-demo-provider(服务提供方)

dubbo-demo-api

该模块最核心的类就是DemoService接口,该接口只有一个方法sayHello


package com.alibaba.dubbo.demo;

public interface DemoService {

    String sayHello(String name);

}

这个接口是联系调用方和提供方的纽带。

dubbo-demo-consumer

该模块核心的类为Consumer,主要是一个main函数


public class Consumer {

    public static void main(String[] args) {
        //Prevent to get IPV6 address,this way only work in debug mode
        //But you can pass use -Djava.net.preferIPv4Stack=true,then it work well whether in debug mode or not
        System.setProperty("java.net.preferIPv4Stack", "true");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});
        context.start();
        DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy

        while (true) {
            try {
                Thread.sleep(1000);
                String hello = demoService.sayHello("world"); // call remote method
                System.out.println(hello); // get result

            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }


        }

    }
}

其主要功能是加载配置文件,用于寻找服务提供方所在的位置,拿到DemoService接口的实现类DemoServiceImpl,并调用其方法实现sayHello

dubbo-demo-provider

该模块包含了DemoService的实现类DemoServiceImpl,同时包含一个服务启动类Provider


public class Provider {

    public static void main(String[] args) throws Exception {
        //Prevent to get IPV6 address,this way only work in debug mode
        //But you can pass use -Djava.net.preferIPv4Stack=true,then it work well whether in debug mode or not
        System.setProperty("java.net.preferIPv4Stack", "true");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-provider.xml"});
        context.start();

        System.in.read(); // press any key to exit
    }

}

启动注册中心

因为调用方和服务提供方需要靠注册中心来联系,提供方将自己的服务登记到注册中心,调用方需要拉取可用的服务提供方的位置信息,比较常见的关系描述如下图所示
Dubbo源码-从HelloWorld开始_第5张图片

调用关系说明

  • 服务容器负责启动,加载,运行服务提供者。

  • 服务提供者在启动时,向注册中心注册自己提供的服务。

  • 服务消费者在启动时,向注册中心订阅自己所需的服务。

  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

鉴于Dubbo源码中,配置文件中的默认配置是multicast,但是我在运行的时候总是出现can't assign address的情况,所以改用zookeeper。

相应修改如下,在dubbo-demo-provider项目中,将dubbo-demo-provider.xml修改为






    
    

    
    

    
    

    
    

    
    

将dubbo-demo-consumer项目中的dubbo-demo-consumer.xml修改为






    
    

    
    

    
    

同时在命令行输入zkServer start启动zk

分别启动Proiver和Consumer

运行Provider类,将自己的服务接口对外开放

Dubbo源码-从HelloWorld开始_第6张图片

运行Consumer类,寻找服务提供方,并调用其接口实现

至此,对于Dubbo有了一个初步的认识并通过dubbo-demo项目了解Dubbo的运作模式。

网上找了一份PDF版的源码阅读心得,如果有需要,下方留下你的邮箱

如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。
1240

转载于:https://www.cnblogs.com/bigdataZJ/p/dubbo-hello-world.html

你可能感兴趣的:(java,大数据,git)