arpc icon indicating copy to clipboard operation
arpc copied to clipboard

timeout不工作的问题

Open nickolastone opened this issue 2 years ago • 6 comments

如果在server里面call client的一个handle,然后client的handle超时后 server发给该client的一切call都直接timeout了 client自身的一切call server的操作也会直接timeout了

此时应该怎么做?因为无法保证client的handle或者server的handle的处理时间 小于call时设置的timeout时间 不能影响其他请求吧?如果取消那个请求呢?

nickolastone avatar Sep 05 '22 04:09 nickolastone

感谢关注和反馈!

导致这个问题应该是因为使用了默认的路由配置:全是同步处理,多个请求排队、处理完一个才会处理下一个,所以调用方使用相同的timeout时,一个超时后其他已经在队列中的请求也就超时了

arpc提供不同级别的同步异步选择,应用层根据自己实际情况选择异步策略就可以了:

  1. 全局级设置所有请求都异步处理:handler.SetAsyncResponse(true),默认为false,则全局级都是同步处理。您的这个问题最简单的解决方式就是这里全局true,就不会再有这种一个超时其他也超时的问题了,client端和server端处理方式是一样的。
  2. 按路由级为单个路由设置同步或者异步:
asyncResponseHello := true
svr.Handler.Handle("Hello", OnHello, asyncResponseHello) // 不传第三个参数默认为false,则同步处理

1和2这两条遵循局部性原理,如果全局已经配置了、新增路由时这个路由自己没有配置则以已经存在的全局配置为准

  1. handler返回不代表响应完成,而是用户实际调用ctx.Write之类的回写才会导致请求结束,所以(不启用pool选项的前提下,启用pool选项涉及到ctx的回收、handler结束后ctx失效)handler内可以由用户根据自己实际需要再进行同步或者异步的处理:比如全局和路由都没有设置异步处理,当用户本次请求的某个参数直接校验失败则直接ctx.Write and return,如果参数校验成功、后续需要一些耗时操作则选择另外再去异步处理

------------------------------------------------------ 分割线 ------------------------------------------------------

对于请求的处理,其他go rpc框架的通常做法是异步处理每个请求:

  1. 一些框架没使用协程池、每个请求都创建一个协程单独处理,这样的问题是对协程频繁创建消耗、以及海量请求时可能系统同时存在大量协程带来硬件压力
  2. 另一些框架引入了协程池,用协程池来异步处理这些请求,从而达到协程数量可控进而硬件消耗可控的目标。

但不管是否使用协程池,这种统一异步处理的方式,还是有些缺点:

  1. 对于handler内cpu消耗型并且耗时非常短的请求,异步处理时协程切换的额外消耗相比于handler本身的逻辑消耗可能会比例较大、不如直接同步处理划算
  2. 其他的go rpc框架通常都是handler返回了就请求结束了,不方便与其他模块进行更灵活的同步异步搭配

arpc支持的基础姿势更加完整,通过这些不同的同步异步组合,能够实现业务层更好的响应性能以及消耗的更好平衡。如果您的业务系统目前没有性能瓶颈,按我上面1中的方式设置全局异步处理即可。如果需要自定制协成池来控制协成数量,可以用 handler.SetAsyncExecutor 来定制

lesismal avatar Sep 05 '22 07:09 lesismal

我在琢磨,如果 arpc 的全局异步配置修改成默认 true 会不会对用户更友好些,避免大家因为不清楚这个多种异步策略而导致使用了默认的策略时的超时问题、有性能需要的用户自行配置全局为false再根据路由、handler实际情况进行异步处理。

lesismal avatar Sep 05 '22 09:09 lesismal

我觉得 可以默认成true, 避免用户第一直觉下 认为 是不是哪里出问题了,进阶时可以再推荐用户自定义

nickolastone avatar Sep 05 '22 12:09 nickolastone

改成默认true了,请试下最新版,如果没问题我再发个release版本

go get -u github.com/lesismal/arpc@5d0e0e9b1b7ed540a64efbeaea1fa5b0e53f99fa

lesismal avatar Sep 05 '22 12:09 lesismal

可以的,有其中一个阻塞 其他会继续请求 然后延时那个执行完也会回收

nickolastone avatar Sep 06 '22 08:09 nickolastone

已发布: https://github.com/lesismal/arpc/releases/tag/v1.2.10

Notify 类型的 Message 也会默认异步处理。

lesismal avatar Sep 06 '22 08:09 lesismal

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Oct 07 '22 03:10 github-actions[bot]