Dubbo从入门到实战:入门篇

很多时候,其实我们使用这个技术的时候,可能都是因为项目需要,所以,我们就用了,但是,至于为什么我们需要用到这个技术,可能自身并不是很了解的,但是,其实了解技术的来由及背景知识,对于理解一项技术还是有帮助的,那么,dubbo是怎么被提上日程的呢?
在互联网的发展过程中,在以前,我们只需要一个服务器,将程序全部打包好就可以,但是,随着流量的增大,常规的垂直应用架构已无法应对,所以,架构就发生了演变。
1 单一应用架构
2 应用和数据库单独部署
3 应用和数据库集群部署
4 数据库压力变大,读写分离
5 使用缓存技术加快速度
6 数据库分库分表
7 应用分为不同的类型拆分
发展到这个阶段的时候,我们发现,应用与应用之间的关系已经十分的复杂了,就会出现以下几个问题(以下摘录于官网):
① 当服务越来越多时,服务 URL 配置管理变得非常困难,F5 硬件负载均衡器的单点压力也越来越大。
② 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
③ 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
为了解决这由于架构的演变所产生的问题几个问题,于是,dubbo 产生了。当然,解决这个问题的技术不止 dubbo 。


从上面 Dubbo 的服务治理图我们就可以看到,Duboo 很好了解决了上面所出现的一些问题。
所以,当你的系统架构发展到了这种阶段的时候,就需要考虑使用 Dubbo 了。
二 Dubbo 技术架构
我们已经非常清楚的知道为什么在我们的系统中需要 Dubbo 这项技术了,下面,我们接着唠叨唠叨 Dubbo 的架构。
首先,上一张图(摘自官网)。


看到图之后,可能你对上面的几个概念还是一脸懵逼,无从下手,下面,带你看看这几个角色到底是什么意思?
节点角色说明

看了这几个概念后似乎发现,其实 Dubbo 的架构也是很简单的(其实现细节是复杂的),为什么这么说呢,有没有发现,其实很像 生产者-消费者 模型。只是在这种模型上,加上了 注册中心和监控中心 ,用于管理提供方提供的 url ,以及管理整个过程。
那么,整个发布-订阅的过程就非常的简单了。
- 启动容器,加载, 运行服务提供者 。
- 服务提供者在启动时,在注册中心 发布注册 自己提供的 服务 。
- 服务消费者在启动时,在注册中心 订阅 自己所需的 服务 。
如果考虑 失败或变更 的情况,就需要考虑下面的过程。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
通过这番讲解,我相信 Dubbo 的架构我们也轻车熟路了,那就直接入手,开车吧。
三 Dubbo 开始入门
终于走到这一步了,写到这里停了大概一周的时间,主要原因还是最近项目太忙,赶着交差呢,今天希望能一鼓作气,完完整整的写完 dubbo 的基础篇!
3.1 服务端
首先,我们先把服务端的接口写好,因为其实 dubbo 的作用简单来说就是给消费端提供接口。
接口定义
/**
* xml方式服务提供者接口
*/
public interface ProviderService { String SayHello(String word);
}
这个接口非常简单,只是包含一个 SayHello 的方法。
接着,定义它的实现类。
/**
* xml方式服务提供者实现类
*/
public class ProviderServiceImpl implements ProviderService{ public String SayHello(String word) {
return word;
}
}
这样我们就把我们的接口写好了,那么我们应该怎么将我们的服务暴露出去呢?
导入 maven 依赖
<?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.ouyangsihai</groupId>
<artifactId>dubbo-provider</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.6</version>
</dependency>
<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.5</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency> </dependencies>
</project>
这里使用的 dubbo 的版本是 2.6.6 ,需要注意的是,如果你只导入 dubbo 的包的时候是 会报错 的, 找不到 netty 和 curator 的依赖 ,所以,在这里我们需要把这两个的依赖加上,就不会报错了。
另外,这里我们使用 zookeeper 作为注册中心。
到目前为止,dubbo 需要的环境就已经可以了,下面,我们就把上面刚刚定义的接口暴露出去。
暴露接口(xml 配置方法)
首先,我们在我们项目的 resource 目录下 创建 META-INF.spring 包 ,然后再创建 provider.xml 文件,名字可以任取哦,如下图。



