第一部分:Dubbo的背景分析及工作原理

1. Dubbo是什么?
Dubbo是一个来自阿里巴巴的开源分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架

其核心部分包含:

1. 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。

2. 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。

3. 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。

2. Dubbo能做什么?

1.透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。

2.软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。

3. 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。

Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。

3、Dubbox是什么?

当当根据自身的需求,为Dubbo实现了一些新的功能,包括REST风格远程调用、Kryo/FST序列化等等。并将其命名为Dubbox(即Dubbo eXtensions)。

Dubbox基于非常成熟的JBoss RestEasy框架,在dubbo中实现了REST风格(HTTP + JSON/XML)的远程调用,以显著简化企业内部的跨语言交互,同时显著简化企业对外的Open API、无线API甚至AJAX服务端等等的开发。

事实上,这个REST调用也使得Dubbo可以对当今特别流行的“微服务”架构提供基础性支持。

另外,REST调用也达到了比较高的性能,在基准测试下,HTTP + JSON与Dubbo 2.x默认的RPC协议(即TCP + Hessian2二进制序列化)之间只有1.5倍左右的差距。

4、Dubbox  实现原理

作为一个分布式的服务框架,有几个核心要点,以dubbox为例:

  • 调用方式(Rest/RPC)
  • 服务注册   (zookeeper)
  • 服务发现   (zookeeper)
  • 序列化/反序列化  (dubbo/hessian2/fastjson/Kryo/FST等)
  • 负载均衡

第二部分:Dubbox的应用实践

1、环境搭建

你可以把Dubbox理解成一个可插拔的服务组件,其依赖的中间件只有Zookeeper,它主要负责是服务注册与服务发现,起到一个中间桥梁的作用,所以Dubbox环境搭建比较简单,只需要一个zookeeper或zookeeper集群环境即可。

zookeeper不是本文的重点,所以不作详细讲解,关于zookeeper的安装和集群配置,可参考:

官方网站:https://zookeeper.apache.org/

安装示例:http://www.cnblogs.com/xxx0624/p/4168440.html

集群示例:http://www.cnblogs.com/huangxincheng/p/5654170.html

2、项目中的jar包依赖

生产者和消费者都需要引入dubbox相关依赖包,maven配置:

<!-- dubbo  -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.5-SNAPSHOT</version>
</dependency> <!-- 序列化 -->
<dependency>
<groupId>com.esotericsoftware.kryo</groupId>
<artifactId>kryo</artifactId>
<version>2.24.0</version>
</dependency> <dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
<version>0.26</version>
</dependency> <!--zookeeper -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>zkclient</artifactId>
<version>0.8.1</version>
</dependency>
<dependency>
<groupId>net.dubboclub</groupId>
<artifactId>netty4</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</dependency>

2、生产者(服务注册)

服务注册比较简单,只需要一个dubbox的配置文件,在服务进程启动的时候加载它,就可以完成服务注册,以spring配置为例:

springDubbo.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="myapp" owner="myapp" />
<dubbo:protocol name="dubbo" port="20889" threads="500" accepts="500" keepalive="true" serialization="kryo" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry protocol="zookeeper" address="zookeeper://192.168.15.5:2189?backup=192.168.15.6:2189,192.168.15.9:2189"
check="true" subscribe="false" register="true" />
<dubbo:provider group="corp" />
<dubbo:service interface="com.yhouse.modules.services.ITestService" ref="testServiceImpl" id="testService" timeout="1200000" protocol="dubbo" /> </beans>

配置文件中的标签作一个简要的说明:

  • dubbo:application  应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者
  • dubbo:protocol      协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受,这里我们采用dubbo协议,当然也可以修改成其他如rmi、hessian等。
  • dubbo:registry      注册中心配置,用于配置连接注册中心相关信息。
  • dubbo:provider     提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选,在一些特定的场景很有用,如多个环境服务重叠时,可使用它来区分是哪个环境的服务,简单的可以理解为分组的概念。
  • dubbo:service       服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。

