基本使用介绍

  1. 服务提供方基于接口编写实现类
  2. 配合Spring配置保留Dubbo服务接口(包括:注册中心地址,协议名及端口)
  3. 消费者配合Spring,引用dubbo服务接口(包括:配置注册中心地址)
  4. 启动spring容器,获取bean,调用方法

Dubbo服务接口 dubbo接口文档_Dubbo服务接口

  1. 详见官网示例
  2. 需要注意的是Dubbo中对与服务的定义:
  • 接口可以叫服务,接口实现也可叫服务
  • 某个服务地址也可叫服务
  • 一个完整的服务ID定义包括 协议、IP、端口、接口名、分组、版本
  • 比如:dubbo://192.168.2.12:8080/user/getUserInfo:user_group:1.0.1

负载均衡

  1. 消费端与服务端均可配置,同时配置以消费端为准
  2. 支持算法
  • Random(默认)
  • RoundRobin
  • LeastActive(最少活跃调用次数)
  • ConsistentHash(相同参数的请求总发给统一提供者)
  • 自定义扩展
  1. 思考:最少活跃次数是如何统计的?
  • 每个消费者自己记录被调用服务端active属性
  • 选定服务调用前+1,收到结果后-1
  • 优先选active为最小,相同则随机

服务超时

  1. 服务端和消费端都支持配置,但效果不一样
  2. 消费端配的,表示调用服务端的超时时间,超过超时时间则抛出异常
  3. 服务端若超出自己配置的超时时间,则只会打印一个警官日志

集群容错

  1. 若存在多个实例,消费者调用服务提供者报错时处理机制
  2. Failover:重试其他实例,默认重试2次,可配,默认
  3. Failfast:快速失败,调用报错即立即报错,通常用于非幂等性操作场景
  4. Failsafe:安全失败,异常视直接忽略,用于比如记录日志场景
  5. Failback:失败自动恢复,使用日志记录,后面定时重发,通常用于发消息场景
  6. Forking:并行调用多个实例,只要一个以上成功即正常返回,也可配置,用于实时性要求较高的读操作,但浪费资源
  7. Broadcast:广播调用,逐个调用,任意一台报错则报错;比如通知所有实例更新本地缓存等本地资源信息等操作,也可配置失败比例限制;

服务降级

  1. 消费者调用提供者,若报错了采取的措施;
  2. 降级与集群容错的区别:集群是集群范围内,降级是指单个服务提供者内;
  3. 可通过降级屏蔽某个非关键功能,定义降级后的返回策略
  4. 该机制说白了就是mock思想,相当于挡板
  5. 用法1:mock=force:return+null,不管是否异常直接返回null值
  6. 用法2:mock=fail:return+null,方法调用在失败后,再返回null

本地存根

  1. 名字很抽象,就是Stub机制
  2. 说白了,消费者本地包装一下调用提供者逻辑
  3. 可在调用之前、之后做一些操作,如参数校验,结果缓存等
  4. 也可以利用该机制做服务调用容错
package com.foo;
public class BarServiceStub implements BarService {
    private final BarService barService;
    
    // 构造函数传入真正的远程代理对象
    public BarServiceStub(BarService barService){
        this.barService = barService;
    }
 
    public String sayHello(String name) {
        // 此代码在客户端执行, 你可以在客户端做ThreadLocal本地缓存,或预先验证参数是否合法,等等
        try {
            return barService.sayHello(name);
        } catch (Exception e) {
            // 你可以容错,可以做任何AOP的事项
            return "容错数据";
        }
    }
}

本地伪装

  1. 就是上面提到的服务降级
  2. 详见官网:本地伪装

参数回调

  1. 消费者调用服务提供者后,支持服务提供者回调消费者某个回调逻辑
  2. Dubbo协议是基于长连接的,故若在两次调用同样的服务提供者方法,则需要用key加以区分
  3. 此功能相当于可监听服务提供者那边的处理情况

异步调用

  1. 直接把它理解为Future
  2. 基于 NIO 的非阻塞实现并行调用
  3. 客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小

泛化调用

  1. 用于客户端没有 API 接口及模型类元的情况
  2. 通常用于框架集成
  3. 例如实现一个通用的服务测试框架,可通过 GenericService调用所有服务实现
import org.apache.dubbo.rpc.service.GenericService; 
... 
 
// 引用远程服务 
// 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); 
// 弱类型接口名
reference.setInterface("com.xxx.XxxService");  
reference.setVersion("1.0.0");
// 声明为泛化接口 
reference.setGeneric(true);  

// 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口引用  
GenericService genericService = reference.get(); 
 
// 基本类型以及Date,List,Map等不需要转换,直接调用 
Object result = genericService.$invoke("sayHello", new String[] {"java.lang.String"}, new Object[] {"world"}); 
 
// 用Map表示POJO参数,如果返回值为POJO也将自动转成Map 
Map<String, Object> person = new HashMap<String, Object>(); 
person.put("name", "xxx"); 
person.put("password", "yyy"); 
// 如果返回POJO将自动转成Map 
Object result = genericService.$invoke("findPerson", new String[]
{"com.xxx.Person"}, new Object[]{person}); 
 
...

泛化服务

  1. 实现了GenericService接口的就是泛化服务
  2. 实现 GenericService 接口处理所有服务请求
  3. 主要用于服务器端没有API接口及模型类元的情况
package com.foo;
public class MyGenericService implements GenericService {
 
    public Object $invoke(String methodName, String[] parameterTypes, Object[] args) throws GenericException {
        if ("sayHello".equals(methodName)) {
            return "Welcome " + args[0];
        }
    }
}

REST

  1. 新版本Dubbo所支持的一种协议
  2. 比如消费者没有使用Dubbo也想调用Dubbo服务
  3. 如果某个服务只有REST协议可用,那么该服务必须用@Path注解定义访问路径
  4. 可以实现服务的”一次编写,到处访问“

Dubbo服务接口 dubbo接口文档_spring_02

管理台

  1. dubbo-admin,下载源码打包启动接口用,springboot工程
  2. dubbo支持配置zk、redis等为配置中心
  3. 进管理台可修改zk或其他配置中心内容
  4. 总体提供的功能还在不断完善
  5. 特殊功能关注:动态配置功能,可动态修改服务各项参数
  6. 条件路由配置
  • 针对消费者与提供者
  • 可用表示配置路由规则
  • 可配置黑名单策略
  • 可用于实现隔离不同机房等功能
  1. 标签路由
  • 可用于蓝绿发布或灰度发布
  • 可给应用实例打标签
  • 消费者带标签访问时,可根据标签找到对应的提供者