一 占位

待整理。。

二 问题汇总

1 谈谈dubbo的超时重试

dubbo 启动时默认有重试机制和超时机制。如果在一定的时间内,provider没有返回,则认为本次调用失败。重试机制出现在调用失败时,会再次调用,如果在配置的调用次数内都失败,则认为此次请求异常,消费端出现RpcException提示retry了多少次还是失败。

如果出现超时,通常是业务处理太慢,可在服务提供方执行 jstack PID > jstack.log 分析线程都卡在哪个方法调用上。如果不能调优性能,请将timeout设大。

dubbo消费端设置的超时时间需要根据业务实际情况来设定,如果设置的过短,一些复杂业务需要很长时间完成,导致在设定的超时时间内无法完成正常的业务处理。这样消费端达到超时时间,那么dubbo会进行重试,不合理的重试在一些特殊的业务场景下可能会引发很多问题。比如发送邮件,可能会发出多份重复邮件等。

dubbo调用服务不成功时,默认会重试两次。dubbo的路由机制,会把超时的请求路由到其他机器上,而不是本机尝试,所以dubbo的重试机制也能得到一定程度的保证。但是不合理地配置重试次数,当失败时会进行重试多次,这样在某个时间点出现性能问题,调用方继续重试请求为正常retries倍,容易引起服务雪崩。

最佳实践:

1.对于核心的服务中心,去除dubbo超时重试机制,并重新评估设置超时时间。
2.业务处理代码必须放在服务端,客户端只做参数验证和服务调用,不涉及业务流程处理

2 dubbo的provider和consumer都配置timeout超时时间, 以哪个为准

在dubbo的provider和consumer的配置文件中,如果都配置了timeout的超时时间,dubbo默认以consumer中配置的时间为准

provider.xml的配置:

<dubbo:service timeout="4000" retries="0" interface="com.dingding.tms.bms.service.BillingZfbCodOrderService" ref="billingZfbCodOrderService" registry="globalRegistry"/>

conusmer中的配置:

<dubbo:reference id="billingInterService" interface="com.dingding.tms.bms.service.BillingInterService" protocol="dubbo" check="false" registry="globalRegistry" timeout="3000"/>

最后这个service在调用时的超时时间就是3秒

另外,超过3s后的表现如下:

(1) consumer会在超过3秒时得到一个调用超时的异常。

(2) provider中代码的执行不会因为超时而中断,在执行完毕后,会得到一个dubbo的警告。

3 关于dubbo的配置上,你有什么经验

(1) 在Provider上尽量多地配置Consumer的属性

原因:

a. 作为服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数等

b. 在provider配置后,consumer不配置则自动使用provider的配置,即作为了consumer端的缺省值。否则,consumer会使用consumer端的全局配置,这对于provider端往往是不可控的。

ps: 配置的优先级:

1. 方法级配置别优于接口级别,即小Scope优先 
2. Consumer端配置优于Provider配置,优于全局配置 
3. Dubbo Hard Code的配置值(默认)

根据规则2, 纵使消费端配置优于服务器配置,但消费端配置超时时间不能随心所欲,需要根据业务实际情况来设定。如果设置的太短,复杂业务本来就需要很长时间完成,服务端无法在设定的超时时间内完成业务处理; 如果设置太长,会由于服务端或者网络问题导致客户端大量线程挂起。

配置示例

<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService"
timeout="300" retry="2" loadbalance="random" actives="0"/> <dubbo:service interface="com.alibaba.hello.api.WorldService" version="1.0.0" ref="helloService"
timeout="300" retry="2" loadbalance="random" actives="0" >
<dubbo:method name="findAllPerson" timeout="10000" retries="9" loadbalance="leastactive" actives="5" />
<dubbo:service/>

在provider端可以配置的consumer属性有:

1 timeout 方法调用超时时间

2 retry 失败重试次数,缺省是2(加上第一次调用,共调用三次)

3 loadbalance 负责均衡算法(即多个provider如何挑选provider调用),缺省是随机(random),还可以有轮训(roundrobin),最不活跃优先(leastactive, 指从consumer端并发调用效果最好的provider,这样可以相对减少并发的堆积)