从上面的配置文件可以看出,我们注册了一个服务:testService。

定义接口与实现类:

package com.yhouse.modules.services;

public interface ITestService {
public String getName();
}
package com.yhouse.modules.services;

import org.springframework.stereotype.Service;

@Service("testServiceImpl")
public class TestServiceImpl implements ITestService {
@Override
public String getName() {
// TODO Auto-generated method stub
return "hello";
}
}

启动进程(jetty),终端打印信息:

从上面颜色标深的三行,可以看出服务已经注册成功。

服务示例使用的环境: java web / jetty容器 / spring4 ,根据你的实际情况选择,如jetty换成tomcat,或者使用dubbo提供的单独启动进程的方式:

public static void main(String[] args) {
    com.alibaba.dubbo.container.Main.main(args);
}

3、消费者(服务发现和调用)

从上面的生产者示例开发,消费端其实也很简单,过程一样,只不过角色换成了服务调用方,首先来看配置文件,看有哪些变化:

<?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="consumerTest" owner="consumerTest" />
<!-- 加入监控 -->
<dubbo:monitor protocol="registry" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry protocol="zookeeper" address="zookeeper://192.168.15.5:2189?backup=192.168.15.6:2189,192.168.15.9:2189" check="true" subscribe="true" register="true" /> <dubbo:reference check="false" interface="com.yhouse.modules.services.ITestService" id="testService" group="corp"/> </beans>
  • dubbo:application  应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者
  • dubbo:registry      注册中心配置,用于配置连接注册中心相关信息。
  • dubbo:reference      引用服务配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心,后面有一个group,其实就是生产者的 <dubbo:provider group="corp" />

注意:生产者与消费者都引用了 com.yhouse.modules.services.ITestService 这个接口,在实际当中不可能在生产者定义一次,又到消费端来定义一次吧,具体的做法可以这样:

把对外的接口、接口参数(如果是对象)、接口返回(如果是对象)抽出一个公共层,生产者与浪费者只需要引用这个公共层即可。

下面用一个简单的测试用例调用dubbox服务:

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.yhouse.modules.services.ITestService; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/spring/dubbox.xml"
}, inheritLocations = true)
public class TestServiceCall { @Autowired
private ITestService testService; @Test
public void dubboCallTest(){ System.out.println(testService.getName()); } }

控制台输出:

从结果看出,dubbox服务可以正常调通,是不是很简单?

在实际应用当中,dubbox还有很多功能可以使用,可以适应不同的应用场景,本文仅作为一个入门级应用示范。

第三部分:配置中一些重要特性讲解 

1、服务调用超时设置

上图中以timeout为例,显示了配置的查找顺序,其它retries, loadbalance, actives也类似。

方法级优先,接口级次之,全局配置再次之。如果级别一样,则消费方优先,提供方次之。

其中,服务提供方配置,通过URL经由注册中心传递给消费方。

建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置。

理论上ReferenceConfig的非服务标识配置,在ConsumerConfig,ServiceConfig, ProviderConfig均可以缺省配置。

2、启动时检查 
Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。

如果你的Spring容器是懒加载的,或者通过API编程延迟引用服务,请关闭check,否则服务临时不可用时,会抛出异常,拿到null引用,如果check=false,总是会返回引用,当服务恢复时,能自动连上。

可以通过check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。

<!-- 关闭某个服务的启动时检查:(没有提供者时报错) -->
<dubbo:reference interface="com.foo.BarService" check="false" /> <!-- 关闭所有服务的启动时检查:(没有提供者时报错) 写在定义服务消费者一方 -->
<dubbo:consumer check="false" /> <!-- 关闭注册中心启动时检查:(注册订阅失败时报错) -->
<dubbo:registry check="false" />

引用缺省是延迟初始化的,只有引用被注入到其它Bean,或被getBean()获取,才会初始化。

如果需要饥饿加载,即没有人引用也立即生成动态代理,可以配置:

