Dubbo基础概念

什么是Dubbo?

Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已被 Apache 维护。可以实现透明化的远程方法调用,可以实现路由选择,负载均衡,集群容错等功能
DubboX 是 Dubbo 的一个扩展,加入了一些服务如可 Restful 调用等。
在这里插入图片描述

Provider 暴露服务的服务提供方
Consumer 远程服务调用的消费方
Registry 服务注册与发现的注册中心
Monitor 监控服务的调用次数与调用时间的监控中心
Container 服务运行容器

为什么要使用Dubbo?

  1. 国内许多互联网公司都在使用,意味着该项目已经比较成熟、稳定
  2. 分布式架构的扩展性好、进一步实现解耦,在未来出现系统瓶颈或功能扩展时,能快速解决

其他分布式架构

Spring Cloud(使用RESTFul方式通信)、Apache Thrift(使用RPC方式通信)


Dubbo服务、消费方常见配置概念

Dubbo在 的所有配置类似,多个配置是有覆盖关系的:

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

Dubbo工作流程

  服务消费方发起一次调用后,经过 路由选择服务提供方 --> 负载均衡选择服务提供节点 --> 集群容错保证服务可用性

负载均衡

通过 loadbalance=“roundrobin / leastactive / consistenthash” 属性来指定,可配置在服务级,方法级

Dubbo提供了四种策略:

  1. RondomLoadBalance: 随机负载均衡。随机的选择一个。是Dubbo的默认负载均衡策略。
    有权重的概念,权重值默认相等;权重大的分配请求概率大,故在该模式下,应对机器性能高的设置更大的权重值。
  2. RoundRobinLoadBalance: 轮询负载均衡。轮询选择一个。
    也有权重的概念,会按照设置的权重比例来分配请求;在该模式下,会出现慢的 Provider 不断积累请求。
  3. LeastActiveLoadBalance: 最少活跃调用数,相同活跃数的随机。活跃数指调用前后计数差。使慢的 Provider 收到更少请求,因为越慢的 Provider 的调用前后计数差会越大。
    该模式的目的是让处理慢的机器,收到更少的请求。
  4. ConsistentHashLoadBalance: 一致性哈希负载均衡。相同参数的请求总是落在同一台机器上。
    该模式可以配合 Provider 本地缓存使用,可以减少对数据库或缓存中间件的访问次数,同时减少网络 I/O 操作。

集群容错

通过 cluster=“failfast / failsafe / failback / forking / broadcast ” 属性来指定

Dubbo提供6中集群容错模式

  1. Failover: 失败后重试,使用 retries=“2” 设置重试次数,不含第一次;为 Dubbo 默认的容错方案;
  2. Failfast : 快速失败模式,调用只执行一次,如果失败就报错;如写操作,写入数据时,如果一次调用失败就应当提示错误信息;
  3. Failsafe: 失败安全模式,将忽略调用失败的信息;在该模式下调用出错时,会给上游返回一个空结果,在上游上来看,是执行成功的,但对于调用出错的下游,会记录一条错误日志。
  4. Failback: 首次调用失败后定时异步重发一次(5秒后异步重发,不可修改),如果还是失败则忽略;适用于对实时性要求不高,且不需要返回值的一些异步操作。
  5. Forking: 并行的调用多个 Provider ,只要一个返回成功就算成功;常用于实时性要求较高的读操作,可设置 forks=“2”(并行调用2台) 避免调用大量的 Provider ;
  6. Broadcast:广播所有 Provider ,只要一个发生错误就算调用失败;常用于广播更新 Provider 本地的缓存等;

消费方同步/异步方法调用

同步调用过程

  默认便为同步调用,即消费方发出请求后,线程阻塞等待服务方返回结果。
  那么Dubbo是怎么实现线程阻塞并得到结果的呢?这里便用到了 Future 类型的线程,消费方调用 future.get() 方法阻塞线程用以获取服务方的返回结果。

异步调用过程

在这里插入图片描述
消费方:

<dubbo:reference id="asyncService" interface="com.alibaba.dubbo.samples.async.api.AsyncService">
    <dubbo:method name="goodbye" async="true"/>
</dubbo:reference>
AsyncService service = ...;
String result = service.goodbye("samples");// 这里的返回值为空,请不要使用
Future<String> future = RpcContext.getContext().getFuture();//不同版本的应使用不同的get方法
... // 业务线程可以开始做其他事情
result = future.get(); // 阻塞需要获取异步结果时,也可以使用 get(timeout, unit) 设置超时时间

method其他配置参数
sent=“true / false” 设置是否等待消息发出,默认为false:
  true:等待消息发出,消息发送失败将抛出异常。
  false:不等待消息发出,将消息放入 IO 队列,即刻返回。

return=“true / false” 设置是否忽略返回值,默认为true
  true:有返回值
  false:完全忽略返回值,不会创建 Future 对象,也就是说 RpcContext.getContext().getFuture(); 方法将返回 null

异步方法调用代码用例:

////////////////////////////////////////  consumer端
	@RequestMapping("/myTest.dhtml")
	@ResponseBody
	public String myTest(String str){
		String s = fourDetectionService.testGet(str);//异步调用方法,立即返回null
		System.err.println("return in consumer,str="+s);
		System.out.println("do something");
		Future<String> future = RpcContext.getContext().getFuture();
		try {
			System.out.println("block wait service's result");
			//阻塞2000ms,等待provider返回结果
			String returnStr=future.get(2000, TimeUnit.MILLISECONDS);//get方法阻塞线程,等待返回结果
			System.err.println("return in consumer,str="+returnStr);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "success";
}
////////////////////////////////////////  provider端
public String testGet(String str) {
        try {
            System.err.println("provider sleep 1000");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.err.println(str+" in serviceImpl");
        return str+" in serviceImpl";
}
////////////////////////////////////////  xml配置的reference
<dubbo:reference  group="${dubbo.mygroup}" timeout="99999" id="fourDetectionService" interface="com.wisesoft.ilda.cinfo.service.FourDetectionService" >
		<dubbo:method name="testGet" loadbalance="leastactive" retries="1" async="true"></dubbo:method>
	</dubbo:reference>

控制台输出:

return in consumer,str=null
sun.reflect.GeneratedMethodAccessor802.invoke:do something
sun.reflect.GeneratedMethodAccessor802.invoke:block wait service's result
provider sleep 1000
abc in serviceImpl
return in consumer,str=abc in serviceImpl

发布了91 篇原创文章 · 获赞 54 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/BigBug_500/article/details/103061795