失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > dubbo 用户指南

dubbo 用户指南

时间:2021-03-20 08:48:23

相关推荐

dubbo 用户指南

背景

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

单一应用架构当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。垂直应用架构当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。分布式服务架构当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。流动计算架构当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。

需求

在大规模服务化之前,应用可能只是通过RMI或Hessian等工具,简单的暴露和引用远程服务,通过配置服务的URL地址进行调用,通过F5等硬件进行负载均衡。

(1) 当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。

此时需要一个服务注册中心,动态的注册和发现服务,使服务的位置透明。

并通过在消费方获取服务提供方地址列表,实现软负载均衡和Failover,降低对F5硬件负载均衡器的依赖,也能减少部分成本。

(2) 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。

这时,需要自动画出应用间的依赖关系图,以帮助架构师理清理关系。

(3) 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?

为了解决这些问题,第一步,要将服务现在每天的调用量,响应时间,都统计出来,作为容量规划的参考指标。

其次,要可以动态调整权重,在线上,将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阀值,记录此时的访问量,再以此访问量乘以机器数反推总容量。

以上是Dubbo最基本的几个需求,更多服务治理问题参见:

/blog/experience_1402/service-governance-process.html

架构

节点角色说明:

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

调用关系说明:

0. 服务容器负责启动,加载,运行服务提供者。1. 服务提供者在启动时,向注册中心注册自己提供的服务。2. 服务消费者在启动时,向注册中心订阅自己所需的服务。3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

(1) 连通性:

注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表注册中心和监控中心都是可选的,服务消费者可以直连服务提供者

(2) 健状性:

监控中心宕掉不影响使用,只是丢失部分采样数据数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务注册中心对等集群,任意一台宕掉后,将自动切换到另一台注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯服务提供者无状态,任意一台宕掉后,不影响使用服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

(3) 伸缩性:

注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者

(4) 升级性:

当服务集群规模进一步扩大,带动IT治理结构进一步升级,需要实现动态部署,进行流动计算,现有分布式服务架构不会带来阻力:Deployer:自动部署服务的本地代理。Repository:仓库用于存储服务应用发布包。Scheduler:调度中心基于访问压力自动增减服务提供者。Admin:统一管理控制台。

用法

本地服务:(Spring配置)

local.xml

远程服务:(Spring配置)

在本地服务的基础上,只需做简单配置,即可完成远程化:

将上面的local.xml配置拆分成两份,将服务定义部分放在服务提供方remote-provider.xml,将服务引用部分放在服务消费方remote-consumer.xml。并在提供方增加暴露服务配置<dubbo:service>,在消费方增加引用服务配置<dubbo:reference>。

如下:

remote-provider.xml

remote-consumer.xml

快速启动

服务提供者

定义服务接口: (该接口需单独打包,在服务提供方和消费方共享)

DemoService.java

在服务提供方实现接口:(对服务消费方隐藏实现)

DemoServiceImpl.java

用Spring配置声明暴露服务:

provider.xml

加载Spring配置:

Provider.java

服务消费者

通过Spring配置引用远程服务:

consumer.xml

加载Spring配置,并调用远程服务:(也可以使用IoC注入)

Consumer.java

依赖

必需依赖

JDK1.5+

缺省依赖

通过mvn dependency:tree > dep.log命令分析,Dubbo缺省依赖以下三方库:

这里所有依赖都是换照Dubbo缺省配置选的,这些缺省值是基于稳定性和性能考虑的。

log4j.jar和commons-logging.jar日志输出包。 可以直接去掉,dubbo本身的日志会自动切换为JDK的java.util.logging输出。但如果其它三方库比如spring.jar间接依赖commons-logging,则不能去掉。javassist.jar 字节码生成。 如果<dubbo:provider proxy="jdk" />或<dubbo:consumer proxy="jdk" />,以及<dubbo:application compiler="jdk" />,则不需要。spring.jar 配置解析。 如果用ServiceConfig和ReferenceConfig的API调用,则不需要。netty.jar 网络传输。 如果<dubbo:protocol server="mina"/>或<dubbo:protocol server="grizzly"/>,则换成mina.jar或grizzly.jar。如果<protocol name="rmi"/>,则不需要。

可选依赖

以下依赖,在主动配置使用相应实现策略时用到,需自行加入依赖。

mina: 1.1.7grizzly: 2.1.4httpclient: 4.1.2hessian_lite: 3.2.1-fixedxstream: 1.4.1fastjson: 1.1.8zookeeper: 3.3.3jedis: 2.0.0xmemcached: 1.3.6jfreechart: 1.0.13hessian: 4.0.7jetty: 6.1.26hibernate-validator: 4.2.0.Finalzkclient: 0.1curator: 1.1.10cxf: 2.6.1thrift: 0.8.0

JEE:

servlet: 2.5bsf: 3.1validation-api: 1.0.0.GAjcache: 0.4

成熟度

功能成熟度

策略成熟度

配置

Xml配置

示例:

provider.xml

如:

或:(2.1.0开始支持)

Configuration Relation:

<dubbo:service/>服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。<dubbo:reference/>引用配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。<dubbo:protocol/>协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。<dubbo:application/>应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。<dubbo:module/>模块配置,用于配置当前模块信息,可选。<dubbo:registry/>注册中心配置,用于配置连接注册中心相关信息。<dubbo:monitor/>监控中心配置,用于配置连接监控中心相关信息,可选。<dubbo:provider/>提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选。<dubbo:consumer/>消费方缺省配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选。<dubbo:method/>方法配置,用于ServiceConfig和ReferenceConfig指定方法级的配置信息。<dubbo:argument/>用于指定方法参数配置。

Configuration Override:

上图中以timeout为例,显示了配置的查找顺序,其它retries, loadbalance, actives等类似。 方法级优先,接口级次之,全局配置再次之。如果级别一样,则消费方优先,提供方次之。其中,服务提供方配置,通过URL经由注册中心传递给消费方。建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置。理论上ReferenceConfig的非服务标识配置,在ConsumerConfig,ServiceConfig, ProviderConfig均可以缺省配置。

属性配置

映射规则:

将XML配置的标签名,加属性名,用点分隔,多个属性拆成多行: 比如:dubbo.application.name=foo等价于<dubbo:application name="foo" />比如:dubbo.registry.address=10.20.153.10:9090等价于<dubbo:registry address="10.20.153.10:9090" />如果XML有多行同名标签配置,可用id号区分,如果没有id号将对所有同名标签生效: 比如:dubbo.protocol.rmi.port=1234等价于<dubbo:protocol id="rmi" name="rmi" port="1099" /> (协议的id没配时,缺省使用协议名作为id)比如:dubbo.registry.china.address=10.20.153.10:9090等价于<dubbo:registry id="china" address="10.20.153.10:9090" />

