Dubbox 学习笔记,本文观点仅代表个人理解,如有错误之处,请留言指正,谢谢。
本文主要根据Dubbox用户手册进行学习,从提供的配置去看dubbox的全貌,没有从源码角度去分析,而是从应用的角度上去学习。
1、dubbo配置学习
1) dubbo:protocol 服务提供方协议配置,如果需要支持多协议,我可以声明多个
dubbo:protocol标签,并在 dubbo:service标签的protocol属性中指定。
dubbo:protocol标签配置项如下:
id
name
port
host
threadpool (fixed | cache)
threads
iothreads
accepts
payload 请求即响应包大小,默认8M,单位字节
codec
serialization
accesslog
path
transport
server
client
dispatcher
queues 默认为0,线程池队列长度
charset
buffer
heatbeat
telnet
register
contextpath
从这些配置项中我学到了什么
1)线程模型
1、通信相关参数
transport netty,mina等NIO框架,指定client ----> server 从server--->client的网络通信模式,默认使用netty
server
client 单独指定server与client端的通信NIO框架。
2、序列化,编码、解码
codec与serialization 需重点学习与了解。
3、线程池,派发方面
threads 指定处理业务的线程池大小,也就是implement处线程池大小
threadpool 线程池类别,默认为fixed(固定大小),可选值 cache
iothreads 处理连接的线程数,iothreads线程接收请求后,通过dispather将连接派发到线程池处理。dubbo协议默认使用单一长连接,是否可以这样理
解,如果iothreads设置为2,dubbo会为 每服务每服务端每消费端 提供两条长连接。
queues 线程池队列长度,建议设置为0,如果线程池满了,应该立即失败,去尝试其他服务提供者。
accepts
payload 请求包与响应包大小,单位为字节,默认为8M
dispatcher :可选值为 all direct message,execution connection,默认为ll
all : 所有的消息都派发到线程池,包括请求,响应,连接事件、断开事件、心跳。
direct 所有的消息都不派发到线程池,直接在IO线程上执行。
message 只有请求、响应消息派发到线程池,其他如断开事件,连接事件
、心跳等在IO线程上执行
execution,只请求消息派发到线程池,响应和其他连接比如断开事件都在IO线程上执行。
connection 在IO线程上,将连接断开事件放入队列,有序逐个执行,其他消息转发到线程池。
疑问:execution,,响应不在IO线程上执行,是什么个意思,那整个流程是怎么交互的呢?
对all,direct message模式理解,对execution模式不理解。
2)<dubbo:registry> 注册中心配置,如果有多个注册中心,可以声明多个标签,并在dubbo:service或dubbo:refercence中
的registry属性指定要注册到哪些注册中心。
相关配置属性:
id
address
protocol
port
username
password
transport
timeout
session
file
wait
register
subscribe
dynamic
从这些标签中学到了什么:
address 协议://host:ip
procotol
host
port
file 标签,可以将注册中心列表,提供者列表缓存在本地文件中。
transport 网络通信模式,可选值 netty mina
register 是否注册
subscribe 是否从注册中心订阅服务。
3、 dubbo:service 服务提供者声明标签
interface
ref
version
group 服务分组,如果一个接口有多个实现时,可以用分组来区分。
path
delay 服务延迟暴露,-1表示当spring容器初始化后在暴露。
timeout
retries
connections 对每个服务提供者最大的连接数。
loadbalance 负载均衡算法
async 是否为异步调用
stub
mock
token
registry
provider 指定默认属性关联
depreacated 是否过期
dynamic 是否动态上下线
accesslog
owner
document
weight
executes 服务提供者每服务每方法最大可并行执行请求数
actives 每服务每消费者每服务每方法最大可并行请求数
proxy 生成动态代理方式
cluster 集群方式
filter
listener
protocol
layer
register
重要属性学习:
interface 接口名称
delay 设置为-1,表示等待Spring容器初始化后,再暴露服务。
timeout 设置服务调用超时时间,单位为毫秒。
retries 设置重试次数,默认为2,表示重试次,最多调用3次。
connections 服务最大连接数
loadbalance 负载均衡算法,默认random, roudbin(轮询)、最小负载。
stub 表示本地存根,在调用服务之前调用
mock 表示服务调用后执行出现RpcException时执行。
cluster 集群方式,主要有failover failfast failsafe failback forking
failover
失败自动切换,当出现失败时,重试其他服务器(缺省)
通常用于读操作,幂等操作。
failfast
快速失败,只发起一次调用,失败立即报错。
通常用于非幂等性的写操作,比如新增记录。
failback
失败后自动恢复,后台记录失败请求,定时重发。
通常用于消息通知操作
forking
并行调用多个服务器,只要一个返回即成功。
通常用于实时性要求较高的读操作,但会浪费更多服务器资源。
可以通过设置forks=2 来设置最大并行数。
broadcast
广播调用所有提供者,逐个调用,任意一台报错即报错。
通常用于通知所有提供者更新缓存或日志等本地资源信息。
4、 dubbo:reference 服务消费者引用服务配置
id
interface
version
group
timeout
retries
connections
async
generic
check
url 直连服务提供者
stub
mock
cache
validation
proxy
client
owner
actives
cluster
filter
listener
init
protocol
2、dubbo常用问题学习
1)dubbo协议缺省 每服务每提供者每消费者使用单一长连接,如果数据传输量大,
可以考虑使用多条连接。
<dubbo:service connections="0"> 表示使用JVM共享长连接. 什么是JVM共享长连接。
<dubbo:service connections="1"> 表示使用独立长连接
<dubbo:server connections="2"> 表示使用两条长连接。
2)
3、服务化最佳实践
1、分包
1)建议将服务接口,服务模型,服务异常等都放到API包中。
实际使用情况:
服务类接口放在API包中,服务模型放在服务提供方;接口返回值,接口
参数使用一个上下文对接,服务模型在服务提供方序列化为JSON字符串。
2、粒度
1)、服务接口尽可能大粒度,每个服务方法代表一个功能,而不是一个功能的
一个步骤,否则将面临分布式事务。
2)、服务接口建议以业务场景为单位,将相近的业务做抽象,这样避免接口爆
炸,也有利于服务治理,比如降级。
3)、不建议使用过于抽象的通用接口,如Map query(Map)这样接口没有明
确的语义,会给后期维护带来不便。
实际使用情况
遵从1、2两点,服务接口的声明类似
RainbowContent sendTopic(RainbowContent);关于维护性,我们规定
Dao层的接口,不使用过于抽象的通用声明,坚决不使用Map query(Map),来尽
量保证可维护性。
3、版本
1)每个接口都应对应版本号,为后续不兼容升级提供可能
2)建议使用两位版本号,因为第三位版本号通常表示兼容版本号。
3)当不兼容时,先升级一半提供者为新版本,再将消费者全部升级为新版本,然后将
另一半提供者升级为新版本。
目前:我们在dubbo服务这层,没有使用版本号。
4、兼容性
服务接口增加方法,服务模型增加字段,可向后兼容。这也是做接口特别需要注意的地
方,要尽量兼容以前版本;如果不兼容,接口应该应该与客户端制定版本约定。
5、异常
1)建议使用异常汇报错误,而不是返回错误码,异常信息能携带更多的语义提示。
2)如果担心性能问题,在必要时,可以通过ovverride将异常类的fillInStackTrace()方
法覆盖为空方法。
3)查询方法不建议抛出chcked异常。
4)服务提供方不应该将DAO或SQL等异常抛出给消费方。
4、推荐用法
1)在Provider上尽量多配置Consumer端属性。
原因如下:
1、作为服务的提供方,比服务使用方更清楚服务性能参数,比如调用的超时时间、
合理的重试次数等。
2、在Provider配置后,Customer不配置则会使用服务端的配置值,即Provider方
的配置可以作为Consumer端的缺省配置,否则会使用Consumer端的全局配
置。在服务端多配置Consumer端的属性,让Provider实现者一开始就思考
Provider服务特点、服务质量问题。
2)在服务端可以配置如下客户端属性
timeout 方法调用超时时间
retries 失败重试次数,缺省为2,表示最多调用3次。
loadbalances 负载均衡算法,默认为随机(加权),还有轮询,最不活跃
actives 消费者端,最大并发调用限制,即当Consumer对一个服务的
并发调用达到上限,新的调用会wait直到超时。
3)在服务端配置合理的Provider属性。
threads 服务线程池大小
queues 服务线程队列长度,默认为0,如果线程池的已满,已经返回错误,引导连接重试。
executes 一个服务提供者并行执行请求的上限。需要查阅executes与
activies的区别。
4)配置管理上信息
5)配置dubbo缓存文件
<dubbo:registry file="${user.home}/output/dubbo.cache"/>
1、文件的路径,应用可以根据需要调整,保证这个文件不会在发布过程中被清除。
2、如果有多个应用进程注意不要使用同一个文件,避免内容被覆盖。
这个文件会缓存 注册中心的列表、服务提供者列表。
待解决问题:
1、如何测试压满连接
2、dubbo各协议比较。
3、序列化方式比较
4、监控中心。