高并发请求dubbo超时,参数调优说明

 dubbo作为一个服务治理框架,功能相对比较完善,性能也挺不错。但很多朋友在使用dubbo的时候,只是简单的参考官方说明进行搭建,并没有过多的去思考一些关键参数的意义,最终做出来的效果有一定的打折。 这里我根据目前我们项目的使用情况列出几个性能调优的参数及其意义。

        在介绍参数之前,我们先了解下dubbo中配置的优先级,以免出现调优参数设置了却没发现效果实际是配置被覆盖导致这样的问题。dubbo分为consumer和provider端,在配置各个参数时,其优先级如下:

1、consumer的method配置 

2、provider的method配置

3、consumer的reference配置

4、provider的service配置

5、consumer的consumer节点配置

6、provider的provider节点配置

可以看到,方法级的配置优先级高于接口级,consumer的优先级高于provider。同时,在本地参数配置还存在一层优先级:

1、系统参数(-D),如-Ddubbo.protocol.port=20003

2、xml配置

3、property文件

         了解了这两个优先级,调优起来才会更加清晰,省去了一些诸如配置设置了不生效这样的麻烦。注意,其实dubbo中还可以通过将配置写入注册中心的方式覆盖用户配置(优先级高于系统参数),这里不展开,有兴趣的同学可以去看官方文档。接下来我们看看dubbo的几个比较重要的调优参数,及其影响的方式和大概实现。

          

参数名作用范围默认值说明备注
activesconsumer0每服务消费者每服务每方法最大并发调用数0表示不限制
connectionsconsumer 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数dubbo时为1,及复用单链接
acceptsprovider0服务提供方最大可接受连接数0表示不限制
iothreadsprovidercpu个数+1io线程池大小(固定大小) 
threadsprovider200业务线程池大小(固定大小) 
executesprovider0服务提供者每服务每方法最大可并行执行请求数0表示不限制
tpsprovider 指定时间内(默认60s)最大的可执行次数,注意与executes的区别默认不开启


 

 

 

 

 

 

 

 

 

 

 

 

 

        注意表中参数与图中的对应关系:

        1、当consumer发起一个请求时,首先经过active limit(参数actives消费端最大并发调用数)进行方法级别的限制,其实现方式为CHM中存放计数器,请求时加1,请求完成(包括异常)减1,如果超过actives则等待有其他请求完成后重试或者超时后失败;

        2、从多个连接(connections)中选择一个连接发送数据,对于默认的netty实现来说,由于可以复用连接,默认一个连接就可以。不过如果你在压测,且只有一个consumer,一个provider,此时适当的加大connections确实能够增强网络传输能力。但线上业务由于有多个consumer多个provider,因此不建议增加connections参数;

        3、连接到达provider时(如dubbo的初次连接),首先会判断总连接数是否超限(acceps),超过限制连接将被拒绝;

        4、连接成功后,具体的请求交给io thread处理。io threads虽然是处理数据的读写,但io部分为异步,更多的消耗的是cpu,因此iothreads默认cpu个数+1是比较合理的设置,不建议调整此参数;

        5、数据读取并反序列化以后,交给业务线程池处理,默认情况下线程池为fixed,且排队队列为0(queues),这种情况下,最大并发等于业务线程池大小(threads),如果希望有请求的堆积能力,可以调整queues参数。如果希望快速失败由其他节点处理(官方推荐方式),则不修改queues,只调整threads;

        6、execute limit(参数executes)是方法级别的并发限制,原理与actives类似,只是少了等待的过程,即受限后立即失败;

        7、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就可以。

    如果到达dubbo连接,acceps默认最大连接数是100,如果没有进行配置且超过最大连接数,则会连接超时,超过限制连接将被拒绝

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dubbo请求超时源码主要涉及到以下几个部分: 1. 超时参数的设置 在Dubbo中,请求超时时间可以通过`timeout`参数进行设置。该参数默认值为`1000`毫秒。在服务提供者和消费者端,Dubbo框架会通过`Invoker`接口的实现类`AbstractInvoker`来获取`timeout`参数的值,并将其转化为`long`类型的`timeout`属性。在`AbstractInvoker`的`invoke`方法中,会将`timeout`属性作为参数传递给`AsyncRpcResult`类的构造方法,以便在异步调用的过程中使用。 2. 请求超时的处理 在Dubbo中,请求超时的处理是通过`TimeoutFilter`过滤器实现的。该过滤器会对服务消费者发起的请求进行拦截,并在指定的时间内检查请求是否已经得到响应。如果请求超时,`TimeoutFilter`会抛出`RpcException`异常,并将异常信息返回给服务消费者。在`TimeoutFilter`的`invoke`方法中,首先会获取`timeout`属性的值,并将其转化为`long`类型的`timeout`变量。然后,通过`RpcContext`类的`isAsync`方法判断当前是否为异步调用。如果是异步调用,则会创建`TimeoutTask`类的实例,并将其提交到线程池中进行执行。`TimeoutTask`类的`run`方法中,会检查当前请求是否已经得到响应,如果超时则抛出`RpcException`异常。 在服务提供者端,Dubbo框架通过`Invoker`接口的实现类`AbstractInvoker`来获取`timeout`参数的值,并将其转化为`long`类型的`timeout`属性。在`AbstractInvoker`的`invoke`方法中,会将`timeout`属性作为参数传递给`RpcContext`类的`set`方法,并将`RpcContext`对象绑定到当前线程中。在服务提供者端,超时的处理主要是通过`RpcContext`类的`get`方法来判断当前请求是否已经超时。如果请求已经超时,则会抛出`RpcException`异常。 3. 超时时间的计算 在Dubbo中,超时时间的计算主要是通过`RpcContext`类的`get`和`set`方法实现的。在服务提供者端,Dubbo框架会在接收到请求后,通过`RpcContext`类的`set`方法将当前时间戳保存到`startTime`属性中。在服务消费者端,Dubbo框架会在发起请求之前,通过`RpcContext`类的`set`方法将当前时间戳保存到`requestTime`属性中。在`TimeoutFilter`过滤器中,会通过`RpcContext`类的`get`方法获取`requestTime`和`startTime`属性的值,并通过计算得到当前请求超时时间。同时,`TimeoutFilter`还会通过`RpcContext`类的`set`方法将当前请求超时时间保存到`timeout`属性中,以便在异步调用的过程中使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值