典型配置如:

dubbo.properties

覆盖策略:

JVM启动-D参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口。XML次之,如果在XML中有配置,则dubbo.properties中的相应配置项无效。Properties最后,相当于缺省值,只有XML没有配置时,dubbo.properties的相应配置项才会生效,通常用于共享公共配置,比如应用名。

注解配置

服务提供方注解:

服务提供方配置:

服务消费方注解:

服务消费方配置:

也可以使用:(等价于前面的:<dubbo:annotation package="com.foo.bar.service" />)

API配置

(1) 服务提供者:

(2) 服务消费者:

(3) 特殊场景

注:下面只列出不同的地方,其它参见上面的写法

(3.1) 方法级设置:

(3.2) 点对点直连:

示例

启动时检查

可以通过check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。

关闭某个服务的启动时检查:(没有提供者时报错)

关闭所有服务的启动时检查:(没有提供者时报错)

关闭注册中心启动时检查:(注册订阅失败时报错)

也可以用dubbo.properties配置:

dubbo.properties

也可以用-D参数:

引用缺省是延迟初始化的,只有引用被注入到其它Bean,或被getBean()获取,才会初始化。

如果需要饥饿加载,即没有人引用也立即生成动态代理,可以配置:

集群容错

各节点关系:

这里的Invoker是Provider的一个可调用Service的抽象,Invoker封装了Provider地址及Service接口信息。Directory代表多个Invoker,可以把它看成List<Invoker>,但与List不同的是,它的值可能是动态变化的,比如注册中心推送变更。Cluster将Directory中的多个Invoker伪装成一个Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个。Router负责从多个Invoker中按路由规则选出子集,比如读写分离,应用隔离等。LoadBalance负责从多个Invoker中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选。

集群容错模式:

可以自行扩展集群容错策略,参见:集群扩展

Failover Cluster

失败自动切换,当出现失败,重试其它服务器。(缺省)通常用于读操作,但重试会带来更长延迟。可通过retries="2"来设置重试次数(不含第一次)。

Failfast Cluster

快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

Failsafe Cluster

失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

Failback Cluster

失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

Forking Cluster

并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过forks="2"来设置最大并行数。

Broadcast Cluster

广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)通常用于通知所有提供者更新缓存或日志等本地资源信息。

重试次数配置如:(failover集群模式生效)

或:

或:

集群模式配置如:

或:

负载均衡

可以自行扩展负载均衡策略,参见:负载均衡扩展

Random LoadBalance

随机,按权重设置随机概率。在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

RoundRobin LoadBalance

轮循,按公约后的权重设置轮循比率。存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

LeastActive LoadBalance

最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

ConsistentHash LoadBalance

一致性Hash,相同参数的请求总是发到同一提供者。当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。算法参见:/wiki/Consistent_hashing。缺省只对第一个参数Hash,如果要修改,请配置<dubbo:parameter key="hash.arguments" value="0,1" />缺省用160份虚拟节点,如果要修改,请配置<dubbo:parameter key="hash.nodes" value="320" />

配置如:

或:

或:

或:

线程模型

Dispatcher all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。direct 所有消息都不派发到线程池,全部在IO线程上直接执行。message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在IO线程上执行。execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在IO线程上执行。connection 在IO线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。ThreadPool fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)cached 缓存线程池,空闲一分钟自动删除,需要时重建。limited 可伸缩线程池,但池中的线程数只会增长不会收缩。(为避免收缩时突然来了大流量引起的性能问题)。

配置如:

直连提供者

在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,

点对点直联方式,将以服务接口为单位,忽略注册中心的提供者列表,

A接口配置点对点,不影响B接口从注册中心获取列表。

(1) 如果是线上需求需要点对点,可在<dubbo:reference>中配置url指向提供者,将绕过注册中心,多个地址用分号隔开,配置如下:(1.0.6及以上版本支持)

(2) 在JVM启动参数中加入-D参数映射服务地址,如:

(key为服务名,value为服务提供者url,此配置优先级最高,1.0.15及以上版本支持)

(3) 如果服务比较多,也可以用文件映射,如:

(用-Ddubbo.resolve.file指定映射文件路径,此配置优先级高于<dubbo:reference>中的配置,1.0.15及以上版本支持)

(2.0以上版本自动加载${user.home}/dubbo-resolve.properties文件,不需要配置)

然后在映射文件xxx.properties中加入:

(key为服务名,value为服务提供者url)

只订阅

禁用注册配置:

或者:

只注册

禁用订阅配置:

或者:

静态服务

或者:

服务提供者初次注册时为禁用状态,需人工启用,断线时,将不会被自动删除,需人工禁用。

如果是一个第三方独立提供者,比如memcached等,可以直接向注册中心写入提供者地址信息,消费者正常使用:

(通常由脚本监控中心页面等调用)

多协议

可以自行扩展协议,参见:协议扩展

(1) 不同服务不同协议

比如:不同服务在性能上适用不同协议进行传输,比如大数据用短连接协议,小数据大并发用长连接协议。

consumer.xml

(2) 多协议暴露服务

比如:需要与http客户端互操作

consumer.xml

多注册中心

可以自行扩展注册中心,参见:注册中心扩展

(1) 多注册中心注册

比如:中文站有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心。

consumer.xml

(2) 不同服务使用不同注册中心

比如:CRM有些服务是专门为国际站设计的,有些服务是专门为中文站设计的。

consumer.xml

(3) 多注册中心引用

比如:CRM需同时调用中文站和国际站的PC2服务,PC2在中文站和国际站均有部署,接口及版本号都一样,但连的数据库不一样。

consumer.xml

如果只是测试环境临时需要连接两个不同注册中心,使用竖号分隔多个不同注册中心地址:

consumer.xml

服务分组

