Dubbo总概

Posted 敲代码的小小酥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dubbo总概相关的知识,希望对你有一定的参考价值。

一、与SpringBoot项目整合

这里不再一一记录步骤,简单描述一下几个重点。
首先,在一个公用common包里,定义服务接口,这个接口在生产者端和消费者端都会依赖这个common包,项目里都要有这个服务接口类。生产者端实现这个接口,提供具体的服务实现方法。消费者端直接依赖注入这个接口,调用接口的方法(本地化调用),dubbo底层通过rpc协议远程调用生产者服务,获取返回结果。大体就是这样一个流程。
下面介绍一下几个常用的注解,以及其原理:
@Service:
生产者暴露接口使用的注解。在服务接口的实现类上加该注解。注意该注解是dubbo包下的注解,和spring包下的@Service注解做区分。
注解参数如下:


从上面的属性看,dubbo为生产者提供了重试次数、最大连接数、负载均衡策略、熔断降级、并行执行请求数、集群容错方式等功能。也就是说,dubbo在实现rpc远程调用的同时,还具有限流、熔断、降级、负载均衡等多种功能。具体功能点在后面进行介绍。

@Refrence:
在消费者端,通过此注解依赖注入服务接口,调用服务接口的方法,就会远程调用生产者端提供的服务,返回接口数据。
看其源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE)
public @interface Reference 
     //同@Service
    Class<?> interfaceClass() default void.class;
     //同@Service
    String interfaceName() default "";
     //同@Service
    String version() default "";
     //同@Service
    String group() default "";
    //点对点直连生产者,绕过注册中心
    String url() default "";
   //性能类调优参数,客户端传输类型设置,如dubbo协议的netty或mina
    String client() default "";
   //是否缺省泛化接口,如果为泛化接口,将返回GenericService
    boolean generic() default false;
   //
    boolean injvm() default false;
   //消费端启动时检查服务提供者是否存在,如果注册中心中不存在,则直接报错,设置为false跳过检查
    boolean check() default true;
   //是否饥饿初始化,还是调用时初始化
    boolean init() default false;

    boolean lazy() default false;
   //
    boolean stubevent() default false;

    String reconnect() default "";

    boolean sticky() default false;

    String proxy() default "";

    String stub() default "";

    String cluster() default "";

    int connections() default 0;

    int callbacks() default 0;

    String onconnect() default "";

    String ondisconnect() default "";

    String owner() default "";

    String layer() default "";

    int retries() default 2;

    String loadbalance() default "";

    boolean async() default false;

    int actives() default 0;

    boolean sent() default false;

    String mock() default "";

    String validation() default "";

    int timeout() default 0;

    String cache() default "";

    String[] filter() default ;

    String[] listener() default ;

    String[] parameters() default ;

    String application() default "";

    String module() default "";

    String consumer() default "";

    String monitor() default "";

    String[] registry() default ;

    /**
     * The communication protocol of Dubbo Service
     *
     * @return the default value is ""
     * @since 2.6.6
     */
    String protocol() default "";  
  
    Method[] methods() default ;


@Refence注解很多属性与@Service注解属性相同。这些相同的属性在生产者端和消费者端都可以设置,两边都设置的话,以生产者端的设置优先。
@EnableDubbo:
开启dubbo功能。

dubbo的所有功能,都在这三个注解中进行配置,下面就详细讲解每个属性的特性。

二、dubbo在ZK中的存储格式


dubbo在zk中注册后,会在zk根节点创建一个dubbo节点,dubbo节点下创建对外暴露的接口节点,暴露几个接口,就创建几个节点。每个接口节点下面,包括providers节点和consumers节点,代表生产者和消费者,节点中记录着生产者和消费者的ip,端口等一系列信息。在接口节点下还会创建routers节点,记录着路由信息。这些信息都是dubbo自动创建的。providers,consumers,routers节点都是持久节点,而providers,consumers节点下的子节点是临时节点,随着客户端的关闭,数据就会消失,以实现动态更新服务列表的功能。

三、高级用法