<dubbo:reference interface="com.foo.BarService" init="true" />

3、订阅

问题:为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。

解决文案:可以让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,通过直连测试正在开发的服务。

<!-- 禁用注册配置:-->
<dubbo:registry address="10.20.153.10:9090" register="false" />
<!-- 或者:-->
<dubbo:registry address="10.20.153.10:9090?register=false" />

4、回声测试(测试服务是否可用)

回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。

所有服务自动实现EchoService接口,只需将任意服务引用强制转型为EchoService,即可使用。

<dubbo:reference id="memberService" interface="com.xxx.MemberService" />

MemberService memberService = ctx.getBean("memberService"); // 远程服务引用
EchoService echoService = (EchoService) memberService; // 强制转型为EchoService
String status = echoService.$echo("OK"); // 回声测试可用性
assert(status.equals("OK"))

5、延迟连接

延迟连接,用于减少长连接数,当有调用发起时,再创建长连接。

只对使用长连接的dubbo协议生效。

<dubbo:protocol name="dubbo" lazy="true" />

6、令牌验证 

防止消费者绕过注册中心访问提供者,在注册中心控制权限,以决定要不要下发令牌给消费者,注册中心可灵活改变授权方式,而不需修改或升级提供者

<!-- 1、全局设置开启令牌验证:随机token令牌,使用UUID生成 -->
<dubbo:provider interface="com.foo.BarService" token="true" />
<!-- 固定token令牌,相当于密码-->
<dubbo:provider interface="com.foo.BarService" token="123456" />
<!-- 2、服务级别设置开启令牌验证: 随机token令牌,使用UUID生成 -->
<dubbo:service interface="com.foo.BarService" token="true" />
<!--固定token令牌,相当于密码-->
<dubbo:service interface="com.foo.BarService" token="123456" />
<!-- 3、协议级别设置开启令牌验证:随机token令牌,使用UUID生成-->
<dubbo:protocol name="dubbo" token="true" />
<!--固定token令牌,相当于密码-->
<dubbo:protocol name="dubbo" token="123456" />

7、日志适配

缺省自动查找:log4j、slf4j、jcl、jdk

可以通过以下方式配置日志输出策略:<dubbo:application logger="log4j"/>

访问日志:如果你想记录每一次请求信息,可开启访问日志,类似于apache的访问日志。此日志量比较大,请注意磁盘容量。

将访问日志输出到当前应用的log4j日志:

<dubbo:protocol accesslog="true" />

将访问日志输出到指定文件:

<dubbo:protocol accesslog="http://192.168.15.9/wiki/foo/bar.log" />

8、配置Dubbo缓存文件

配置方法如下:

<dubbo:registryfile=”${user.home}/output/dubbo.cache” />

注意:

文件的路径,应用可以根据需要调整,保证这个文件不会在发布过程中被清除。如果有多个应用进程注意不要使用同一个文件,避免内容被覆盖。

这个文件会缓存:

  • 注册中心的列表
  • 服务提供者列表

有了这项配置后,当应用重启过程中,Dubbo注册中心不可用时则应用会从这个缓存文件读取服务提供者列表的信息,进一步保证应用可靠性。

