以下是Dubbo的一些最佳实践整理,可以当做一张Dubbo的使用说明书,具体的原理分析后续再详写,这里就言简意赅的说明用法,且大部分来自官方文档:

【一】服务化最佳实践

分包

  • 服务接口、服务模型、服务异常等均放在 API 包中,符合REP(重用发布原则),CRP(共同重用原则)

粒度

  • 服务接口尽可能大粒度,避免分布式事务,因为Dubbo暂未提供分布式事务支持。
  • 服务接口建议以业务场景为单位划分,并对相近业务做抽象。
  • 不建议使用过于抽象的通用接口,会给后期维护带来不便。

版本

  • 每个接口都应定义版本号。
  • 建议使用两位版本号。
  • 不兼容时,建议先升级一半提供者为新版本,再将消费者全部升为新版本,然后将剩下的一半提供者升为新版本。

枚举值

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

兼容性

  • 服务接口增加方法,或服务模型增加字段,可向后兼容。
  • 删除方法,删除字段,枚举类型新增字段将不兼容,需通过变更版本号升级。

序列化

  • 参数及返回值建议使用 POJO 对象
  • 参数及返回值不建议使用接口,抽象意义不大且不能隐藏实现意图
  • 参数及返回值都必须是传值调用,而不能是传引用调用,Dubbo不支持引用远程对象

异常

  • 建议使用异常汇报错误,而不是返回错误码,语义更友好。
  • 如果担心性能问题,可以通过 override 掉异常类的 fillInStackTrace() 方法为空方法。
  • 查询方法不建议抛出 checked 异常。
  • 服务提供方不应将 DAO 或 SQL 等异常抛给消费方,避免消费方无法反序列化相应异常。

调用

  • 提供方需要对输入参数进行校验。
  • 不要只是因为是 Dubbo 调用,而把调用 try...catch 起来

【二】关于配置的最佳实践

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

这样的配置可以让 Provider 的实现者一开始就思考 Provider 端的服务特点和服务质量等问题。建议在Provider端配置的属性有:

  1. timeout:方法调用的超时时间
  2. retries:失败重试次数,缺省是 2 (加上第一次调用,会调用 3 次)
  3. loadbalance:负载均衡算法(有多个 Provider 时,如何挑选 Provider 调用),缺省是随机 random。还可以配置轮询 roundrobin、最不活跃优先leastactive 和一致性哈希 consistenthash
  4. actives:消费者端的最大并发调用限制,即当 Consumer 对一个服务的并发调用到上限后,新调用会阻塞直到超时,在方法上配置 dubbo:method 则针对该方法进行并发限制,在接口上配置 dubbo:service,则针对该服务进行并发限制
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService"
    timeout="300" retries="2" loadbalance="random" actives="0" />
 
<dubbo:service interface="com.alibaba.hello.api.WorldService" version="1.0.0" ref="helloService"
    timeout="300" retries="2" loadbalance="random" actives="0" >
    <dubbo:method name="findAllPerson" timeout="10000" retries="9" loadbalance="leastactive" actives="5" />
<dubbo:service/>

这样做的考量有下面两个:

  1. 服务提供方,比消费方更清楚服务的性能参数,比如调用超时时间,合理的重试次数等

  2. Provider 端的配置可以作为 Consumer 的缺省值,否则对于Provider 是不可控的。

    • 配置的覆盖规则:

      1. 方法级别配置优于接口级别,即小 Scope 优先 2) Consumer 端配置优于 Provider 端配置,优于全局配置,最后是 Dubbo 硬编码的配置值

在 Provider 端配置合理的 Provider 端属性

建议在Provider端配置的属性有:

  1. threads:服务线程池大小
  2. executes:一个服务提供者并行执行请求上限,即当 Provider 对一个服务的并发调用达到上限后,新调用会阻塞,此时 Consumer 可能会超时。在方法上配置 dubbo:method 则针对该方法进行并发限制,在接口上配置 dubbo:service,则针对该服务进行并发限制
<dubbo:protocol threads="200" /> 
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService"
    executes="200" >
    <dubbo:method name="findAllPerson" executes="50" />
</dubbo:service>
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