-
Notifications
You must be signed in to change notification settings - Fork 26.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
服务调用的超时问题 Some issues with service timeout #1968
Comments
顶 |
对于issue1,可以考虑使用dubbo的心跳,如果心跳检测不到,可以直接返回,不再等待。 @baigod |
@luyuanwan 具体怎么实现呢 : ) |
For case 2, I am afraid there are no perfect solutions, when a heuristic exception occur, you can only retry or check offline. For case 1, I think it's meaningful to notify the hanging client requests as soon as possible. When Server goes down it will trigger |
@diecui1202 |
@carryxyh Great thanks. |
#2451 has been merged to 2.6.x. |
@carryxyh 你好, 我們專案中(使用 2.5.3)也遇到 issues code 1 的困擾. 看到這個 issue (修正在2.6.4)之後. 我下載 2.6.6 的代碼到我本地運行. 但是發現. 我從 consumer 送出服務調用請求 並且進到 provider 之後,在 provider 返回處理結果前, 我手動把 provider 的進程刪除,我的 consumer 端仍然處於等待狀態. 為此我調試了 dubbo 2.6.6 底層代碼, 由於對 dubbo 的同訊架構不熟, 我只能從我調試的代碼看出, consumer 的確有收到 provider 斷開, 但是 consumer 收到通知的是 HeaderExchangeChannel 這個類, 而我看了git 上修正的 file, 關鍵的修正是在 HeaderExchangeHandler 類中的 disconnected 方法調用 DefaultFuture.closeChannel(channel); |
@falcondsc 首先确认一个问题,就是你的provider的关闭方式是什么样的,我猜测你可能并不是正常关闭provider,而是使用kill -9这种方式关闭(或者其他的方式关闭,导致TCP通道并不是通过四次挥手来正常关闭的)。 如果你是通过正常方式关闭provider的TCP通道的,则consumer端的触发过程应该是: 此时,正如我的PR中修复的那样,所有的事情按照预期的方式发生。 反之,如果你是通过kill -9或者provider端直接断网等更加暴力的方式关闭,则provider并不会向consumer端发送fin报文。在这种情况下,对于TCP通道来说,consumer端会仍然认为provider端的进程是存活的、能够处理请求的。 那为什么会触发HeaderExchangeChannel的close方法呢? |
@carryxyh 的確如你所說的. 當我關閉 provider 進程時,consumer 的 HeaderExchangeChannel close 調用堆棧是從 dubbo 的 ZookeeperRegistry notify 所發起的. issues code 1 的說明中提到 "B宕机,如何让a()立即捕获到异常信息",所以我就直接使用 IDE 關閉 provider 來驗證這一個問題, 我們 目前這邊的 生產環境中搭配 docker swarm 佈署 provider 節點,並且使用 docker 健康檢查自動融斷沒有回應的節點(有時因為 db 資源不足, 實際是在等待 db,不過我們有做服務調用冪等性, 我可能還要檢查下被 docker 融斷的節點是否是docker 送出 kill -9指令). 所以想再請教一下當服務發現機制偵測到 provider 下線時通知 HeaderExchangeChannel close 方法. 而我在 close 方法內加上調用 DefaultFuture.closeChannel(channel); 會引起甚麼問題嗎? |
我认为不会引发什么问题,反而加上这个调用以后,功能会更加健壮。在任何情况下,当调用真正进行到 HeaderExchangeChannel#close 的时候,都意味着我们不再关心hang住的请求是否能够正常返回。 如果你愿意,可以创建一个新的issue来跟踪这个问题并且提交一个pull request来优化它。 |
@carryxyh 好的. 謝謝. 為了這個問題. 我今天才註冊 GitHub. 等我們生產環境驗證後. 我再回頭看下要怎麼建新的 issue 並 提交 pull request. :) |
@falcondsc I verified on the master branch. This solution doesn't work. |
@beiwei30 你好. 請問一下你改的 master branch 是指主分支 2.7.x 嗎? 我測試是使用 2.6.6 的代碼進行修改的. 註冊中心使用的是 zookeeper. consumer 設定 timeout 為 10分鐘, 我並沒有對 2.7.x 版進行調整並測試這個問題. 以上的信息 希望對你有些幫助. |
補充一下: 另外我的 consumer retries 設定為 0 |
我另外測試了 註冊中心是使用 Multicast 時. 那麼 consumer 的 HeaderExchangeChannel 將會是 |
@falcondsc 是的,是针对 master 分支做的分析和修复。2.6.x 上还麻烦你验证一下,如果工作的话,欢迎提 pull request 过来把 master 上的修复 backport 回来。 |
@beiwei30 |
我獲取了 2.6.x 分支 在 HeaderExchangeChannel.close() 調用 DefaultFuture.closeChannel(channel); 方法. 但測試後發現調用到 HeaderExchangeChannel.close() 的堆棧 和 我先前用 2.6.6 去修改時有些不同, 2.6.x 分支代碼上慢了很多(關閉 dubbo provider 之後, 要等 30 秒以上)才會進到 consumer 端的HeaderExchangeChannel.close() .. 我先再繼續做些測試, 查看下是不是我兩個測試環境有不同而引起的問題. |
@beiwei30 想再請教一下, 因為剛接觸 github. 所以我反覆看了整個 issue 和關聯出去的內容. |
Try it with the latest version, if you still have problems, you can reopen the issues |
dubbo version: 2.5.6
issues code 1
使用场景,当B服务提供者需要紧急重启的情况下:
此时,B宕机,如何让a()立即捕获到异常信息,而不用等待3分钟才返回,如果大量并发请求在请求中,将可能造成A服务大量请求堆积。这个是否有更友好的办法去处理,或者,我的配置并不完善。
Usage Scenarios When the B Service Provider Needs an Emergency Restart:
At this point, B crashes, how to make a() immediately capture exception information without waiting for 3 minutes to return. If a large number of concurrent requests are in the request, it may cause a large number of A service requests to be accumulated. Is there a more friendly way to deal with this, or my configuration is not perfect.
issues code 2
使用场景,当B服务提供者遇到数据库性能瓶颈(updateSomeRows()执行缓慢):
此时,A捕获超时异常,a()的事务因异常回滚,但是B的数据已插入,这是不符合预期的。请问怎么简单优雅地处理这样的问题(不考虑使用分布式事务的情况下)。
Usage scenario, when B service provider encounters a database performance bottleneck (execution of updateSomeRows() is slow):
At this point, A capture timeout exception, a () transaction rollback due to anomalies, but B's data has been inserted, which is not in line with expectations. How to handle such problems simply and gracefully (not considering the use of distributed transactions).
The text was updated successfully, but these errors were encountered: