Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册)。java
其核心部分包含:
1. 远程通信: 提供对多种基于长链接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
2. 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
3. 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方能够平滑增长或减小机器。算法
1.透明化的远程方法调用,就像调用本地方法同样调用远程方法,只需简单配置,没有任何API侵入。
2.软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,下降成本,减小单点。
3. 服务自动注册与发现,再也不须要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,而且可以平滑添加或删除服务提供者。spring
dubbo架构图:apache
Provider: 暴露服务的服务提供方。缓存
Consumer: 调用远程服务的服务消费方。安全
Registry: 服务注册与发现的注册中心。服务器
Monitor: 统计服务的调用次调和调用时间的监控中心。架构
Container: 服务运行容器。app
0 服务容器负责启动,加载,运行服务提供者。负载均衡
1. 服务提供者在启动时,向注册中心注册本身提供的服务。
2. 服务消费者在启动时,向注册中心订阅本身所需的服务。
3. 注册中心返回服务提供者地址列表给消费者,若是有变动,注册中心将基于长链接推送变动数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,若是调用失败,再选另外一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置便可,Dubbo基于Spring的Schema扩展进行加载。
1. 下载zookeeper注册中心,下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/ 下载后解压便可,进入D:\apach-zookeeper-3.4.5\bin,
双击zkServer.cmd启动注册中心服务。
2. 定义服务接口: (该接口需单独打包,在服务提供方和消费方共享)
1 package com.unj.dubbotest.provider; 2
3 import java.util.List; 4
5 public interface DemoService { 6
7 String sayHello(String name); 8
9 public List getUsers(); 10
11 }
在服务提供方实现接口:(对服务消费方隐藏实现)
1 package com.unj.dubbotest.provider; 2
3 import java.util.ArrayList; 4 import java.util.LinkedList; 5 import java.util.List; 6
7
8 public class DemoServiceImpl implements DemoService{ 9
10 public String sayHello(String name) { 11 return "Hello " + name; 12 } 13 public List getUsers() { 14 List list = new ArrayList(); 15 User u1 = new User(); 16 u1.setName("jack"); 17 u1.setAge(20); 18 u1.setSex("男"); 19
20 User u2 = new User(); 21 u2.setName("tom"); 22 u2.setAge(21); 23 u2.setSex("女"); 24
25 User u3 = new User(); 26 u3.setName("rose"); 27 u3.setAge(19); 28 u3.setSex("女"); 29
30 list.add(u1); 31 list.add(u2); 32 list.add(u3); 33 return list; 34 } 35 }
用Spring配置声明暴露服务:
<?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 ">
<!-- 具体的实现bean -->
<bean id="demoService" class="com.unj.dubbotest.provider.DemoServiceImpl" />
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="xixi_provider" />
<!-- 使用multicast广播注册中心暴露服务地址 <dubbo:registry address="multicast://224.5.6.7:1234" />-->
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明须要暴露的服务接口 -->
<dubbo:service interface="com.unj.dubbotest.provider.DemoService" ref="demoService" />
</beans>
说明:
1)register是否向此注册中心注册服务,若是设为false,将只订阅,不注册。
2)check注册中心不存在时,是否报错。
3)subscribe是否向此注册中心订阅服务,若是设为false,将只注册,不订阅。
4)timeout注册中心请求超时时间(毫秒)。
5)address能够Zookeeper集群配置,地址能够多个以逗号隔开等。
1)interface服务接口的路径
2)ref引用对应的实现类的Bean的ID
3)registry向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,若是不想将该服务注册到任何registry,可将值设为N/A
4)register 默认true ,该协议的服务是否注册到注册中心。
1.经过Spring配置引用远程服务:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://code.alibabatech.com/schema/dubbo 7 http://code.alibabatech.com/schema/dubbo/dubbo.xsd 8 ">
9
10 <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方同样 -->
11 <dubbo:application name="hehe_consumer" />
12
13 <!-- 使用zookeeper注册中心暴露服务地址 -->
14 <!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> -->
15 <dubbo:registry address="zookeeper://127.0.0.1:2181" />
16
17 <!-- 生成远程服务代理,能够像使用本地bean同样使用demoService -->
18 <dubbo:reference id="demoService"
19 interface="com.unj.dubbotest.provider.DemoService" />
20
21 </beans>
2.消费方调用远程服务:
@Autowired
DemoService demoService;
各节点关系:
Invoker:是Provider的一个可调用Service的抽象,Invoker封装了Provider地址及Service接口信息。
Directory:表明多个Invoker,能够把它当作List<Invoker>,但与List不一样的是,它的值多是动态变化的,好比注册中心推送变动。
Cluster:将Directory中的多个Invoker假装成一个Invoker,对上层透明,假装过程包含了容错逻辑,调用失败后,重试另外一个。
Router:负责从多个Invoker中按路由规则选出子集,好比读写分离,应用隔离等。
LoadBalance:负责从多个Invoker中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,须要重选。
集群容错模式:
失败自动切换,当出现失败,重试其它服务器。(缺省)一般用于读操做,但重试会带来更长延迟。可经过retries="2"来设置重试次数(不含第一次)。
快速失败,只发起一次调用,失败当即报错。一般用于非幂等性的写操做,好比新增记录。
失败安全,出现异常时,直接忽略。一般用于写入审计日志等操做。
失败自动恢复,后台记录失败请求,定时重发。一般用于消息通知操做。
并行调用多个服务器,只要一个成功即返回。一般用于实时性要求较高的读操做,但须要浪费更多服务资源。可经过forks="2"来设置最大并行数。
广播调用全部提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)一般用于通知全部提供者更新缓存或日志等本地资源信息。
重试次数配置如:(failover集群模式生效)
<dubbo:service retries="2"/>
或:
<dubbo:reference retries="2"/>
或:
<dubbo:reference>
<dubbo:methodname="findFoo" retries="2"/>
</dubbo:reference>
集群模式配置如:
<dubbo:service cluster="failsafe"/>
或:
<dubbo:reference cluster="failsafe"/>
均衡策略:(缺省为random随机调用)
随机,按权重设置随机几率。
在一个截面上碰撞的几率高,但调用量越大分布越均匀,并且按几率使用权重后也比较均匀,有利于动态调整提供者权重。
轮循,按公约后的权重设置轮循比率。
存在慢的提供者累积请求问题,好比:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,长此以往,全部请求都卡在调到第二台上。
最少活跃调用数,相同活跃数的随机,活跃数指调用先后计数差。
使慢的提供者收到更少请求,由于越慢的提供者的调用先后计数差会越大。
一致性Hash,相同参数的请求老是发到同一提供者。
当某一台提供者挂时,本来发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引发剧烈变更。
均衡策略配置:
例如:
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" loadbalance="roundrobin"/>