定时任务带来了什么问题
我们来看一下RPC框架是如何处理超时请求的:
- RPC中,无论是同步调用还是异步调用,调用端内部实行的都是异步
- 调用端在向服务端发送消息之前会创建一个Future,并存储这个消息标识与这个Future的映射
- 当服务端收到消息并且处理完毕后向调用端发送响应消息,调用端在接收到消息后会根据消息的唯一标识找到这个Future,并将结果注入到这个Future
那这个过程中,如果服务端没有及时响应消息给调用端呢?调用端应该如何处理超时的请求?
- 可以利用定时任务
- 每次创建一个Future,我们都记录这个Future的场景时间与这个Future的超时时间,并且有一个定时任务进行检测
- 当这个Future到达超时时间并且没有被处理时,我们就对这个Future执行超时逻辑
时钟轮在 RPC 中的应用
在 RPC框架中只要涉及到定时相关的操作,我们就可以使用时钟轮。
那么 RPC 框架在哪些功能实现中会用到它呢?
- 请求超时处理:每发一次请求,都创建一个处理请求超时的定时任务放到时钟轮里面,在高并发、高访问量的情况下,时钟轮每次只轮询一个时间槽中的任务,这样会大量节省CPU
- 调用端和服务端的启动超时:以调用端为例,假设我们想要让应用可以快速的部署,比如1分钟内启动,超过1分钟则启动失败。我们可以在调用端启动时创建一个处理启动超时的定时任务,放到时钟轮里
- 定时心跳:RPC调用端定时向服务端发送心跳,来维护连接。我们可以将心跳的逻辑封装为一个心跳任务,放到时钟轮里。但心跳任务是要定时执行的,而时钟轮中的任务执行一遍就被移除了,对于这种需要重复执行的定时任务我们应该如何处理呢?在定时任务的执行逻辑的最后,我们可以重设这个任务的定时时间,把它重新丢回时钟轮里