详细用法可看官网:高级用法
这里只记录一下感兴趣的几个高级用法和其中的原理。

线程模型
详细的可参考官网,这里只强调两个概念:业务线程和IO线程。
IO线程就是用于网络传输的线程。业务线程就是专门的线程池,用来进行业务处理的。官网建议处理时间短,响应快的业务,直接使用IO线程,避免业务线程线程池的调度。而处理时间长的业务,使用业务线程,避免IO线程阻塞,影响其他数据的网络传输。
参考文章:Dubbo的线程模型

多协议
dubbo远程调用支持多种协议方式调用,在不同的应用场景和接口服务下,可以配置不同的协议方式,进行数据传输。各协议特点可参考文章:精通Dubbo——Dubbo支持的协议的详解

结果缓存
dubbo中提供了缓存服务,需要开启才可使用。对于热点数据,可缓存到客户端本地,不再走远程调用,原理图如下:

参考文章:dubbo解析-服务结果缓存

上下文
上下文中存放的是当前调用过程中所需的环境信息。所有配置信息都将转换为 URL 的参数。具体可看官网。

异步调用与异步执行

1.dubbo的消费端调用远程接口,进入dubbo的IO线程
2.dubbo的IO线程发送异步请求给服务提供方
3.IO线程创建RpcContext对象;
4.消费端获取到第三步创建的RpcContext对象;
5.消费端线程调用RpcContext的get/wait方法,进行线程阻塞;
6.等到远程接口提供方回复;
7.消费端dubbo的IO释放第五步的阻塞。完成整个调用。

通过上面的描述可知,dubbo的异步是IO线程的异步,而消费端调用线程UserThread不是异步的,还是阻塞的。所以才会说异步执行无异于节省资源或提升RPC响应性能,因为如果业务执行需要阻塞,则始终还是要有线程来负责执行。

参数回调
消费者可以实现服务接口的方法,然后以参数的形式传给生产者,让生产者调用。

事件通知
消费者在远程调用之前、调用之后、出现异常时的事件通知,类似于监听事件,添加其他的扩展操作。

本地存根
也是在消费者端执行一段业务代码,然后再调用远程的服务实现,执行代码。就相当于是在消费者的UserThread里,调用服务接口的方法之前,先执行一段逻辑代码,然后再调用服务接口的方法,只不过,dubbo留出了豁口,讲调用远程接口之前的这段代码,也归纳到了这个接口方法里,这个接口由客户端实现,而且称之为存根。

本地伪装
用于服务降级。分为两种,一种是rpc远程调用失败,走降级方法。这个会经过远程调用过程。一种是不经过远程调用,直接走降级方法。这种方式不会出现在代码中直接使用,会配合dubbo-admin插件,可视化管理动态配置这种降级。可见,dubbo降级需要人工手动介入。

四、可视化界面

dubbo-admin是一个管理dubbo服务的可视化插件。

总结

由上述描述可知,dubbo在实现RPC协议的基础上,还包含了服务降级、限流、路由规则、负载均衡等一系列分布式治理功能。所以,dubbo是一款集远程调用,服务治理于一体的分布式框架。相比于Spring Cloud技术栈,dubbo一个框架完成了Cloud多个组件的功能,这也造成Cloud专一的组件相比于dubbo对应功模块供了更完善的功能。个人理解,在dubbo 3.0之前版本,对于简单的分布式业务而言,可以使用dubbo来做服务 治理,而对于大型复杂业务场景而言,再使用Cloud技术栈。
阿里对dubbo3.0的推广力度极大,dubbo3.0与Cloud技术栈的对比,等研究完dubbo3.0后,再做比较。

以上是关于Dubbo总概的主要内容,如果未能解决你的问题,请参考以下文章

Dubbo本地存根是什么,Dubbo本地伪装又是什么?

dubbo之本地存根

10.Dubbo配置-重试,超时(集群容错),启动检查,多版本,本地存根

dubbo源码阅读-ProxyFactory之StubProxyFactoryWrapper本地存根

Java后端线上问题排查常用命令收藏

后端线上服务监控与报警方案