dubbo做为一个服务治理框架,功能相对比较完善,性能也挺不错。但不少朋友在使用dubbo的时候,只是简单的参考官方说明进行搭建,并无过多的去思考一些关键参数的意义(也多是时间紧任务多,没空出来研究),最终作出来的效果有必定的打折。 这里我根据目前咱们项目的使用状况列出几个性能调优的参数及其意义,供你们参考。网络
在介绍参数以前,咱们先了解下dubbo中配置的优先级,以避免出现调优参数设置了却没发现效果实际是配置被覆盖致使这样的问题。dubbo分为consumer和provider端,在配置各个参数时,其优先级以下:并发
一、consumer的method配置 框架
二、provider的method配置异步
三、consumer的reference配置ide
四、provider的service配置性能
五、consumer的consumer节点配置spa
六、provider的provider节点配置线程
能够看到,方法级的配置优先级高于接口级,consumer的优先级高于provider。同时,在本地参数配置还存在一层优先级:netty
一、系统参数(-D),如-Ddubbo.protocol.port=20881xml
二、xml配置
三、property文件
了解了这两个优先级,调优起来才会更加清晰,省去了一些诸如配置设置了不生效这样的麻烦。注意,其实dubbo中还能够经过将配置写入注册中心的方式覆盖用户配置(优先级高于系统参数),这里不展开,有兴趣的同窗能够去看官方文档。接下来咱们看看dubbo的几个比较重要的调优参数,及其影响的方式和大概实现。
参数名 | 做用范围 | defult | 说明 | 备注 |
---|---|---|---|---|
actives | consumer | 0 | 每服务消费者每服务每方法最大并发调用数 | 0表示不限制 |
connections | consumer | 对每一个提供者的最大链接数,rmi、http、hessian等短链接协议表示限制链接数,dubbo等长链接协表示创建的长链接个数 | dubbo时为1,及复用单连接 | |
accepts | provider | 0 | 服务提供方最大可接受链接数 | 0表示不限制 |
iothreads | provider | cpu个数+1 | io线程池大小(固定大小) | |
threads | provider | 200 | 业务线程池大小(固定大小) | |
executes | provider | 0 | 服务提供者每服务每方法最大可并行执行请求数 | 0表示不限制 |
tps | provider | 指定时间内(默认60s)最大的可执行次数,注意与executes的区别 | 默认不开启 |
注意表中参数与图中的对应关系:
一、当consumer发起一个请求时,首先通过active limit(参数actives)进行方法级别的限制,其实现方式为CHM中存放计数器(AtomicInteger),请求时加1,请求完成(包括异常)减1,若是超过actives则等待有其余请求完成后重试或者超时后失败;
二、从多个链接(connections)中选择一个链接发送数据,对于默认的netty实现来讲,因为能够复用链接,默认一个链接就能够。不过若是你在压测,且只有一个consumer,一个provider,此时适当的加大connections确实可以加强网络传输能力。但线上业务因为有多个consumer多个provider,所以不建议增长connections参数;
三、链接到达provider时(如dubbo的初次链接),首先会判断总链接数是否超限(acceps),超过限制链接将被拒绝;
四、链接成功后,具体的请求交给io thread处理。io threads虽然是处理数据的读写,但io部分为异步,更多的消耗的是cpu,所以iothreads默认cpu个数+1是比较合理的设置,不建议调整此参数;
五、数据读取并反序列化之后,交给业务线程池处理,默认状况下线程池为fixed,且排队队列为0(queues),这种状况下,最大并发等于业务线程池大小(threads),若是但愿有请求的堆积能力,能够调整queues参数。若是但愿快速失败由其余节点处理(官方推荐方式),则不修改queues,只调整threads;
六、execute limit(参数executes)是方法级别的并发限制,原理与actives相似,只是少了等待的过程,即受限后当即失败;
七、tps,控制指定时间内(默认60s)的请求数。注意目前dubbo默认没有支持该参数,须要加一个META-INF/dubbo/com.alibaba.dubbo.rpc.Filter文件,文件内容为:
tps=com.alibaba.dubbo.rpc.filter.TpsLimitFilter
从上面的分析,能够看出若是consumer数*actives>provider数*threads且queues=0,则会存在部分请求没法申请到资源,重试也有很大概率失败。 当须要对一个接口的不一样方法进行不一样的并发控制时使用executes,不然调整threads就能够。