<?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"> <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
<dubbo:application name="provider" owner="sihai">
<dubbo:parameter key="qos.enable" value="true"/>
<dubbo:parameter key="qos.accept.foreign.ip" value="false"/>
<dubbo:parameter key="qos.port" value="55555"/>
</dubbo:application> <dubbo:monitor protocol="registry"/> <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
<!--<dubbo:registry address="N/A"/>-->
<dubbo:registry address="N/A" /> <!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->
<dubbo:protocol name="dubbo" port="20880"/> <!--服务发布的配置,需要暴露的服务接口-->
<dubbo:service
interface="com.sihai.dubbo.provider.service.ProviderService"
ref="providerService"/> <!--Bean bean定义-->
<bean id="providerService" class="com.sihai.dubbo.provider.service.ProviderServiceImpl"/> </beans>
① 上面的文件其实就是类似 spring 的配置文件,而且,dubbo 底层就是 spring。
② 节点:dubbo:application 就是整个项目在分布式架构中的唯一名称,可以在 name 属性中配置,另外还可以配置 owner 字段,表示属于谁。 下面的参数是可以不配置的,这里配置是因为出现了端口的冲突,所以配置。
③ 节点:dubbo:monitor 监控中心配置, 用于配置连接监控中心相关信息,可以不配置,不是必须的参数。
④ 节点:dubbo:registry 配置注册中心的信息,比如,这里我们可以配置 zookeeper 作为我们的注册中心。 address 是注册中心的地址,这里我们配置的是 N/A 表示由 dubbo 自动分配地址。或者说是一种直连的方式,不通过注册中心。
⑤ 节点:dubbo:protocol 服务发布的时候 dubbo 依赖什么协议,可以配置 dubbo、webserovice、Thrift、Hessain、http等协议。
⑥ 节点:dubbo:service 这个节点就是我们的重点了,当我们服务发布的时候,我们就是通过这个配置将我们的服务发布出去的。 interface 是接口的包路径, ref 是第 ⑦ 点配置的接口的 bean。
⑦ 最后,我们需要像配置 spring 的接口一样,配置接口的 bean。
到这一步,关于服务端的配置就完成了,下面我们通过 main 方法 将接口发布出去。
发布接口
package com.sihai.dubbo.provider; import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import com.alibaba.dubbo.container.Main;
import com.sihai.dubbo.provider.service.ProviderService;
import com.sihai.dubbo.provider.service.ProviderServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; /**
* xml方式启动
*
*/
public class App
{
public static void main( String[] args ) throws IOException {
//加载xml配置文件启动
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/provider.xml");
context.start();
System.in.read(); // 按任意键退出
}
}
发布接口非常简单,因为 dubbo 底层就是依赖 spring 的,所以,我们只需要通过 ClassPathXmlApplicationContext 拿到我们刚刚配置好的 xml ,然后调用 context.start() 方法就启动了。
看到下面的截图,就算是启动成功了,接口也就发布出去了。

你以为到这里就结束了了,并不是的,我们拿到 dubbo 暴露出去的 url 分析分析。
dubbo 暴露的 url
dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService?anyhost=true&application=provider&bean.name=com.sihai.dubbo.provider.service.ProviderService&bind.ip=192.168.234.1&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=8412&qos.accept.foreign.ip=false&qos.enable=true&qos.port=55555&side=provider×tamp=1562077289380
分析
① 首先,在形式上我们发现,其实这么牛逼的 dubbo 也是用 类似于 http 的协议 发布自己的服务的,只是这里我们用的是 dubbo 协议 。
② dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService 上面这段链接就是 ? 之前的链接,构成: 协议://ip:端口/接口 。发现是不是也没有什么神秘的。
③ anyhost=true&application=provider&bean.name=com.sihai.dubbo.provider.service.ProviderService&bind.ip=192.168.234.1&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=8412&qos.accept.foreign.ip=false&qos.enable=true&qos.port=55555&side=provider×tamp=1562077289380 ? 之后的字符串,分析后你发现,这些都是刚刚在 provider.xml 中配置的字段,然后通过 & 拼接而成的,闻到了 http 的香味了吗?
终于,dubbo 服务端入门了。下面我们看看拿到了 url 后,怎么消费呢?
3.2 消费端
上面提到,我们在服务端提供的只是点对点的方式提供服务,并没有使用注册中心,所以,下面的配置也是会有一些不一样的。
消费端环境配置
首先,我们在消费端的 resource 下建立配置文件 consumer.xml 。

<?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"> <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
<dubbo:application name="consumer" owner="sihai"/> <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
<!--点对点的方式-->
<dubbo:registry address="N/A" />
<!--<dubbo:registry address="zookeeper://localhost:2181" check="false"/>--> <!--生成一个远程服务的调用代理-->
<!--点对点方式-->
<dubbo:reference id="providerService"
interface="com.sihai.dubbo.provider.service.ProviderService"
url="dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService"/> <!--<dubbo:reference id="providerService"
interface="com.sihai.dubbo.provider.service.ProviderService"/>--> </beans>
分析
① 发现这里的 dubbo:application 和 dubbo:registry 是一致的。
② dubbo:reference :我们这里采用 点对点 的方式,所以,需要配置在服务端暴露的 url 。
maven 依赖
和服务端一样
<?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.ouyangsihai</groupId>
<artifactId>dubbo-consumer</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<dependency>
<groupId>com.ouyangsihai</groupId>
<artifactId>dubbo-provider</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.6</version>
</dependency>
<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.5</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
</project>
调用服务
package com.sihai.dubbo.consumer; import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.sihai.dubbo.provider.service.ProviderService;
import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; /**
* xml的方式调用
*
*/
public class App
{
public static void main( String[] args ) throws IOException { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("consumer.xml");
context.start();
ProviderService providerService = (ProviderService) context.getBean("providerService");
String str = providerService.SayHello("hello");
System.out.println(str);
System.in.read(); }
}
这里和服务端的发布如出一辙。