4 actives 消费端最大并发调用限制,即当consumer对一个服务的并发调用达到上限后,新调用会wait直到超时。粒度上,在方法上配置(dubbo: method)则并发针对方法,在接口上配置(dubbo:service)则并发限制针对服务

(2) 在Provider上配置合理的provider属性

<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>

Provider上可以配置的Provider端属性有:

  1. threads,服务线程池大小
  2. executes,一个服务提供者并行执行请求上限,即当Provider对一个服务的并发调用到上限后,新调用会wait(Consumer可能到超时)。在方法上配置(dubbo:method )则并发限制针对方法,在接口上配置(dubbo:service),则并发限制针对服务。

超时配置:

Dubbo消费端 
全局超时配置

<dubbo:consumer timeout="5000" />

指定接口以及特定方法超时配置

<dubbo:reference interface="com.foo.BarService" timeout="2000">
<dubbo:method name="sayHello" timeout="3000" />
</dubbo:reference>

Dubbo服务端 
全局超时配置

<dubbo:provider timeout="5000" />

指定接口以及特定方法超时配置

<dubbo:provider interface="com.foo.BarService" timeout="2000">
<dubbo:method name="sayHello" timeout="3000" />
</dubbo:provider>

4 dubbo协议超时实现

Dubbo协议超时实现使用了Future模式,主要涉及类DubboInvoker,ResponseFuture, DefaultFuture。 
ResponseFuture.get()在请求还未处理完或未到超时前一直是wait状态;响应达到后,设置请求状态,并进行notify唤醒。

public Object get() throws RemotingException {
return get(timeout);
} public Object get(int timeout) throws RemotingException {
if (timeout <= 0) {
timeout = Constants.DEFAULT_TIMEOUT;
}
if (! isDone()) {
long start = System.currentTimeMillis();
lock.lock();
try {
while (! isDone()) {
done.await(timeout, TimeUnit.MILLISECONDS);
if (isDone() || System.currentTimeMillis() - start > timeout) {
break;
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
if (! isDone()) {
throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false));
}
}
return returnFromResponse();
}
    public static void received(Channel channel, Response response) {
try {
DefaultFuture future = FUTURES.remove(response.getId());
if (future != null) {
future.doReceived(response);
} else {
logger.warn("The timeout response finally returned at "
+ (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()))
+ ", response " + response
+ (channel == null ? "" : ", channel: " + channel.getLocalAddress()
+ " -> " + channel.getRemoteAddress()));
}
} finally {
CHANNELS.remove(response.getId());
}
} private void doReceived(Response res) {
lock.lock();
try {
response = res;
if (done != null) {
done.signal();
}
} finally {
lock.unlock();
}
if (callback != null) {
invokeCallback(callback);
}
}

@see http://shiyanjun.cn/archives/325.html dubbo架构设计详解