使用Dubbox构架分布式服务的更多相关文章

  1. Dubbo 分布式服务框架(spring、zookeeper)

    DUBBO DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架, alibaba资源 源码:https://github.com ...

  2. Dubbo分布式服务框架入门使用

    概念: Provider 暴露服务方称之为"服务提供者". Consumer 调用远程服务方称之为"服务消费者". Registry 服务注册与发现的中心目录服 ...

  3. Dubbo 分布式服务框架简介

    1.分布式服务框架 1.1 Dubbo 简介 Dubbo 是一个分布式服务框架,以及阿里巴巴内部的 SOA 服务化治理方案的核心框架.其功能主要包括:高性能 NIO 通讯及多协议集成,服务动态寻址与路 ...

  4. 分布式服务治理框架Dubbo的前世今生及应用实战

    Dubbo的出现背景 Dubbo从开源到现在,已经出现了接近10年时间,在国内各大企业被广泛应用. 它到底有什么魔力值得大家去追捧呢?本篇文章给大家做一个详细的说明. 大规模服务化对于服务治理的要求 ...

  5. 分享在Linux下使用OSGi.NET插件框架快速实现一个分布式服务集群的方法

    在这篇文章我分享了如何使用分层与模块化的方法来设计一个分布式服务集群.这个分布式服务集群是基于DynamicProxy.WCF和OSGi.NET插件框架实现的.我将从设计思路.目标和实现三方面来描述. ...

  6. 分布式服务注册和发现consul 简要介绍

    Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,Consul的方案更"一站式",内置了服务注册与发现框 架 ...

  7. 基于Dubbo框架构建分布式服务(一)

    Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...

  8. 微软开源 WCF 分布式服务框架,并入 .NET 基金会项目

    微软北京时间2015.5.20 在其 .NET Foundation GitHub 开源项目页中开放了 WCF 分布式服务框架的代码.WCF突然之间成为一个热门话题,在各大网站上都有不同的报道:dot ...

  9. 使用dubbo分布式服务框架发布服务及消费服务

    什么是DUBBO DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案. 准备工作 安装zookeeper ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服 ...

随机推荐

  1. ForEach 循环

    在C 标签里面 有个foreach 标签,这个标签是专门来做循环的标签: <c:forEach items="${wekList}"  var="list" ...

  2. JS一周游~(基础、运算符、条件语句)

    一.基础篇 JavaScript 基于浏览器(客户端).基于(面向)对象{没有继承}.事件驱动(要有对象).脚本语言(灵活多变) 1.作用 表单的验证,减轻服务端的压力 添加页面动画效果 动态更改页面 ...

  3. python之实现批量远程执行命令(堡垒机)

    python远程批量执行 我并不是一个专业的开发,我一直在学习linux运维,对于python也是接触不久,所以代码写的并不是很规范简洁. 前段时间一个同学找我一起做一个自动化运维平台,我对pytho ...

  4. H5表单

    H5表单 HTML5 新的 Input 类型 HTML5 拥有多个新的表单输入类型.这些新特性提供了更好的输入控制和验证. 本章全面介绍这些新的输入类型: email url number range ...

  5. Xamarin自定义布局系列——PivotPage,多页面切换控件

    PivotPage ---- 多页面切换控件 PivotPage是一个多页面切换控件,类似安卓中的ViewPager和UWP中的Pivot枢轴控件. 起初打算直接通过ScrollView+StackL ...

  6. 修改Delphi 10.1.2 edit控件在android的复制、剪切和粘贴样式

    Delphi 10.1.2 edit控件在android默认的复制.剪切和粘贴样式太丑,经悟能-DelphiTeacher的提示,用最简单的代码修改后稍有改观. 默认的样式: 修改后的样式: 修改FM ...

  7. iOS开发之数据存储之Preference(偏好设置)

    1.概述 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能. 每个应用都有个NSUserDefaults实例,通过它来存取偏好 ...

  8. unity3D插件开发——前篇

    Unity3D(以下简称Unity)是今年来非常流行的游戏开发引擎.他不仅有足够和unreal(虚幻)引擎媲美的渲染效果,足够多的平台输出,更为突出的就是Unity本身的编辑器.unity本身除了使用 ...

  9. git操作详解

    前言:一般公司git的master主干与线上代码保持一致,在使用git的时候,偶尔会发生一些莫名其妙的事情,很容易导致运营事故.so- 总结一下经常使用的git命令以及git的一些小坑,方便日后查阅 ...

  10. centos5.11架设svn(svn系列 架设服务器 知识一总结)

    ♣svn是什么? ♣安装    --yum安装    --创建svn版本库目录    --创建版本库    --进入conf目录进行配置(该svn版本库配置文件)    --启动svn版本库    - ...