(+) (#)

任意组:(2.2.0以上版本支持,总是只调一个可用组的实现)

多版本

(+) (#)

在低压力时间段,先升级一半提供者为新版本再将所有消费者升级为新版本然后将剩下的一半提供者升级为新版本

不区分版本:(2.2.0以上版本支持)

分组聚合

(+) (#)

代码参见:/alibaba/dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/merge

配置如:(搜索所有分组)

或:(合并指定分组)

或:(指定方法合并结果,其它未指定的方法,将只调用一个Group)

或:(某个方法不合并结果,其它都合并结果)

或:(指定合并策略,缺省根据返回值类型自动匹配,如果同一类型有两个合并器时,需指定合并器的名称)

参见:[合并结果扩展]

或:(指定合并方法,将调用返回结果的指定方法进行合并,合并方法的参数类型必须是返回结果类型本身)

参数验证

(+) (#)

完整示例代码参见:/alibaba/dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/validation

验证方式可扩展,参见:Validation扩展点

参数标注示例:

分组验证示例:

关联验证示例:

参数验证示例:

在客户端验证参数:

在服务器端验证参数:

验证异常信息:

需要加入依赖:

结果缓存

(+) (#)

示例代码:/alibaba/dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/cache

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

缓存类型可扩展,参见:CacheFactory扩展点

配置如:

或:

泛化引用

(+) (#)

假设存在POJO如:

则POJO数据:

可用下面Map表示:

泛化实现

(+) (#)

回声测试

(+) (#)

上下文信息

(+) (#)

(1) 服务消费方

(2) 服务提供方

隐式传参

(+) (#)

(1) 服务消费方

【注】 setAttachment设置的KV,在完成下面一次远程调用会被清空。即多次远程调用要多次设置。

(2) 服务提供方

异步调用

(+) (#)

配置声明:

consumer.xml

调用代码:

你也可以设置是否等待消息发出:(异步总是不等待返回)

sent="true" 等待消息发出,消息发送失败将抛出异常。sent="false" 不等待消息发出,将消息放入IO队列,即刻返回。

如果你只是想异步,完全忽略返回值,可以配置return="false",以减少Future对象的创建和管理成本:

本地调用

(+) (#)

Define injvm protocol:

Set default protocol:

Set service protocol:

Use injvm first:

自动暴露、引用本地服务

从 dubbo 2.2.0 开始,每个服务默认都会在本地暴露;在引用服务的时候,默认优先引用本地服务;如果希望引用远程服务可以使用一下配置强制引用远程服务。

参数回调

(+) (#)

代码参见:/alibaba/dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/callback

(1) 共享服务接口:

服务接口示例:

CallbackService.java

CallbackListener.java

(2) 服务提供者:

服务提供者接口实现示例:

CallbackServiceImpl.java

服务提供者配置示例:

(2) 服务消费者:

服务消费者配置示例:

consumer.xml

服务消费者调用示例:

CallbackServiceTest.java

事件通知

(+) (#)

(1) 服务提供者与消费者共享服务接口:

IDemoService.java

(2) 服务提供者实现:

DemoServiceImpl.java

(3) 服务提供者配置:

provider.xml

(4) 服务消费者Callback接口及实现:

Nofify.java

NofifyImpl.java

(5) 服务消费者Callback接口及实现:

consumer.xml

(6) TEST CASE:

Test.java

本地存根

(+) (#)

Or:

api.jar:

本地伪装

(+) (#)

Or:

api.jar:

如果服务的消费方经常需要try-catch捕获异常,如:

请考虑改为Mock实现,并在Mock中return null。

如果只是想简单的忽略异常,在2.0.11以上版本可用:

延迟暴露

(+) (#)

延迟5秒暴露服务:

延迟到Spring初始化完成后,再暴露服务:(基于Spring的ContextRefreshedEvent事件触发暴露)

并发控制

(+) (#)

限制com.foo.BarService的每个方法,服务器端并发执行(或占用线程池线程数)不能超过10个:

限制com.foo.BarService的sayHello方法,服务器端并发执行(或占用线程池线程数)不能超过10个:

限制com.foo.BarService的每个方法,每客户端并发执行(或占用连接的请求数)不能超过10个:

Or:

限制com.foo.BarService的sayHello方法,每客户端并发执行(或占用连接的请求数)不能超过10个:

Or:

如果<dubbo:service>和<dubbo:reference>都配了actives,<dubbo:reference>优先,参见:配置的覆盖策略。

Load Balance均衡:

配置服务的客户端的loadbalance属性为leastactive,此Loadbalance会调用并发数最小的Provider(Consumer端并发数)。

Or:

连接控制

(+) (#)

限制服务器端接受的连接不能超过10个:(以连接在Server上,所以配置在Provider上)

限制客户端服务使用连接连接数:(如果是长连接,比如Dubbo协议,connections表示该服务对每个提供者建立的长连接数)

Or:

如果<dubbo:service>和<dubbo:reference>都配了connections,<dubbo:reference>优先,参见:配置的覆盖策略。

延迟连接

(+) (#)

粘滞连接

(+) (#)

令牌验证

(+) (#)

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

可以全局设置开启令牌验证:

也可在服务级别设置:

还可在协议级别设置:

路由规则

(+) (#)

向注册中心写入路由规则:(通常由监控中心或治理中心的页面完成)

其中:

condition:// 表示路由规则的类型,支持条件路由规则和脚本路由规则,可扩展,必填。0.0.0.0 表示对所有IP地址生效,如果只想对某个IP的生效,请填入具体IP,必填。com.foo.BarService 表示只对指定服务生效,必填。category=routers 表示该数据为动态配置类型,必填。dynamic=false 表示该数据为持久数据,当注册方退出时,数据依然保存在注册中心,必填。enabled=true 覆盖规则是否生效,可不填,缺省生效。force=false 当路由结果为空时,是否强制执行,如果不强制执行,路由结果为空的路由规则将自动失效,可不填,缺省为flase。runtime=false 是否在每次调用时执行路由规则,否则只在提供者地址列表变更时预先执行并缓存结果,调用时直接从缓存中获取路由结果。如果用了参数路由,必须设为true,需要注意设置会影响调用的性能,可不填,缺省为flase。priority=1 路由规则的优先级,用于排序,优先级越大越靠前执行,可不填,缺省为0。rule=URL.encode("host = 10.20.153.10 => host = 10.20.153.11") 表示路由规则的内容,必填。

条件路由规则

(#)

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

规则:

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

表达式:

参数支持: 服务调用信息,如:method,argument等(暂不支持参数路由)URL本身的字段,如:protocol, host, port 等以及URL上的所有参数,如:application, organization 等条件支持: 等号"="表示"匹配",如:host = 10.20.153.10不等号"!="表示"不匹配",如:host != 10.20.153.10值支持: 以逗号","分隔多个值,如:host != 10.20.153.10,10.20.153.11以星号"*"结尾,表示通配,如:host != 10.20.*以美元符"$"开头,表示引用消费者参数,如:host = $host

示例:

1. 排除预发布机:

2. 白名单:(注意:一个服务只能有一条白名单规则,否则两条规则交叉,就都被筛选掉了)

3. 黑名单:

4. 服务寄宿在应用上,只暴露一部分的机器,防止整个集群挂掉:

5. 为重要应用提供额外的机器:

6. 读写分离:

7. 前后台分离:

8. 隔离不同机房网段:

9. 提供者与消费者部署在同集群内,本机只访问本机的服务:

脚本路由规则

(#)

基于脚本引擎的路由规则,如:

配置规则

(+) (#)

向注册中心写入动态配置覆盖规则:(通常由监控中心或治理中心的页面完成)

其中:

override:// 表示数据采用覆盖方式,支持override和absent,可扩展,必填。0.0.0.0 表示对所有IP地址生效,如果只想覆盖某个IP的数据,请填入具体IP,必填。com.foo.BarService 表示只对指定服务生效,必填。category=configurators 表示该数据为动态配置类型,必填。dynamic=false 表示该数据为持久数据,当注册方退出时,数据依然保存在注册中心,必填。enabled=true 覆盖规则是否生效,可不填,缺省生效。application=foo 表示只对指定应用生效,可不填,表示对所有应用生效。timeout=1000 表示将满足以上条件的timeout参数的值覆盖为1000。如果想覆盖其它参数,直接加在override的URL参数上。

示例:

1. 禁用提供者:(通常用于临时踢除某台提供者机器,相似的,禁止消费者访问请使用路由规则)

2. 调整权重:(通常用于容量评估,缺省权重为100)

3. 调整负载均衡策略:(缺省负载均衡策略为random)

4. 服务降级:(通常用于临时屏蔽某个出错的非关键服务)

服务降级

(+) (#)

向注册中心写入动态配置覆盖规则:(通过由监控中心或治理中心的页面完成)

其中:

表示消费方对该服务的方法调用都直接返回null值,不发起远程调用。屏蔽不重要服务不可用时对调用方的影响。

还可以改为:

表示消费方对该服务的方法调用在失败后,再返回null值,不抛异常。容忍不重要服务不稳定时对调用方的影响。

优雅停机

(+) (#)

原理:

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

设置优雅停机超时时间,缺省超时时间是10秒:(超时则强制关闭)

如果ShutdownHook不能生效,可以自行调用:

主机绑定

(+) (#)

缺省主机IP查找顺序:

通过LocalHost.getLocalHost()获取本机地址。如果是127.*等loopback地址,则扫描各网卡,获取网卡IP。

注册的地址如果获取不正确,比如需要注册公网地址,可以:

1. 可以在/etc/hosts中加入:机器名 公网IP,比如:

2. 在dubbo.xml中加入主机地址的配置:

3. 或在dubbo.properties中加入主机地址的配置:

缺省主机端口与协议相关:

dubbo: 20880rmi: 1099http: 80hessian: 80webservice: 80memcached: 11211redis: 6379

主机端口配置:

1. 在dubbo.xml中加入主机地址的配置:

3. 或在dubbo.properties中加入主机地址的配置:

日志适配

(+) (#)

缺省自动查找:

log4jslf4jjcljdk

可以通过以下方式配置日志输出策略:

dubbo.properties

dubbo.xml

访问日志

(+) (#)

将访问日志输出到当前应用的log4j日志:

将访问日志输出到指定文件:

服务容器

(+) (#)

Spring Container

自动加载META-INF/spring目录下的所有Spring配置。配置:(配在java命令-D参数或者dubbo.properties中) dubbo.spring.config=classpath*:META-INF/spring/*.xml ----配置spring配置加载位置

Jetty Container

启动一个内嵌Jetty,用于汇报状态。配置:(配在java命令-D参数或者dubbo.properties中) dubbo.jetty.port=8080 ----配置jetty启动端口dubbo.jetty.directory=/foo/bar ----配置可通过jetty直接访问的目录,用于存放静态文件dubbo.jetty.page=log,status,system ----配置显示的页面,缺省加载所有页面

Log4j Container

自动配置log4j的配置,在多进程启动时,自动给日志文件按进程分目录。配置:(配在java命令-D参数或者dubbo.properties中) dubbo.log4j.file=/foo/bar.log ----配置日志文件路径dubbo.log4j.level=WARN ----配置日志级别dubbo.log4j.subdirectory=20880 ----配置日志子目录,用于多进程启动,避免冲突

容器启动

如:(缺省只加载spring)

或:(通过main函数参数传入要加载的容器)

或:(通过JVM启动参数传入要加载的容器)

或:(通过classpath下的dubbo.properties配置传入要加载的容器)

dubbo.properties

Reference Config缓存

(+) (#)

ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接,需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。API方式编程时,容易忽略此问题。

Dubbo2.4.0+版本,提供了简单的工具类ReferenceConfigCache用于缓存ReferenceConfig实例。

使用方式如下:

消除Cache中的ReferenceConfig,销毁ReferenceConfig并释放对应的资源。

缺省ReferenceConfigCache把相同服务Group、接口、版本的ReferenceConfig认为是相同,缓存一份。即以服务Group、接口、版本为缓存的Key。

可以修改这个策略,在ReferenceConfigCache.getCache时,传一个KeyGenerator。详见ReferenceConfigCache类的方法。

分布式事务

(+) (#)

两阶段提交:

API参考手册

(+) (#)

API汇总如下:

配置API

com.alibaba.dubbo.config.ServiceConfigcom.alibaba.dubbo.config.ReferenceConfigcom.alibaba.dubbo.config.ProtocolConfigcom.alibaba.dubbo.config.RegistryConfigcom.alibaba.dubbo.config.MonitorConfigcom.alibaba.dubbo.config.ApplicationConfigcom.alibaba.dubbo.config.ModuleConfigcom.alibaba.dubbo.config.ProviderConfigcom.alibaba.dubbo.config.ConsumerConfigcom.alibaba.dubbo.config.MethodConfigcom.alibaba.dubbo.config.ArgumentConfig 参见:API配置

注解API

com.alibaba.dubbo.config.annotation.Servicecom.alibaba.dubbo.config.annotation.Reference 参见:注解配置

模型API

com.mon.URLcom.alibaba.dubbo.rpc.RpcException

上下文API

com.alibaba.dubbo.rpc.RpcContext 参见:上下文信息&对方地址&隐式传参&异步调用

服务API

com.alibaba.dubbo.rpc.service.GenericServicecom.alibaba.dubbo.rpc.service.GenericException 参见:泛化引用&泛化实现com.alibaba.dubbo.rpc.service.EchoService 参见:回声测试

配置参考手册

(+) (#)

注意:只有group,interface,version是服务的匹配条件,三者决定是不是同一个服务,其它配置项均为调优和治理参数。

所有配置项分为三大类,参见下表中的"作用"一列。

服务发现:表示该配置项用于服务的注册与发现,目的是让消费方找到提供方。服务治理:表示该配置项用于治理服务间的关系,或为开发测试提供便利条件。性能调优:表示该配置项用于调优性能,不同的选项对性能会产生影响。

所有配置最终都将转换为URL表示,并由服务提供方生成,经注册中心传递给消费方,各属性对应URL的参数,参见配置项一览表中的"对应URL参数"列。

URL格式:

protocol://username:password@host:port/path?key=value&key=value

Schema:/schema/dubbo/dubbo.xsd

<dubbo:service/>

(+) (#)

服务提供者暴露服务配置:

配置类:com.alibaba.dubbo.config.ServiceConfig

<dubbo:reference/>

(+) (#)

服务消费者引用服务配置:

配置类:com.alibaba.dubbo.config.ReferenceConfig

<dubbo:protocol/>

(+) (#)

服务提供者协议配置:

配置类:com.alibaba.dubbo.config.ProtocolConfig

说明:如果需要支持多协议,可以声明多个<dubbo:protocol>标签,并在<dubbo:service>中通过protocol属性指定使用的协议。

<dubbo:registry/>

(+) (#)

注册中心配置:

配置类:com.alibaba.dubbo.config.RegistryConfig

说明:如果有多个不同的注册中心,可以声明多个<dubbo:registry>标签,并在<dubbo:service>或<dubbo:reference>的registry属性指定使用的注册中心。

<dubbo:monitor/>

(+) (#)

监控中心配置:

配置类:com.alibaba.dubbo.config.MonitorConfig

<dubbo:application/>

(+) (#)

应用信息配置:

配置类:com.alibaba.dubbo.config.ApplicationConfig

<dubbo:module/>

(+) (#)

模块信息配置:

配置类:com.alibaba.dubbo.config.ModuleConfig

<dubbo:provider/>

(+) (#)

服务提供者缺省值配置:

配置类:com.alibaba.dubbo.config.ProviderConfig

说明:该标签为<dubbo:service>和<dubbo:protocol>标签的缺省值设置。

<dubbo:consumer/>

(+) (#)

服务消费者缺省值配置:

配置类:com.alibaba.dubbo.config.ConsumerConfig

说明:该标签为<dubbo:reference>标签的缺省值设置。

<dubbo:method/>

(+) (#)

方法级配置:

配置类:com.alibaba.dubbo.config.MethodConfig

说明:该标签为<dubbo:service>或<dubbo:reference>的子标签,用于控制到方法级,

比如:

<dubbo:argument/>

(+) (#)

方法参数配置:

配置类:com.alibaba.dubbo.config.ArgumentConfig

说明:该标签为<dubbo:method>的子标签,用于方法参数的特征描述,比如:

<dubbo:parameter/>

(+) (#)

选项参数配置:

配置类:java.util.Map

说明:该标签为<dubbo:protocol>或<dubbo:service>或<dubbo:provider>或<dubbo:reference>或<dubbo:consumer>的子标签,用于配置自定义参数,该配置项将作为扩展点设置自定义参数使用。

比如:

也可以:

详细参见:自定义参数

协议参考手册

(+) (#)

dubbo://

(+) (#)

Set default protocol:

Set service protocol:

Multi port:

Dubbo protocol options:

Transporter mina, netty, grizzySerialization dubbo, hessian2, java, jsonDispatcher all, direct, message, execution, connectionThreadPool fixed, cached<dubbo:service connections=”0”>或<dubbo:reference connections=”0”>表示该服务使用JVM共享长连接。(缺省)<dubbo:service connections=”1”>或<dubbo:reference connections=”1”>表示该服务使用独立长连接。<dubbo:service connections=”2”>或<dubbo:reference connections=”2”>表示该服务使用独立两条长连接。

缺省协议,使用基于mina1.1.7+hessian3.2.1的tbremoting交互。

连接个数:单连接连接方式:长连接传输协议:TCP传输方式:NIO异步传输序列化:Hessian二进制序列化适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串。适用场景:常规远程服务方法调用

为什么要消费者比提供者个数多:

因dubbo协议采用单一长连接,

假设网络为千兆网卡(1024Mbit=128MByte),

根据测试经验数据每条连接最多只能压满7MByte(不同的环境可能不一样,供参考),

理论上1个服务提供者需要20个服务消费者才能压满网卡。

为什么不能传大包:

因dubbo协议采用单一长连接,

如果每次请求的数据包大小为500KByte,假设网络为千兆网卡(1024Mbit=128MByte),每条连接最大7MByte(不同的环境可能不一样,供参考),

单个服务提供者的TPS(每秒处理事务数)最大为:128MByte / 500KByte = 262。

单个消费者调用单个服务提供者的TPS(每秒处理事务数)最大为:7MByte / 500KByte = 14。

如果能接受,可以考虑使用,否则网络将成为瓶颈。

为什么采用异步单一长连接:

因为服务的现状大都是服务提供者少,通常只有几台机器,

而服务的消费者多,可能整个网站都在访问该服务,

比如Morgan的提供者只有6台提供者,却有上百台消费者,每天有1.5亿次调用,

如果采用常规的hessian服务,服务提供者很容易就被压跨,

通过单一连接,保证单一消费者不会压死提供者,

长连接,减少连接握手验证等,

并使用异步IO,复用线程池,防止C10K问题。

(1) 约束:

参数及返回值需实现Serializable接口参数及返回值不能自定义实现List, Map, Number, Date, Calendar等接口,只能用JDK自带的实现,因为hessian会做特殊处理,自定义实现类中的属性值都会丢失。()Hessian序列化,只传成员属性值和值的类型,不传方法或静态变量,兼容情况:(由吴亚军提供)

总结:会抛异常的情况:枚 举值一边多一种,一边少一种,正好使用了差别的那种,或者属性名相同,类型不同

接口增加方法,对客户端无影响,如果该方法不是客户端需要的,客户端不需要重新部署;

输入参数和结果集中增加属性,对客户端无影响,如果客户端并不需要新属性,不用重新

部署;

输入参数和结果集属性名变化,对客户端序列化无影响,但是如果客户端不重新部署,不管输入还是输出,属性名变化的属性值是获取不到的。

总结:服务器端和客户端对领域对象并不需要完全一致,而是按照最大匹配原则。

(2) 配置:

dubbo.properties:

rmi://

(+) (#)

如果服务接口继承了java.rmi.Remote接口,可以和原生RMI互操作,即: 提供者用Dubbo的RMI协议暴露服务,消费者直接用标准RMI接口调用,或者提供方用标准RMI暴露服务,消费方用Dubbo的RMI协议调用。如果服务接口没有继承java.rmi.Remote接口, 缺省Dubbo将自动生成一个com.xxx.XxxService$Remote的接口,并继承java.rmi.Remote接口,并以此接口暴露服务,但如果设置了<dubbo:protocol name="rmi" codec="spring" />,将不生成$Remote接口,而使用Spring的RmiInvocationHandler接口暴露服务,和Spring兼容。

Define rmi protocol:

Set default protocol:

Set service protocol:

Multi port:

Spring compatible:

Java标准的远程调用协议。

连接个数:多连接连接方式:短连接传输协议:TCP传输方式:同步传输序列化:Java标准二进制序列化适用范围:传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件。适用场景:常规远程服务方法调用,与原生RMI服务互操作

(1) 约束:

参数及返回值需实现Serializable接口dubbo配置中的超时时间对rmi无效,需使用java启动参数设置:-Dsun.rmi.transport.tcp.responseTimeout=3000,参见下面的RMI配置。

(2) 配置:

dubbo.properties:

(3) RMI配置:

更多RMI优化参数请查看:

/docs/cd/E17409_01/javase/6/docs/technotes/guides/rmi/sunrmiproperties.html

hessian://

(+) (#)

依赖:

可以和原生Hessian服务互操作,即:

提供者用Dubbo的Hessian协议暴露服务,消费者直接用标准Hessian接口调用,或者提供方用标准Hessian暴露服务,消费方用Dubbo的Hessian协议调用。

基于Hessian的远程调用协议。

连接个数:多连接连接方式:短连接传输协议:HTTP传输方式:同步传输序列化:Hessian二进制序列化适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。适用场景:页面传输,文件传输,或与原生hessian服务互操作

(1) 约束:

参数及返回值需实现Serializable接口参数及返回值不能自定义实现List, Map, Number, Date, Calendar等接口,只能用JDK自带的实现,因为hessian会做特殊处理,自定义实现类中的属性值都会丢失。

(2) 配置:

Define hessian protocol:

Set default protocol:

Set service protocol:

Multi port:

Directly provider:

h4. Jetty Server: (default)

h4. Servlet Bridge Server: (recommend)

web.xml:

注意,如果使用servlet派发请求:

协议的端口<dubbo:protocol port="8080" />必须与servlet容器的端口相同,协议的上下文路径<dubbo:protocol contextpath="foo" />必须与servlet应用的上下文路径相同。

http://

(+) (#)

基于http表单的远程调用协议。参见:[HTTP协议使用说明]

连接个数:多连接连接方式:短连接传输协议:HTTP传输方式:同步传输序列化:表单序列化适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。适用场景:需同时给应用程序和浏览器JS使用的服务。

(1) 约束:

参数及返回值需符合Bean规范

(2) 配置:

dubbo.xml:

h4. Jetty Server: (default)

h4. Servlet Bridge Server: (recommend)

web.xml:

注意,如果使用servlet派发请求:

协议的端口<dubbo:protocol port="8080" />必须与servlet容器的端口相同,协议的上下文路径<dubbo:protocol contextpath="foo" />必须与servlet应用的上下文路径相同。

webservice://

(+) (#)

依赖:

可以和原生WebService服务互操作,即:

提供者用Dubbo的WebService协议暴露服务,消费者直接用标准WebService接口调用,或者提供方用标准WebService暴露服务,消费方用Dubbo的WebService协议调用。

基于WebService的远程调用协议。

连接个数:多连接连接方式:短连接传输协议:HTTP传输方式:同步传输序列化:SOAP文本序列化适用场景:系统集成,跨语言调用。

(1) 约束:

参数及返回值需实现Serializable接口参数尽量使用基本类型和POJO。

(2) 配置:

Define hessian protocol:

Set default protocol:

Set service protocol:

Multi port:

Directly provider:

WSDL:

h4. Jetty Server: (default)

h4. Servlet Bridge Server: (recommend)

web.xml:

注意,如果使用servlet派发请求:

协议的端口<dubbo:protocol port="8080" />必须与servlet容器的端口相同,协议的上下文路径<dubbo:protocol contextpath="foo" />必须与servlet应用的上下文路径相同。

thrift://

(+) (#)

示例:/alibaba/dubbo/tree/master/dubbo-rpc/dubbo-rpc-thrift/src/test/java/com/alibaba/dubbo/rpc/protocol/thrift/examples

依赖:

所有服务共用一个端口:(与原生Thrift不兼容)

Thrift不支持数据类型:

null值 (不能在协议中传递null值)

memcached://

(+) (#)

可以通过脚本或监控中心手工填写表单注册memcached服务的地址:

然后在客户端使用时,不需要感知Memcached的地址:

或者,点对点直连:

也可以使用自定义接口:

方法名建议和memcached的标准方法名相同,即:get(key), set(key, value), delete(key)。

如果方法名和memcached的标准方法名不相同,则需要配置映射关系:(其中"p:xxx"为spring的标准p标签)

redis://

(+) (#)

可以通过脚本或监控中心手工填写表单注册redis服务的地址:

然后在客户端使用时,不需要感知Redis的地址:

或者,点对点直连:

也可以使用自定义接口:

方法名建议和redis的标准方法名相同,即:get(key), set(key, value), delete(key)。

如果方法名和redis的标准方法名不相同,则需要配置映射关系:(其中"p:xxx"为spring的标准p标签)

注册中心参考手册

(+) (#)

Multicast注册中心

(+) (#)

提供方启动时广播自己的地址。消费方启动时广播订阅请求。提供方收到订阅请求时,单播自己的地址给订阅者,如果设置了unicast=false,则广播给订阅者。消费方收到提供方地址时,连接该地址进行RPC调用。

Or:

为了减少广播量,Dubbo缺省使用单播发送提供者地址信息给消费者,

如果一个机器上同时启了多个消费者进程,消费者需声明unicast=false,否则只会有一个消费者能收到消息:

Or:

Zookeeper注册中心

(+) (#)

流程说明:

服务提供者启动时 向/dubbo/com.foo.BarService/providers目录下写入自己的URL地址。服务消费者启动时 订阅/dubbo/com.foo.BarService/providers目录下的提供者URL地址。并向/dubbo/com.foo.BarService/consumers目录下写入自己的URL地址。监控中心启动时 订阅/dubbo/com.foo.BarService目录下的所有提供者和消费者URL地址。

支持以下功能:

当提供者出现断电等异常停机时,注册中心能自动删除提供者信息。当注册中心重启时,能自动恢复注册数据,以及订阅请求。当会话过期时,能自动恢复注册数据,以及订阅请求。当设置<dubbo:registry check="false" />时,记录失败注册和订阅请求,后台定时重试。可通过<dubbo:registry username="admin" password="1234" />设置zookeeper登录信息。可通过<dubbo:registry group="dubbo" />设置zookeeper的根节点,不设置将使用无根树。支持*号通配符<dubbo:reference group="*" version="*" />,可订阅服务的所有分组和所有版本的提供者。

在provider和consumer中增加zookeeper客户端jar包依赖:

或直接下载:/maven2/org/apache/zookeeper/zookeeper

支持zkclient和curator两种Zookeeper客户端实现:

ZKClient Zookeeper Registry

从2.2.0版本开始缺省为zkclient实现,以提升zookeeper客户端的健状性。

缺省配置:

或:

或:

需依赖:

或直接下载:/maven2/com/github/sgroschupf/zkclient

Curator Zookeeper Registry

从2.3.0版本开始支持可选curator实现。

如果需要改为curator实现,请配置:

或:

或:

需依赖:

或直接下载:/maven2/com/netflix/curator/curator-framework

Zookeeper单机配置:

Or:

Zookeeper集群配置:

Or:

同一Zookeeper,分成多组注册中心:

Redis注册中心

(+) (#)

数据结构:

使用Redis的Key/Map结构存储数据。 主Key为服务名和类型。Map中的Key为URL地址。Map中的Value为过期时间,用于判断脏数据,脏数据由监控中心删除。(注意:服务器时间必需同步,否则过期检测会不准确)使用Redis的Publish/Subscribe事件通知数据变更。 通过事件的值区分事件类型:register, unregister, subscribe, unsubscribe。普通消费者直接订阅指定服务提供者的Key,只会收到指定服务的register, unregister事件。监控中心通过psubscribe功能订阅/dubbo/*,会收到所有服务的所有变更事件。

调用过程:

服务提供方启动时,向Key:/dubbo/com.foo.BarService/providers下,添加当前提供者的地址。并向Channel:/dubbo/com.foo.BarService/providers发送register事件。服务消费方启动时,从Channel:/dubbo/com.foo.BarService/providers订阅register和unregister事件。并向Key:/dubbo/com.foo.BarService/providers下,添加当前消费者的地址。服务消费方收到register和unregister事件后,从Key:/dubbo/com.foo.BarService/providers下获取提供者地址列表。服务监控中心启动时,从Channel:/dubbo/*订阅register和unregister,以及subscribe和unsubsribe事件。服务监控中心收到register和unregister事件后,从Key:/dubbo/com.foo.BarService/providers下获取提供者地址列表。服务监控中心收到subscribe和unsubsribe事件后,从Key:/dubbo/com.foo.BarService/consumers下获取消费者地址列表。

选项:

可通过<dubbo:registry group="dubbo" />设置redis中key的前缀,缺省为dubbo。可通过<dubbo:registry cluster="replicate" />设置redis集群策略,缺省为failover。 failover: 只写入和读取任意一台,失败时重试另一台,需要服务器端自行配置数据同步。replicate: 在客户端同时写入所有服务器,只读取单台,服务器端不需要同步,注册中心集群增大,性能压力也会更大。

Config redis registry:

Or:

Or:

Or:

Simple注册中心

(+) (#)

Export simple registry service:

Reference the simple registry service:

Or:

Simple监控中心

(+) (#)

1.1 暴露一个简单监控中心服务到注册中心: (如果是用安装包,不需要自己写这个配置,如果是自己实现监控中心,则需要)

1.2 通过注册中心发现监控中心服务:

或:

dubbo.properties

2.1 暴露一个简单监控中心服务,但不注册到注册中心: (如果是用安装包,不需要自己写这个配置,如果是自己实现监控中心,则需要)

2.2 直连监控中心服务:

或:

或:

dubbo.properties

Telnet命令参考手册

(+) (#)

Dubbo2.0.5以上版本服务提供端口支持telnet命令,

使用如:

telnet localhost 20880

或者:

echo status | nc -i 1 localhost 20880

telnet命令可以扩展,参见:扩展参考手册第6条。

status命令所检查的资源也可以扩展,参见:扩展参考手册第5条。

ls

(list services and methods)

ls

显示服务列表。

ls -l

显示服务详细信息列表。

ls XxxService

显示服务的方法列表。

ls -l XxxService

显示服务的方法详细信息列表。

ps

(print server ports and connections)

ps

显示服务端口列表。

ps -l

显示服务地址列表。

ps 20880

显示端口上的连接信息。

ps -l 20880

显示端口上的连接详细信息。

cd

(change default service)

cd XxxService

改变缺省服务,当设置了缺省服务,凡是需要输入服务名作为参数的命令,都可以省略服务参数。

cd /

取消缺省服务。

pwd

(print working default service)

pwd

显示当前缺省服务。

trace

trace XxxService

跟踪1次服务任意方法的调用情况。

trace XxxService 10

跟踪10次服务任意方法的调用情况。

trace XxxService xxxMethod

跟踪1次服务方法的调用情况

trace XxxService xxxMethod 10

跟踪10次服务方法的调用情况。

count

count XxxService

统计1次服务任意方法的调用情况。

count XxxService 10

统计10次服务任意方法的调用情况。

count XxxService xxxMethod

统计1次服务方法的调用情况。

count XxxService xxxMethod 10

统计10次服务方法的调用情况。

invoke

invoke XxxService.xxxMethod({"prop": "value"})

调用服务的方法。

invoke xxxMethod({"prop": "value"})

调用服务的方法(自动查找包含此方法的服务)。

status

status

显示汇总状态,该状态将汇总所有资源的状态,当全部OK时则显示OK,只要有一个ERROR则显示ERROR,只要有一个WARN则显示WARN。

status -l

显示状态列表。

log

2.0.6以上版本支持

log debug

修改dubbo logger的日志级别

log 100

查看file logger的最后100字符的日志

help

help

显示telnet命帮助信息。

help xxx

显示xxx命令的详细帮助信息。

clear

clear

清除屏幕上的内容。

clear 100

清除屏幕上的指定行数的内容。

exit

exit

退出当前telnet命令行。

Maven插件参考手册

(+) (#)

mvn dubbo:registry

mvn dubbo:registry

以缺省的9090端口启动一个简易注册中心

mvn dubbo:registry -Dport=9099

以指定的9099端口启动一个简易注册中心

mvn dubbo:create

(尚未发布)

mvn dubbo:create

生成demo服务提供者应用

mvn dubbo:create -Dapplication=xxx -Dpackage=com.alibaba.xxx -Dservice=XxxService,YyyService -Dversion=1.0.0

生成指定接口和版本的服务提供者应用

服务化最佳实践

(+) (#)

分包

建议将服务接口,服务模型,服务异常等均放在API包中,因为服务模型及异常也是API的一部分,

同时,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)如果需要,也可以考虑在API包中放置一份spring的引用配置,这样使用方,只需在Spring加载过程中引用此配置即可,

配置建议放在模块的包目录下,以免冲突,如:com/alibaba/china/xxx/dubbo-reference.xml

粒度

服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo暂未提供分布式事务支持。服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义,会给后期维护带来不便。

版本

每个接口都应定义版本号,为后续不兼容升级提供可能,如:<dubbo:service interface="com.xxx.XxxService" version="1.0" />建议使用两位版本号,因为第三位版本号通常表示兼容升级,只有不兼容时才需要变更服务版本。当不兼容时,先升级一半提供者为新版本,再将消费者全部升为新版本,然后将剩下的一半提供者升为新版本。

兼容性

服务接口增加方法,或服务模型增加字段,可向后兼容,删除方法或删除字段,将不兼容,枚举类型新增字段也不兼容,需通过变更版本号升级。各协议的兼容性不同,参见:服务协议

枚举值

如果是完备集,可以用Enum,比如:ENABLE, DISABLE。如果是业务种类,以后明显会有类型增加,不建议用Enum,可以用String代替。如果是在返回值中用了Enum,并新增了Enum值,建议先升级服务消费方,这样服务提供方不会返回新值。如果是在传入参数中用了Enum,并新增了Enum值,建议先升级服务提供方,这样服务消费方不会传入新值。

序列化

服务参数及返回值建议使用POJO对象,即通过set,get方法表示属性的对象。服务参数及返回值不建议使用接口,因为数据模型抽象的意义不大,并且序列化需要接口实现类的元信息,并不能起到隐藏实现的意图。服务参数及返回值都必需是byValue的,而不能是byRef的,消费方和提供方的参数或返回值引用并不是同一个,只是值相同,Dubbo不支持引用远程对象。

异常

建议使用异常汇报错误,而不是返回错误码,异常信息能携带更多信息,以及语义更友好,如果担心性能问题,在必要时,可以通过override掉异常类的fillInStackTrace()方法为空方法,使其不拷贝栈信息,查询方法不建议抛出checked异常,否则调用方在查询时将过多的try...catch,并且不能进行有效处理,服务提供方不应将DAO或SQL等异常抛给消费方,应在服务实现中对消费方不关心的异常进行包装,否则可能出现消费方无法反序列化相应异常。

调用

不要只是因为是Dubbo调用,而把调用Try-Catch起来。Try-Catch应该加上合适的回滚边界上。对于输入参数的校验逻辑在Provider端要有。如有性能上的考虑,服务实现者可以考虑在API包上加上服务Stub类来完成检验。

推荐用法

(+) (#)

在Provider上尽量多配置Consumer端属性

原因如下:

作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数,等等在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置可以作为Consumer的缺省值。

否则,Consumer会使用Consumer端的全局设置,这对于Provider不可控的,并且往往是不合理的

PS: 配置的覆盖规则:1) 方法级配置别优于接口级别,即小Scope优先 2) Consumer端配置 优于 Provider配置 优于 全局配置,最后是Dubbo Hard Code的配置值(见配置文档)

配置的覆盖规则详见:Dubbo配置参考手册

Provider上尽量多配置Consumer端的属性,让Provider实现者一开始就思考Provider服务特点、服务质量的问题。

示例:

在Provider可以配置的Consumer端属性有:

timeout,方法调用超时retries,失败重试次数,缺省是2(表示加上第一次调用,会调用3次)loadbalance,负载均衡算法(有多个Provider时,如何挑选Provider调用),缺省是随机(random)。

还可以有轮训(roundrobin)、最不活跃优先(leastactive,指从Consumer端并发调用最好的Provider,可以减少的反应慢的Provider的调用,因为反应更容易累积并发的调用)actives,消费者端,最大并发调用限制,即当Consumer对一个服务的并发调用到上限后,新调用会Wait直到超时。

在方法上配置(dubbo:method )则并发限制针对方法,在接口上配置(dubbo:service),则并发限制针对服务。

详细配置说明参见:Dubbo配置参考手册

Provider上配置合理的Provider端属性

Provider上可以配置的Provider端属性有:

threads,服务线程池大小executes,一个服务提供者并行执行请求上限,即当Provider对一个服务的并发调用到上限后,新调用会Wait(Consumer可能到超时)。在方法上配置(dubbo:method )则并发限制针对方法,在接口上配置(dubbo:service),则并发限制针对服务。

配置上管理信息

目前有负责人信息和组织信息(用于区分站点)。

有问题时便于的找到服务的负责人,至少写两个人以便备份。

负责人和组织的信息可以在注册中心的上看到。

示例:

应用配置负责人、组织

service配置负责人

reference配置负责人

dubbo:service、dubbo:reference没有配置负责人,则使用dubbo:application设置的负责人。

配置上Dubbo缓存文件

配置方法如下:

提供者列表缓存文件

注意:

文件的路径,应用可以根据需要调整,保证这个文件不会在发布过程中被清除。如果有多个应用进程注意不要使用同一个文件,避免内容被覆盖。

这个文件会缓存:

注册中心的列表服务提供者列表

有了这项配置后,当应用重启过程中,Dubbo注册中心不可用时则应用会从这个缓存文件读取服务提供者列表的信息,进一步保证应用可靠性。

监控配置

1. 使用固定端口暴露服务,而不要使用随机端口

这样在注册中心推送有延迟的情况下,消费者通过缓存列表也能调用到原地址,保证调用成功。

3. 使用Dragoon的http监控项监控注册中心上服务提供方

Dragoon监控服务在注册中心上的状态:http://dubbo-reg1..:8080/status/com.alibaba.morgan.member.MemberService:1.0.5,确保注册中心上有该服务的存在。

4. 服务提供方,使用Dragoon的telnet或shell监控项

监控服务提供者端口状态:echo status | nc --i 1 20880 | grep OK | wc --l,其中的20880为服务端口

5. 服务消费方,通过将服务强制转型为EchoService,并调用$echo()测试该服务的提供者是可用

如 assertEqauls(“OK”, ((EchoService)memberService).$echo(“OK”));

不要使用dubbo.properties文件配置,推荐使用对应XML配置

Dubbo2中所有的配置项都可以Spring配置中,并且可以针对单个服务配置。

# 如完全不配置使用Dubbo缺省值,参见Dubbo配置参考手册中的说明。

在Dubbo1中需要在dubbo.properties文件中的配置项,Dubbo2中配置示例如下:

1. 应用名

对应dubbo.properties中的Key名dubbo.application.name

2.注册中心地址

对应dubbo.properties中的Key名dubbo.registry.address

3. 调用超时

可以在多个配置项设置超时,由上至下覆盖(即上面的优先),示例如下:

# 其它的参数(retries、loadbalance、actives等)的覆盖策略也一样。

提供者端特定方法的配置

提供者端特定接口的配置

# timeout可以在多处设置,配置项及覆盖规则详见:Dubbo配置参考手册

全局配置项值,对应dubbo.properties中的Key名dubbo.service.invoke.timeout

5. 服务提供者协议、服务的监听端口

对应dubbo.properties中的Key名dubbo.service.protocol、dubbo.service.server.port

4.服务线程池大小

对应dubbo.properties中的Key名dubbo.service.max.thread.threads.size

6. 消费者启动时,没有提供者是否抛异常Fast-Fail

对应dubbo.properties中的Key名mons.dubbo.service.allow.no.provider

容量规划

如果觉得《dubbo 用户指南》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。