dubbo探究的更多相关文章

  1. 探究Dubbo的拓展机制: 上

    这篇博文是我决心深度学习Dubbo框架时记录的笔记, 主题是Dubbo的拓展点, 下面的几个部分相对来说比较零散, 貌似是不和主题挂钩的 , 并且是一些很冷门的知识点 , 但是它们确实是深入学习Dub ...

  2. 探究Dubbo的拓展机制: 下

    承接上篇, 本篇博文的主题就是认认真真捋一捋, 看一下 Dubbo是如何实现他的IOC / AOP / 以及Dubbo SPI这个拓展点的 总览: 本篇的话总体上分成两部分进行展开 第一点就是 Dub ...

  3. 通过单元测试理解spring容器以及dubbo+zookeeper单元测试异常处理

    一.先说一个结论:单元测试与主项目的spring容器是隔离的,也就是说,单元测试无法访问主项目spring容器,需要自己加载spring容器. 接下来是代码实例,WEB主项目出于运行状态,单元测试中可 ...

  4. Dubbo 源码分析 - 服务导出

    1.服务导出过程 本篇文章,我们来研究一下 Dubbo 导出服务的过程.Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可 ...

  5. 面试官问我,使用Dubbo有没有遇到一些坑?我笑了

    17年的时候,因为一时冲动没把持住(当然最近也有粉丝叫我再冲动一把再更新一波),结合面试题写了一个系列的Dubbo源码解析.目前公众号大部分粉丝都是之前的粉丝,这里不过多介绍. 根据我的面试经验而言, ...

  6. Dubbo RPC源码解读

    https://yq.aliyun.com/articles/272405#27 本文代码摘录的时候,将一些与本流程无关的内容去掉了,如有需要请看源码. 一.闲言碎语 使用rpc框架已经多年了,虽然之 ...

  7. 深入浅出微服务框架dubbo(一):基础篇

    一.基础篇 1.1 开篇说明 dubbo是一个分布式服务框架,致力于提供高性能透明化RPC远程调用方案,提供SOA服务治理解决方案.本文旨在将对dubbo的使用和学习总结起来,深入源码探究原理,以备今 ...

  8. Dubbo源码学习之-SPI介绍

    前言 学习之路还是要戒骄戒躁,一以贯之的积累前行.之前的公司部门技术达人少,自己总向往那些技术牛人多的团队,想象自己进去之后能跟别人学到多少东西.如今进到一个这样的团队之后,却发现之前自己的想法过于幼 ...

  9. 超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个简单的分布式服务

    来自:JavaGuide Github 地址:https://github.com/Snailclimb/springboot-integration-examples 目录: 使用 SpringBo ...

随机推荐

  1. C语言中怎样定义能够保存16进制整数的变量

    可以通过int 或long int存储,16进制整数说到底还是整数,16进制只是一种记数方式.例如,int x=0x16;十六进制(hexadecimal)只是计算机中数据的一种表示方法,规则是“逢十 ...

  2. [CERC2015]Juice Junctions(边双连通+字符串hash)

    做法 考虑边数限制的特殊条件,显然答案仅有\(\{0,1,2,3\}\) 0:不联通 1:连通 2:边双连通 3:任意删掉一条边都为边双连通 考虑每次删边后记录各点的边双染色情况来特判\(3\):是否 ...

  3. [PKUSC2018]最大前缀和——状压DP

    题目链接: [PKUSC2018]最大前缀和 设$f[S]$表示二进制状态为$S$的序列,任意前缀和都小于等于$0$的方案数. 设$g[S]$表示二进制状态为$S$的序列是整个序列的最大前缀和的方案数 ...

  4. Arts打卡第9周

    Algorithm.主要是为了编程训练和学习. 每周至少做一个 leetcode 的算法题(先从Easy开始,然后再Medium,最后才Hard). 进行编程训练,如果不训练你看再多的算法书,你依然不 ...

  5. nrm切换npm包源

    nrm可以随时切换npm包的源 npm install -g nrm 安装nrm完成 查看nrm源 nrm ls 切换源 npm use npm #也可以切换成其他源 

  6. C#实现获取当前文件路径的上级路径

    界面: 声明: textBox1.Text为指定文件路径:string path = @"F:\ABB-pragram\ABB工作站\ABB Station\Systems\Situatio ...

  7. linux几种传输方式与拷贝方式的性能分析

    本文记录linux系统中文件传输的多种方式,留作备忘.linux中文件传输的方式有ftp,scp,rsync,rz,sz等,但各个工具的功能又有所区别: FTP : FTP是文件服务器,可实现文件的上 ...

  8. cin中的注意事项

    猎豹网校C++ Primer学习笔记 - ostartech - 博客园 https://www.cnblogs.com/wxl845235800/p/11396323.html 在VS中使用cin& ...

  9. 【分类算法】感知机(Perceptron)

    0 - 算法描述 感知机算法是一类二分类算法,其问题描述为,给定一个训练数据集 $$T=\{(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)\},$$ 其中$x_i\in \m ...

  10. js 点击列表li,获得当前li的id

    html <ul id="demo"> <li id="li-1">li1</li> <li id="li- ...