Dubbo基本原理与超时机制
一. dubbo基本原理
–高性能和透明化的RPC远程服务调用方案
–SOA服务治理方案
-Apache MINA 框架基于Reactor模型通信框架,基于tcp长连接
Dubbo缺省协议采用单一长连接和NIO异步通讯,
适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况
分析源代码,基本原理如下:
- client一个线程调用远程接口,生成一个唯一的ID(比如一段随机字符串,UUID等),Dubbo是使用AtomicLong从0开始累计数字的
- 将打包的方法调用信息(如调用的接口名称,方法名称,参数值列表等),和处理结果的回调对象callback,全部封装在一起,组成一个对象object
- 向专门存放调用信息的全局ConcurrentHashMap里面put(ID, object)
- 将ID和打包的方法调用信息封装成一对象connRequest,使用IoSession.write(connRequest)异步发送出去
- 当前线程再使用callback的get()方法试图获取远程返回的结果,在get()内部,则使用synchronized获取回调对象callback的锁, 再先检测是否已经获取到结果,如果没有,然后调用callback的wait()方法,释放callback上的锁,让当前线程处于等待状态。
- 服务端接收到请求并处理后,将结果(此结果中包含了前面的ID,即回传)发送给客户端,客户端socket连接上专门监听消息的线程收到消息,分析结果,取到ID,再从前面的ConcurrentHashMap里面get(ID),从而找到callback,将方法调用结果设置到callback对象里。
- 监听线程接着使用synchronized获取回调对象callback的锁(因为前面调用过wait(),那个线程已释放callback的锁了),再notifyAll(),唤醒前面处于等待状态的线程继续执行(callback的get()方法继续执行就能拿到调用结果了),至此,整个过程结束。
- 当前线程怎么让它“暂停”,等结果回来后,再向后执行?
答:先生成一个对象obj,在一个全局map里put(ID,obj)存放起来,再用synchronized获取obj锁,再调用obj.wait()让当前线程处于等待状态,然后另一消息监听线程等到服 务端结果来了后,再map.get(ID)找到obj,再用synchronized获取obj锁,再调用obj.notifyAll()唤醒前面处于等待状态的线程。
- 正如前面所说,Socket通信是一个全双工的方式,如果有多个线程同时进行远程方法调用,这时建立在client server之间的socket连接上会有很多双方发送的消息传递,前后顺序也可能是乱七八糟的,server处理完结果后,将结果消息发送给client,client收到很多消息,怎么知道哪个消息结果是原先哪个线程调用的?
答:使用一个ID,让其唯一,然后传递给服务端,再服务端又回传回来,这样就知道结果是原先哪个线程的了。
二. dubbo超时机制
dubbo是一种NIO模式,消费端发起请求后得到一个ResponseFuture,然后消费端一直轮询这个ResponseFuture直至超时或者收到服务端的返回结果
1.同步检测
public Object get(int timeout) throws RemotingException {//1 获取超时时间,该timeout是根据配置文件的优先级获取的if (timeout <= 0) {timeout = Constants.DEFAULT_TIMEOUT;}//2 如果response不为空,则代表返回报文已经接收到了if (!isDone()) {long start = System.currentTimeMillis();lock.lock();try {//3 循环检测返回报文是否已经接收到while (!isDone()) {//4 如果没有接到到,则释放线程,等待时间为超时时间,这里会有两种情况会被唤醒done.await(timeout, TimeUnit.MILLISECONDS);//5 判断是否超时if (isDone() || System.currentTimeMillis() - start > timeout) {break;}}} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}//6 如果循环结束,还没有完成,则说明超时了if (!isDone()) {throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false));}}return returnFromResponse();}
其中第4步中,线程被唤醒的情况有两种
1) 当接收到返回报文之后回调用done.signal();
2) 等待timeout毫秒后
如果数据返回了或者已经超时了,都会终止循环,最后判断是否是因为超时终止的。
这是dubbo的超时第一种机制
2.异步回调
dubbo是可以配置异步,那么设置异步模式的时候,在发送完消息之后,不会立即通过ResponseFuture的get方法来阻塞的获取返回结果,而是将future放入RpcContext中之后就返回了,刚才所说的在get中实现的超时机制就不会起作用了,所以dubbo还有第二种机制,先看下面的DefaultFuture源码片段
static {Thread th = new Thread(new RemotingInvocationTimeoutScan(), "DubboResponseTimeoutScanTimer");th.setDaemon(true);th.start();}
private static class RemotingInvocationTimeoutScan implements Runnable {public void run() {while (true) {try {//1 遍历所有FUTURES集合for (DefaultFuture future : FUTURES.values()) {if (future == null || future.isDone()) {continue;}//根据future记录的开始时间,判断是否已经超时if (System.currentTimeMillis() - future.getStartTimestamp() > future.getTimeout()) {// create exception response.Response timeoutResponse = new Response(future.getId());// set timeout status.timeoutResponse.setStatus(future.isSent() ? Response.SERVER_TIMEOUT : Response.CLIENT_TIMEOUT);timeoutResponse.setErrorMessage(future.getTimeoutMessage(true));// handle response.DefaultFuture.received(future.getChannel(), timeoutResponse);}}//休眠30秒Thread.sleep(30);} catch (Throwable e) {logger.error("Exception when scan the timeout invocation of remoting.", e);}}}}
首先在类加载的时候就会开启了一个子线程, 这个子线程就是不断的检测还没有接收到返回报文的future,验证每一个是否已经超时,如果超时则返回相应的超时报文,这种机制就保证了异步模式也具备超时这样的特性
Dubbo基本原理与超时机制相关推荐
- Dubbo超时机制导致的雪崩连接
Bug影响:Dubbo服务提供者出现无法获取Dubbo服务处理线程异常,后端DB爆出拿不到数据库连接池,导致前端响应时间异常飙高,系统处理能力下降,核心基础服务无法提供正常服务. Bug发现过程: ...
- dubbo的超时机制和重试机制
参考: https://www.cnblogs.com/ASPNET2008/p/7292472.html https://www.tuicool.com/articles/YfA3Ub https: ...
- dubbo重试机制原理_[转]dubbo重试机制和超时机制
dubbo启动时默认有重试机制和超时机制. 超时机制的规则是如果在一定的时间内,provider没有返回,则认为本次调用失败, 重试机制在出现调用失败时,会再次调用.如果在配置的调用次数内都失败,则认 ...
- TCP重传与超时机制:解锁网络性能之秘
目录标题 一.TCP重传(TCP Retransmission) 1.1 重传原理与机制(Retransmission Principles and Mechanisms) 二.TCP超时(TCP T ...
- Dubbo第三讲:Dubbo的可扩展机制SPI源码解析
本文是Dubbo第三讲:Dubbo的可扩展机制SPI源码解析 文章目录 1.Dubbo SPI机制 1.1.Dubbo具有良好拓展性的原因 1.2.Dubbo SPI和Java SPI的区别? 1.3 ...
- 关于Hystrix超时机制和线程状态的测试观察和个人理解
作者:未完成交响曲,资深Java工程师!目前在某一线互联网公司任职,架构师社区合伙人! 我们在使用Hystrix时,大部分情况下都是直接基于SpringCloud的相关注解来完成请求调用的.我们有个项 ...
- golang net/http 超时机制完全手册
目录 SetDeadline 服务器端超时设置 客户端超时设置 Cancel 和 Context 英文原始出处: The complete guide to Go net/http timeouts, ...
- .Net Cancellable Task - APM异步超时机制扩展
概述 .NET基于委托的APM(Asynchronous Programming Model)模式通过BeginInvoke, EndInvoke, AsyncCallback,IAsyncResul ...
- 超时机制,断路器模式简介
使用Hystrix保护应用,它是一种豪猪,他身上有很多的刺,所以他能保护自己,我们知道老外的项目,他的项目名称往往取得比较有格调,比较的生动形象,所以他可以保护这样的一个组件,起名叫Hystrix,我 ...
最新文章
- Hadoop Hive sql 语法详细解释
- 《Thinking in UML》读书笔记之一
- gpu的单位表示_GPU是如何工作的
- 获取客户端IP和MAC地址
- 一口气搞懂「链表」,就靠这20+张图了
- yum安装openoffice
- 在 Linux 下打包命令 tar 和压缩命令 7z 的配合使用示例
- mysql查询耗时_一种数据库高耗时查询的自动取消方法与流程
- 选择文件夹里指定文件图片路径_这简直是鼠标一拖,自动帮你整理好文件
- asp.net程序中最常用的三十三种编程代码(转自CSDN)
- [UEFI启动教程]移动硬盘安装U盘装机助理(双模式启动)
- linux 系统服务里没有系统服务,windows怎样添加系统服务|windows 添加不了系统服务怎么办|windows 添加系统服务方法-系统城...
- 使用Unified Communications Managed API获取Lync在线会议的链接地址
- 记一次戴尔灵越7000(7000-7591)的坑爹螺丝设计,中招了保修都没门
- 计算机毕业设计ssm网上花店系统0716c系统+程序+源码+lw+远程部署
- sns.relplot
- Python获取高德POI(关键词搜索法)
- 让网页FLASH变成黑白的css语句
- 【时序逻辑电路(sequential logic circuit)】
- Shaders for Game
热门文章
- 什么是云服务举例说明_云服务器有什么用?最好举例说明。
- 计算机病毒会危害计算机用户的身体健康,了解计算机病毒给我们生活带来巨大危害的事例(病毒名称爆发时间中毒后症状或造成的危害)...
- Java基础测试题 - 核心类库(一)
- 移动互联网下的服务转型――10086APP成长的探索
- Vysor Pro 2.2.2 Windows
- directx比较java,在DirectX中绘制多个2d形状
- JAVA随机读写功能实现类_Java 实现文件随机读写-RandomAccessFile
- 计算机组装 ppt,计算机组装第一单元.ppt
- 微软2016校园招聘在线笔试 B Professor Q's Software [ 拓扑图dp ]
- 一步5G手机进入5G时代?这只是一个开始