一、Dubbo是什么?
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册)。
其核心部分包含:
1. 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
2. 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
3. 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
二、Dubbo的作用
1.透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
2.软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
3. 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
三、Dubbo的架构
dubbo架构图:
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
调用关系说明:
0 服务容器负责启动,加载,运行服务提供者。
1. 服务提供者在启动时,向注册中心注册自己提供的服务。
2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
四、Dubbo的使用方法
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
服务提供者:
1. 下载zookeeper注册中心,下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/ 下载后解压即可,进入D:apach-zookeeper-3.4.5in,
双击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>
说明:
dubbo:registry 标签一些属性的说明:
1)register是否向此注册中心注册服务,如果设为false,将只订阅,不注册。
2)check注册中心不存在时,是否报错。
3)subscribe是否向此注册中心订阅服务,如果设为false,将只注册,不订阅。
4)timeout注册中心请求超时时间(毫秒)。
5)address可以Zookeeper集群配置,地址可以多个以逗号隔开等。
dubbo:service 标签的一些属性说明:
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;
五、dubbo服务治理
六、dubbo的集群容错和负载均衡
各节点关系:
Invoker:是Provider的一个可调用Service的抽象,Invoker封装了Provider地址及Service接口信息。
Directory:代表多个Invoker,可以把它看成List<Invoker>,但与List不同的是,它的值可能是动态变化的,比如注册中心推送变更。
Cluster:将Directory中的多个Invoker伪装成一个Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个。
Router:负责从多个Invoker中按路由规则选出子集,比如读写分离,应用隔离等。
LoadBalance:负责从多个Invoker中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选。
1、集群容错
集群容错模式:
①Failover Cluster
失败自动切换,当出现失败,重试其它服务器。(缺省)通常用于读操作,但重试会带来更长延迟。可通过retries="2"来设置重试次数(不含第一次)。
②Failfast Cluster
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
③Failsafe Cluster
失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
④Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
⑤Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过forks="2"来设置最大并行数。
⑥Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错。(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"/>
2、负载均衡
均衡策略:(缺省为random随机调用)
①Random LoadBalance
随机,按权重设置随机概率。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
②RoundRobin LoadBalance
轮循,按公约后的权重设置轮循比率。
存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
③LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
④ConsistentHash LoadBalance
一致性Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
均衡策略配置:
例如:
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" loadbalance="roundrobin"/>