天天看点

Dubbo

apache dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源 java rpc 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 rpc 远程服务调用方案、服务治理方案。

面向接口代理:调用接口的方法,在 a 服务器调用 b 服务器的方法,由 dubbo 实现对 b 的调用,无需关心实现的细节,就像 mybatis 访问 dao 的接口,可以操作数据库一样。不用关心 dao 接口方法的实现。这样开发是方便,舒服的。

Dubbo

服务提供者(provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。

服务消费者(consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

注册中心(registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册

中心将基于长连接推送变更数据给消费者。

监控中心(monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时

每分钟发送一次统计数据到监控中心。

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

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

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

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

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

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

支持多种协议:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。dubbo 官方推荐使用 dubbo 协议。dubbo 协议默认端口 20880

使用 dubbo 协议,spring 配置文件加入:

<code>&lt;dubbo:protocol name="dubbo" port="20880" /&gt;</code>

点对点的直连项目:消费者直接访问服务提供者,没有注册中心。消费者必须指定服务提供者的访问地址(url)。

消费者直接通过 url 地址访问固定的服务提供者。这个 url 地址是不变的。

<code>&lt;dubbo:service interface="com.hzc.service.userservice" ref="userservice" registry="n/a"/&gt;</code>使用直连方式registry的属性值为<code>n/a</code>.

建议将服务接口、服务模型、服务异常等均放在公共包中。

服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,dubbo 暂未提供分布式事务支持。

服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。

不建议使用过于抽象的通用接口,如:map query(map),这样的接口没有明确语义,会给后期维护带来不便。

每个接口都应定义版本号,为后续不兼容升级提供可能,如:<code>&lt;dubbo:service interface="com.xxx.xxxservice" version="1.0" /&gt;。</code>建议使用两位版本号,要变更服务版本。先升级一半提供者为新版本,再将消费者全

部升为新版本,然后将剩下的一半提供者升为新版本。

<code>&lt;dubbo:application name="服务的名称"/&gt;</code>声明dubbo服务提供者:保证唯一性.

<code>&lt;dubbo:registry address="ip:port" protocol="协议"/&gt;</code>

例如:

<code>&lt;dubbo:registry address="zookeeper://localhost:2181" /&gt;</code>

<code>&lt;dubbo:service interface="服务接口全限定名" ref="服务实现对象 bean"&gt;</code>

<code>&lt;dubbo:service interface="com.hzc.service.userservice" ref="userservice" /&gt;</code>

<code>&lt;dubbo:reference id="服务引用 bean 的 id" interface="服务接口名"/&gt;</code>

<code>&lt;dubbo:reference id="userservice" interface="com.hzc.service.userservice" /&gt;</code>

对于服务提供方,它需要发布服务,而且由于应用系统的复杂性,服务的数量、类型也不断膨胀;对于服务消费方,它最关心如何获取到它所需要的服务,而面对复杂的应用系统,需要管理大量的服务调用。而且,对于服务提供方和服务消费方来说,他们还有可能兼具这两种角色,即需要提供服务,有需要消费服务。 通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理。服务注册中心可以通过特定协议来完成服务对外的统一。dubbo 提供的注册中心有如下几种类型可供选:

multicast 注册中心:组播方式

redis 注册中心:使用 redis 作为注册中心

simple 注册中心:就是一个 dubbo 服务。作为注册中心。提供查找服务的功能。

zookeeper 注册中心:使用 zookeeper 作为注册中心

推荐使用 zookeeper 注册中心。

Dubbo

概念:

高可用性(high availability):通常来描述一个系统经过专门的设计,从而减少不能提供服务的时间,而保持其服务的高度可用性。zookeeper 是高可用的,健壮的。zookeeper 宕机,正在运行中的 dubbo 服务仍然可以正常访问。

健壮性:

⚫ 监控中心宕掉不影响使用,只是丢失部分采样数据

⚫ 注册中心仍能通过缓存提供服务列表查询,但不能注册新服务

⚫ 服务提供者无状态,任意一台宕掉后,不影响使用

⚫ 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

演示操作:

1. 先启动 zookeeper, dubbo 服务提供者,dubbo 服务消费者。

2. 测试正常访问

3. 停止 zookeeper

4. 测试消费者仍然可以访问提供者

每个接口都应定义版本号,为后续不兼容升级提供可能。当一个接口有不同的实现,项目早期使用的一个实现类, 之后创建接口的新的实现类。区分不同的接口实现使用 version。特别是项目需要把早期接口的实现全部换位新的实现类,也需要使用 version.可以用版本号从早期的接口实现过渡到新的接口实现,版本号不同的服务相互间不引用。可以按照以下的步骤进行版本迁移:

在低压力时间段,先升级一半提供者为新版本

再将所有消费者升级为新版本

然后将剩下的一半提供者升级为新版本

举例:

提供者:

<code>&lt;dubbo:service interface="com.hzc.service.userservice" ref="userservice" version = "1.0"/&gt;</code>

<code>&lt;dubbo:service interface="com.hzc.service.orderservice" ref="orderservice" version = "2.0"/&gt;</code>

消费者:

<code>&lt;dubbo:reference id="userservice" interface="com.hzc.service.userservice" version = "1.0"/&gt;</code>

<code>&lt;dubbo:reference id="orderservice" interface="com.hzc.service.orderservice" version = "1.0"/&gt;</code>

dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 spring 初始化完成,以便上线时,能及早发现问题,默认 check=true。通过 check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。

例 1:关闭某个服务的启动时检查

<code>&lt;dubbo:reference interface="com.foo.barservice" check="false" /&gt;</code>

例 2:关闭注册中心启动时检查

<code>&lt;dubbo:registry check="false" /&gt;</code>

默认启动服务时检查注册中心存在并已运行。注册中心不启动会报错。

消费者访问提供者,如果访问失败,则切换重试访问其它服务器,但重试会带来更长延迟。访问时间变长,用户的体验较差。多次重新访问服务器有可能访问成功。可通过 retries="2" 来设置重试次数(不含第一次)。

<code>&lt;dubbo:service retries="2" /&gt;</code>

<code>&lt;dubbo:reference retries="2" /&gt;</code>

由于网络或服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间。timeout:调用远程服务超时时间(毫秒)

<code>&lt;dubbo:server interface="com.foo.barservice" timeout="2000" /&gt;</code>

<code>&lt;dubbo:reference interface="com.foo.barservice" timeout="2000" /&gt;</code>

继续阅读