如此,我们就成功调用接口了。
文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的 微信公众号 :
Java技术zhai,获取优质学习资源。免费Java高级资料需要自己领取,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高并发分布式等教程,一共40G。
传送门: https://mp.weixin.qq.com/s/DHCu6AkF4nz4hNOv9c0IZg

Dubbo从入门到实战:入门篇的更多相关文章
- 用Python让单片机“行动”起来——MicroPython实战入门篇
MicroPython以微控制器作为目标,从而使得Python可以用来控制硬件.说到MicroPython,也许有人会感到陌生.而说到和它密切相关的Python,是否会恍然大悟呢?Python属于解释 ...
- Sping Boot入门到实战之入门篇(三):Spring Boot属性配置
该篇为Sping Boot入门到实战系列入门篇的第三篇.介绍Spring Boot的属性配置. 传统的Spring Web应用自定义属性一般是通过添加一个demo.properties配置文件(文 ...
- Sping Boot入门到实战之入门篇(二):第一个Spring Boot应用
该篇为Spring Boot入门到实战系列入门篇的第二篇.介绍创建Spring Boot应用的几种方法. Spring Boot应用可以通过如下三种方法创建: 通过 https://start.spr ...
- Sping Boot入门到实战之入门篇(一):Spring Boot简介
该篇为Spring Boot入门到实战系列入门篇的第一篇.对Spring Boot做一个大致的介绍. 传统的基于Spring的Java Web应用,需要配置web.xml, applicationCo ...
- Sping Boot入门到实战之入门篇(四):Spring Boot自动化配置
该篇为Sping Boot入门到实战系列入门篇的第四篇.介绍Spring Boot自动化配置的基本原理与实现. Spring Boot之所以受开发者欢迎, 其中最重要的一个因素就是其自动化配置特性 ...
- Sping Boot入门到实战之实战篇(一):实现自定义Spring Boot Starter——阿里云消息队列服务Starter
在 Sping Boot入门到实战之入门篇(四):Spring Boot自动化配置 这篇中,我们知道Spring Boot自动化配置的实现,主要由如下几部分完成: @EnableAutoConfigu ...
- xgboost入门与实战(原理篇)
sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...
- xgboost入门与实战(实战调参篇)
https://blog.csdn.net/sb19931201/article/details/52577592 xgboost入门与实战(实战调参篇) 前言 前面几篇博文都在学习原理知识,是时候上 ...
- CMake快速入门教程-实战
http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/ http://blog.csdn.net/dbzhang800/article/detai ...
- BDD敏捷开发入门与实战
BDD敏捷开发入门与实战 1.BDD的来由 2003年,Dan North首先提出了BDD的概念,并在随后开发出了JBehave框架.在Dan North博客上介绍BDD的文章中,说到了BDD的想法是 ...
随机推荐
- pandas 学习 第6篇:DataFrame - 数据处理(长宽格式、透视表)
长宽格式的转换 宽格式是指:一列或多列作为标识变量(id_vars),其他变量作为度量变量(value_vars),直观上看,这种格式的数据比较宽,举个列子,列名是:id1.id2.var1.var2 ...
- Elasticsearch Query DSL 语言介绍
目录 0. 引言 1. 组合查询 2. 全文搜索 2.1 Match 2.2 Match Phase 2.3 Multi Match 2.4 Query String 2.5 Simple Query ...
- wpf file embeded resource is readonly,Copy always will copy the file and its folder to the bin folder
Wpf file embeded resource will compile the file into the assembly and it will be readonly and can no ...
- 在Vue中使用i18n 国际化遇到 Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
最近用Vue在搭建前端框架,在引用i18n时,运行的时候报错:Uncaught TypeError: Cannot assign to read only property 'exports' of ...
- Linux域名服务DNS
什么是 DNS DNS 全称是 Domain Name System,大意是域名解析系统,它的职责是把域名翻译成一个一个可以识别的 IP 供不同的计算机设备连接. linux 有关 DNS 解析的配置 ...
- JavaScript几种继承方式
我们先构建一个Person的构造函数 function Person(name) { this.name=name; } Person.prototype.sayHi=function () { co ...
- 概要设计文档(final)
1. 引言部分 引言部分主要说明编写目的.系统的范围和参考资料等. 1.1目的 该文档的目的是描述“自习吧”微信小程序的概要设计,主要内容包括系统功能简介.系统结构设计.模块设计和界面设计等. 本文档 ...
- Linux:路径的概念及路径的切换
路径分为绝对路径和相对路径 绝对路径:从/根开头的路径为绝对路径 相对路径:以当前目录为开头的为相对路径 根目录:/ 家目录:普通用户的家目录在/home下,root用户的家目录是/root 切换目录 ...
- 【bzoj1941】[Sdoi2010]Hide and Seek(kd-tree)
bzoj 题意: 给出\(n\)个点,对于每个点,\(d_i\)等于距离其最远的点的距离减去距离最近的点的距离.这里的距离为曼哈顿距离. 求\(min\{d_i\}\). 思路: 考虑直接对每个点暴力 ...
- pushgateway
下载pushgateway wget https://github.com/prometheus/pushgateway/releases/download/v0.9.0/pushgateway-0. ...