参考:http://dubbo.apache.org/zh-cn/docs/user/demos/group-merger.html

分组聚合

按组合并返回集合,用group区分,消费方从每种group中调用一次返回结果,合并结果返回,就可以实现聚合菜单项。

参数验证

参数验证是基于JSR303实现的,用户只需表示JSR303标准的验证annotation,并通过声明filter来实现验证。

需要添加的maven依赖为

<dependency>
    <groupId>javax.valiadation</groupId>
    <artifactId>validation-api</artifacId>
    <version>1.0.0.GA</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifacId>
    <version>4.2.0.Final</version>
</dependency>

使用时在参数上加上标注@NotNull、@Size(min = 1, max = 20)等

结果缓存

结果缓存,用于加速热门数据的访问速度,Dubbo提供声明式缓存,以减少用户加缓存的工作量。

缓存类型有:

  • lru,基于最近最少使用原则删除多余缓存,保持最热的数据被缓存
  • threadlocal。当前线程缓存,比如页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余访问
  • jcache与JSR107集成,可以桥接各种缓存实现

泛化引用

http://dubbo.apache.org/zh-cn/docs/user/demos/generic-reference.html

泛化接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中所有的POJO均用Map表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过GenericService调用所有服务实现。

可以通过Spring使用泛化调用、通过API方式使用泛化调用。

实现泛化调用

泛接口实现方式主要用于服务器端没有API接口及模型类元的情况,参数及返回值中的所有POJO接口均用Map表示,通常用于框架集成。可以通过Spring暴露泛化实现或者通过API方式暴露泛化实现。

回声测试

回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。所有服务自动实现EchoService接口,只需要将任意服务引用强制转型为EchoService,即可使用。

上下文信息

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

RpcContext是一个ThreadLocal的临时状态记录器,当接受到RPC请求,或发起RPC请求时,RpcContext的状态都会变化,比如:A调用B,B再调用C,则B机器上,在B调用C之前,RpcContext记录的是A调B的信息,在B调用C之后,RpcContext记录的是B调C的信息。

隐式参数

可以通过RpcContext上的setAttachment和getAttachment在服务消费方和提供方之间进行参数的隐式传递。

Dubbo 对参数的大小有限制_客户端

setAttachment设置KV对,path、group、version、dubbo、token、timeout几个key是保留字段。

异步调用

http://dubbo.apache.org/zh-cn/docs/user/demos/async-call.html

基于NIO的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。

Dubbo 对参数的大小有限制_缓存_02

本地调用

本地调用使用了injvm协议,是一个伪装协议,它不开启端口,不发起远程调用,只在JVM内直接关联,但执行Dubbo的Filter链。

参数回调

参数回调方式与调用本地callback或listener相同,只需要在Spring的配置文件中声明哪个参数时callback类型即可。Dubbo将基于长连接生成反向代理,这样就可以从服务器端调用客户端逻辑。

事件通知

在调用之前、调用之后、出现异常时,会触发oninvoke、onreturn、onthrow三个事件,可以配置当前事件发生时,通知哪个类的哪个方法。

本地存根

远程服务后,客户端通常只剩下接口,而实现全在服务端,但提供方有些时候像在客户端也执行部分逻辑,比如:做ThreadLocal缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在API中带上Stub,客户端生成Proxy实例,会把Proxy通过构造函数传给stub,然后把stub暴露给用户,stub决定要不要去调用Proxy。

Dubbo 对参数的大小有限制_Dubbo 对参数的大小有限制_03

本地伪装

本地伪装通常用于服务降级,比如某验权服务,当服务提供方全部挂掉后,客户端不抛出异常,而是通过Mock数据返回授权失败。

延迟暴露

如果服务需要预热时间,比如初始化缓存,等待相关资源就位等,可以使用delay进行延迟暴露。

并发控制

可以为service的方法配置服务器端并发执行(或占用线程池线程数)的数目,或者限制方法每客户端并发执行(或占用连接的请求数)。

延迟连接

延迟连接用于减少长连接数,当有调用发起时,再创建长连接,这个配置只对使用长连接的dubbo协议生效。

粘滞连接

粘滞连接用于有状态服务,尽可能让客户端总是向同一提供者发起调用,除非是该提供者挂了,再连另一台。粘滞连接将自动开启延迟连接,以减少长连接数。

Dubbo支持方法级别的粘滞连接。

令牌验证

通过令牌验证在注册中心的控制权限,以决定要不要下发令牌给消费者,可以防止消费者绕过注册中心的访问提供者,另外通过注册中心可灵活改变授权方式,而不需要修改或升级提供者。

Dubbo 对参数的大小有限制_缓存_04

路由规则

路由规则决定一次dubbo服务调用的目标服务器,分为条件路由规则和脚本路由规则,并且支持可扩展。

写入路由规则

向注册中心写入路由规则的操作通常由监控中心或治理中心的页面完成。

条件路由规则

基于条件表达式的路由规则

规则:

  • =>之前的为消费者匹配条件,所有参数和消费者的URL进行对比,当消费者满足匹配条件时,对该消费者执行后面的过滤规则。
  • =>之后的为提供者地址列表的过滤条件,所有参数和提供者URL进行对比,消费者最终只拿到过滤后的地址列表
  • 如果匹配条件为空,表示对所有消费方应用
  • 如果过滤条件为空,表示禁止访问

脚本路由规则

脚本路由规则支持JDK脚本引擎的所有脚本,通过type参数设置脚本类型,缺省为javascript。

标签路由规则

标签路由规则,当应用选择装配标签路由之后,一次dubbo调用能够根据请求携带的tag标签智能地选择对应tag的服务提供者进行调用。

优雅停机

Dubbo是通过JDK的ShutdownHook来完成优雅停机的,所以如果用户使用kill -9 PID等强制关闭指令,是不会执行优雅停机的,只有通过kill PID时,才会执行。

原理:

服务提供方停止时,先标记为不接收新请求,新请求过来时直接报错,让客户端重试其他机器。然后,检测线程池中的线程是否正在运行,如果有,等待所有线程执行完成,除非超时,则强制关闭。

服务消费方,停止时不再发起新的调用请求,所有新的调用在客户端即报错。然后,检测有没有请求的响应还没有返回,等待响应返回,除非超时,则强制关闭。

dump

当业务线程池满时,我们需要知道线程都在等待哪些资源、条件,以找到系统的瓶颈点或异常点。dubbo通过Jstack自动导出线程堆栈来保留线程,方便排查问题。

默认策略:

  • 导出路径,user.home标识的用户主目录
  • 导出间隔,最短间隔允许每隔10分钟导出一次