Dubbo源码-从HelloWorld开始
Dubbo简介
Dubbo,相信做后端的同学应该都用过,或者有所耳闻。没错,我就是那个有所耳闻中的一员。
公司在好几年前实现了一套自己的RPC框架,所以也就没有机会使用市面上琳琅满目的RPC框架产品。
之所以想好好看看Dubbo,有以下几个原因
公司内部的框架一直在做迭代更新,配置越来越简洁,性能越来越好。但是作为使用者,它就像一个黑盒子,我们无法感知其内部的改动以及实现的原理
现在使用的框架,因为使用了thrift,让平时的开发显得格外的蹩脚,常常在各种model的转换中迷失自我,耗尽了耐心
阿里团队从去年开始重新维护Dubbo,并在春节之际进入Apache孵化器,在开源的道路上又猛跨一大步,其背后定然有我们值得学习借鉴的地方,更何况有阿里技术的背书
开源项目是很好的学习素材,希望借助学习Dubbo代码,了解序列化、分布式、网络通讯等方面的知识
Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。
GitHub:https://github.com/apache/incubator-dubbo
中文用户手册: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在项目目录下编译

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

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

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

今天要介绍的是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源码中,配置文件中的默认配置是multicast,但是我在运行的时候总是出现can't assign address的情况,所以改用zookeeper。
相应修改如下,在dubbo-demo-provider项目中,将dubbo-demo-provider.xml修改为
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- provider's application name, used for tracing dependency relationship -->
<dubbo:application name="demo-provider"/>
<!-- use multicast registry center to export service -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- use dubbo protocol to export service on port 20880 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- service implementation, as same as regular local bean -->
<bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/>
<!-- declare the service interface to be exported -->
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService"/>
</beans>
将dubbo-demo-consumer项目中的dubbo-demo-consumer.xml修改为
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),
don't set it same as provider -->
<dubbo:application name="demo-consumer"/>
<!-- use multicast registry center to discover service -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- generate proxy for the remote service, then demoService can be used in the same way as the
local regular interface -->
<dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.demo.DemoService"/>
</beans>
同时在命令行输入zkServer start启动zk
分别启动Proiver和Consumer
运行Provider类,将自己的服务接口对外开放

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

至此,对于Dubbo有了一个初步的认识并通过dubbo-demo项目了解Dubbo的运作模式。
网上找了一份PDF版的源码阅读心得,如果有需要,下方留下你的邮箱
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。

Dubbo源码-从HelloWorld开始的更多相关文章
- dubbo源码之四——服务发布二
dubbo版本:2.5.4 2. 服务提供者暴露一个服务的详细过程 上图是服务提供者暴露服务的主过程: 首先ServiceConfig类拿到对外提供服务的实际类ref(如:HelloWorldImpl ...
- 【Dubbo 源码解析】05_Dubbo 服务发现&引用
Dubbo 服务发现&引用 Dubbo 引用的服务消费者最终会构造成一个 Spring 的 Bean,具体是通过 ReferenceBean 来实现的.它是一个 FactoryBean,所有的 ...
- dubbo源码分析6-telnet方式的管理实现
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- dubbo源码分析1-reference bean创建
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- dubbo源码分析2-reference bean发起服务方法调用
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- dubbo源码分析3-service bean的创建与发布
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- dubbo源码分析4-基于netty的dubbo协议的server
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- dubbo源码分析5-dubbo的扩展点机制
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- dubbo源码之二——dubbo入口
dubbo源码版本:2.5.4 dubbo-contaner-api com.alibaba.dubbo.container dubbo-demo-consumer com.alibaba.dubbo ...
随机推荐
- C#抽象类应用实例
abstract修饰符可以和类.方法.属性.索引器及事件一起使用,在类声明中使用abstract修饰符以表明这个类只能是其他类的基类. 抽象类的特性 (1)抽象类不能被实例化 (2)抽象类可以包含抽象 ...
- 芝麻HTTP:Ansible扩展
Ansible简介 Ansible是由Python开发的一个运维工具,因为工作需要接触到Ansible,经常会集成一些东西到Ansible,所以对Ansible的了解越来越多. 那Ansible到底是 ...
- Reactor-反应器模式
Reactor模式:反应器模式,是高性能网络服务器中最为常用的一种模式,libevent,muduo,libuv等网络库都是以 Reactor模式构建.Reactor模式由同步事件多路分解器和具体事件 ...
- js模块编写
js模块编写 编写模块obj.js //obj.js 'use strict'; //引入模块 const dkplus = require('dkplus.js'); !(function(){ / ...
- 石子归并 51Nod - 1021
N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有 ...
- Android App性能评测分析-流畅度篇
1.前言 在手机App竞争越来越激烈的今天,Android App的各项性能特别是流畅度不如IOS,安卓基于java虚拟机运行,触控响应的延迟和卡顿比IOS系统严重得多.一些下拉上滑.双指缩放快速打字 ...
- Emacs考场配置
当年\(NOip\)考场配置不记得啦 存在这里搞事情 (set-background-color "gray15") (set-foreground-color "gra ...
- C++学习-9
友元主要用于访问私有变量,友元函数跟所在位置的权限没有任何关系friend+函数声明 友元类通常设计为一种对数据操作或类之间传递消息的辅助类(注意一下顺序) Explicit就是要求严格的匹配,不允许 ...
- 学习笔记-Little Tips_day20170615-"\n" and '\n'
1.'\n'是字符 相当于char 占一个字节 "\n"是字符串 相当于char[2] 占两个字节 答案是ABC
- Vim修炼秘籍之语法篇
前言 少年,我看你骨骼精奇,是万中无一的武学奇才,维护世界和平就靠你了,我这有本秘籍<Vim修炼秘籍>,见与你有缘,就十块卖给你了! 如果你是一名 Vimer,那么恭喜你,你的 Vim 技 ...