一. dubbo基本原理

–高性能和透明化的RPC远程服务调用方案

–SOA服务治理方案

-Apache MINA 框架基于Reactor模型通信框架,基于tcp长连接

Dubbo缺省协议采用单一长连接和NIO异步通讯,
适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况
分析源代码,基本原理如下:

  1. client一个线程调用远程接口,生成一个唯一的ID(比如一段随机字符串,UUID等),Dubbo是使用AtomicLong从0开始累计数字的
  2. 将打包的方法调用信息(如调用的接口名称,方法名称,参数值列表等),和处理结果的回调对象callback,全部封装在一起,组成一个对象object
  3. 向专门存放调用信息的全局ConcurrentHashMap里面put(ID, object)
  4. 将ID和打包的方法调用信息封装成一对象connRequest,使用IoSession.write(connRequest)异步发送出去
  5. 当前线程再使用callback的get()方法试图获取远程返回的结果,在get()内部,则使用synchronized获取回调对象callback的锁, 再先检测是否已经获取到结果,如果没有,然后调用callback的wait()方法,释放callback上的锁,让当前线程处于等待状态。
  6. 服务端接收到请求并处理后,将结果(此结果中包含了前面的ID,即回传)发送给客户端,客户端socket连接上专门监听消息的线程收到消息,分析结果,取到ID,再从前面的ConcurrentHashMap里面get(ID),从而找到callback,将方法调用结果设置到callback对象里。
  7. 监听线程接着使用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基本原理与超时机制相关推荐

  1. Dubbo超时机制导致的雪崩连接

    Bug影响:Dubbo服务提供者出现无法获取Dubbo服务处理线程异常,后端DB爆出拿不到数据库连接池,导致前端响应时间异常飙高,系统处理能力下降,核心基础服务无法提供正常服务. ​Bug发现过程: ...

  2. dubbo的超时机制和重试机制

    参考: https://www.cnblogs.com/ASPNET2008/p/7292472.html https://www.tuicool.com/articles/YfA3Ub https: ...

  3. dubbo重试机制原理_[转]dubbo重试机制和超时机制

    dubbo启动时默认有重试机制和超时机制. 超时机制的规则是如果在一定的时间内,provider没有返回,则认为本次调用失败, 重试机制在出现调用失败时,会再次调用.如果在配置的调用次数内都失败,则认 ...

  4. TCP重传与超时机制:解锁网络性能之秘

    目录标题 一.TCP重传(TCP Retransmission) 1.1 重传原理与机制(Retransmission Principles and Mechanisms) 二.TCP超时(TCP T ...

  5. Dubbo第三讲:Dubbo的可扩展机制SPI源码解析

    本文是Dubbo第三讲:Dubbo的可扩展机制SPI源码解析 文章目录 1.Dubbo SPI机制 1.1.Dubbo具有良好拓展性的原因 1.2.Dubbo SPI和Java SPI的区别? 1.3 ...

  6. 关于Hystrix超时机制和线程状态的测试观察和个人理解

    作者:未完成交响曲,资深Java工程师!目前在某一线互联网公司任职,架构师社区合伙人! 我们在使用Hystrix时,大部分情况下都是直接基于SpringCloud的相关注解来完成请求调用的.我们有个项 ...

  7. golang net/http 超时机制完全手册

    目录 SetDeadline 服务器端超时设置 客户端超时设置 Cancel 和 Context 英文原始出处: The complete guide to Go net/http timeouts, ...

  8. .Net Cancellable Task - APM异步超时机制扩展

    概述 .NET基于委托的APM(Asynchronous Programming Model)模式通过BeginInvoke, EndInvoke, AsyncCallback,IAsyncResul ...

  9. 超时机制,断路器模式简介

    使用Hystrix保护应用,它是一种豪猪,他身上有很多的刺,所以他能保护自己,我们知道老外的项目,他的项目名称往往取得比较有格调,比较的生动形象,所以他可以保护这样的一个组件,起名叫Hystrix,我 ...

最新文章

  1. Hadoop Hive sql 语法详细解释
  2. 《Thinking in UML》读书笔记之一
  3. gpu的单位表示_GPU是如何工作的
  4. 获取客户端IP和MAC地址
  5. 一口气搞懂「链表」,就靠这20+张图了
  6. yum安装openoffice
  7. 在 Linux 下打包命令 tar 和压缩命令 7z 的配合使用示例
  8. mysql查询耗时_一种数据库高耗时查询的自动取消方法与流程
  9. 选择文件夹里指定文件图片路径_这简直是鼠标一拖,自动帮你整理好文件
  10. asp.net程序中最常用的三十三种编程代码(转自CSDN)
  11. [UEFI启动教程]移动硬盘安装U盘装机助理(双模式启动)
  12. linux 系统服务里没有系统服务,windows怎样添加系统服务|windows 添加不了系统服务怎么办|windows 添加系统服务方法-系统城...
  13. 使用Unified Communications Managed API获取Lync在线会议的链接地址
  14. 记一次戴尔灵越7000(7000-7591)的坑爹螺丝设计,中招了保修都没门
  15. 计算机毕业设计ssm网上花店系统0716c系统+程序+源码+lw+远程部署
  16. sns.relplot
  17. Python获取高德POI(关键词搜索法)
  18. 让网页FLASH变成黑白的css语句
  19. 【时序逻辑电路(sequential logic circuit)】
  20. Shaders for Game

热门文章

  1. 什么是云服务举例说明_云服务器有什么用?最好举例说明。
  2. 计算机病毒会危害计算机用户的身体健康,了解计算机病毒给我们生活带来巨大危害的事例(病毒名称爆发时间中毒后症状或造成的危害)...
  3. Java基础测试题 - 核心类库(一)
  4. 移动互联网下的服务转型――10086APP成长的探索
  5. Vysor Pro 2.2.2 Windows
  6. directx比较java,在DirectX中绘制多个2d形状
  7. JAVA随机读写功能实现类_Java 实现文件随机读写-RandomAccessFile
  8. 计算机组装 ppt,计算机组装第一单元.ppt
  9. 微软2016校园招聘在线笔试 B Professor Q's Software [ 拓扑图dp ]
  10. 一步5G手机进入5G时代?这只是一个开始