分享

Dubbo 超时WARN 日志 invoke time out....

 LGPL 2023-01-31 发布于北京

dubbo 有服务端和客户端两个地方设置timeout

// 服务端

<dubbo:service ref="xxxService" interface="com.xxx.XxxService"  timeout="5000"  />

// 客户端

<dubbo:reference id="xxxService" interface="com.xxx.XxxService" timeout="10000"  />

客户端调用远程服务时,本地会生成一个DefaultFuture,调用DefaultFuture.get()获取远程服务返回的结构,此方法获取锁,调用await方法,此时当前线程进入等待队列,此线程会有两种结果过:要么超时,抛出TimeOutException;如果被唤醒,则返回rpc的结果

在服务端timeout时间为5s,如果实际的数据操作耗时7s,服务端TimeoutFilter会根据服务端timeout检测到操作超时,打出warn日志。

在第7s,客户端接收到数据包,客户端timeout设置为10s>7s,DefaultFuture被唤醒,仍然可以接收到Rpc返回值。

  1. public Object get(int timeout) throws RemotingException {
  2. if (timeout <= 0) {
  3. timeout = Constants.DEFAULT_TIMEOUT;
  4. }
  5. if (! isDone()) {
  6. long start = System.currentTimeMillis();
  7. lock.lock();//加锁
  8. try {
  9. while (! isDone()) {
  10. done.await(timeout, TimeUnit.MILLISECONDS); //等待timeout
  11. if (isDone() || System.currentTimeMillis() - start > timeout) {
  12. break;
  13. }
  14. }
  15. } catch (InterruptedException e) {
  16. throw new RuntimeException(e);
  17. } finally {
  18. lock.unlock();
  19. }
  20. if (! isDone()) {// 客户端超时仍然没有得到服务端返回,抛出异常
  21. throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false));
  22. }
  23. }
  24. return returnFromResponse();
  25. }

如果超出了10s还没有返回值,抛出TimeoutException。

此时这个DefaultFuture超时了,有一个线程RemotingInvocationTimeoutScan,清理所有超时的DefaultFuture,创建一个timeoutResponse,DefaultFuture.received这样的response就会抛出TimeoutException。

综上所诉:当客户端timeout值>服务端timeout值,会出现超时日志,但是仍然可以获取到结果。客户端timeout超时抛出异常时,对应超时的Future会自动清理。

 

 

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多