【微服务】Dubbo的最佳实践
以下是Dubbo的一些最佳实践整理,可以当做一张Dubbo的使用说明书,具体的原理分析后续再详写,这里就言简意赅的说明用法,且大部分来自官方文档:【一】服务化最佳实践分包服务接口、服务模型、服务异常等均放在 API 包中,符合REP(重用发布原则),CRP(共同重用原则)粒度服务接口尽可能大粒度,避免分布式事务,因为Dubbo暂未提供分布式事务支持。服务接口建议以业务场景为...
·
以下是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端配置的属性有:
timeout
:方法调用的超时时间retries
:失败重试次数,缺省是 2 (加上第一次调用,会调用 3 次)loadbalance
:负载均衡算法(有多个 Provider 时,如何挑选 Provider 调用),缺省是随机random
。还可以配置轮询roundrobin
、最不活跃优先leastactive
和一致性哈希consistenthash
等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/>
这样做的考量有下面两个:
-
服务提供方,比消费方更清楚服务的性能参数,比如调用超时时间,合理的重试次数等
-
Provider 端的配置可以作为 Consumer 的缺省值,否则对于Provider 是不可控的。
-
配置的覆盖规则:
- 方法级别配置优于接口级别,即小 Scope 优先 2) Consumer 端配置优于 Provider 端配置,优于全局配置,最后是 Dubbo 硬编码的配置值
-
在 Provider 端配置合理的 Provider 端属性
建议在Provider端配置的属性有:
threads
:服务线程池大小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>
更多推荐
已为社区贡献2条内容
所有评论(0)