前言SOFABolt是一个基于 Netty 最佳实践的轻量、易用、高性能、易扩展的通信框架。目前已经运用在了蚂蚁中间件的微服务,消息中心,分布式事务,分布式开关,配置中心等众多产品上。 本文将分析SOFABolt的超时控制和心跳机制。 超时在程序中,超时一般指的是程序在特定的等待时间内没有得到响应,网络通信问题、程序BUG等等都会引起超时。系统引入超时机制往往是为了解决资源的问题,比如一个同步RPC请求,在网络不稳定的情况下可能一直无法得到响应,那么请求线程将一直等待结果而无法执行其它任务,最终导致所有线程资源耗尽。超时机制正是为了解决这样的问题,在特定的等待时间之后触发一个“超时事件”来释放资源。 在一个网络通信框架中,超时问题无处不在,连接的建立、数据的读写都可能遇到超时问题。并且网络通信框架作为分布式系统的底层组件,需要管理大量的连接,如何建立一个高效的超时处理机制就成为了一个问题。 时间轮(TimeWheel)在网络通信框架中动辄管理上万的连接,每个连接上都有很多的超时任务,如果每个超时任务都启动一个java.util.Timer,不仅低效而且会占用大量的资源。George Varghese 和 Tony Lauck在1996年发表了一篇论文:《Hashed and Hierarchical Timing Wheels: EfficientData Structures for Implementing a Timer Facility》来高效的管理和维护大量的定时任务。 时间轮其实就是一种环形的数据结构,可以理解为时钟,每个格子代表一段时间,每次指针跳动一格就表示一段时间的流逝(就像时钟分为60格,秒针没跳动一格代表一秒钟)。时间轮每一格上都是一个链表,表示对应时间对应的超时任务,每次指针跳动到对应的格子上则执行链表中的超时任务。时间轮只需要一个线程执行指针的“跳动”来触发超时任务,且超时任务的插入和取消都是O(1)的操作,显然比java.util.Timer的方式要高效的多。 SOFABolt的超时控制机制如上图所示,SOFABolt中支持四中调用方式:
同步调用的超时控制实现同步调用中,每一次调用都会阻塞调用线程等待服务端的响应,这种场景下同一时刻产生最大的超时任务取决于调用线程的数量。线程资源是非常昂贵的,用户的线程数是相对可控的,所以这种场景下,SOFABolt使用简单的java.util.concurrent.CountDownLatch来实现超时任务的触发。 SOFABolt同步调用的代码如上,核心逻辑是:
java.util.concurrent.CountDownLatch#await(timeout, timeoutUnit) 方法实现了等待一段时间的逻辑,并且通过countDown方法来提前中断等待,SOFABolt 中 InvokeFuture 通过构建 new CountDownLatch(1)的实例,并将 await 和 countDown 方法包装为 awaitResponse 和 putResponse 来实现同步调用的超时控制。 异步调用的超时控制实现相对于同步调用,异步调用并不会阻塞调用线程,那么超时任务的数量并不受限于线程对的数量,用户可能通过一个线程来触发量大的请求,从而产生大量的定时任务。那么我们需要一个机制来管理大量的定时任务,并且作为系统底层的通信框架,需要保证这个机制尽量少的占用资源。上文已经提到 TimeWheel 是一个非常适合于这种场景的数据结构。 SOFABolt 异步调用的代码如上,核心逻辑是:
Fail-Fast机制以上关于 SOFABolt 的超时机制介绍都是关于 SOFABolt 客户端如何完成高效的超时任务管理的,其实在 SOFABolt 的服务端同样针对超时的场景做了优化。 如上图所示,请求可能在服务端积压了一段时间,此时这些请求在客户端看来已经超时了,如果服务端继续处理这些超时的请求,第一请求的响应最终会被客户端丢弃;第二可能加剧服务端的压力导致后续更多请求超时。通过 Fail-Fast 机制直接丢弃掉这批请求能减轻服务端的负担使服务端尽快恢复并提供正常的服务能力。 这样会有一小部分客户端认为已经超时的请求服务端还会处理(因为网络传输是需要时间的),但是不会出现误判的情况。 SOFABolt 的心跳机制除了上文提供的超时机制外,在通信框架中往往还有另一类超时,那就是连接的超时。 上面是客户端触发心跳后的代码,当客户端接收到 IdleStateEvent 时会调用上面的heartbeatTriggered 方法。 RpcHeartbeatProcessor 是 SOFABolt 对心跳处理的实现,包含对心跳请求的处理和心跳响应的处理(服务端和客户端复用这个类,通过请求的数据类型来判断是心跳请求还是心跳响应)。 总结本文简单的介绍了 TimeWheel 的原理,SOFABolt 的超时控制机制和心跳机制的实现。SOFABolt 基于高效的 TimeWheel 实现了自己的超时控制机制,同时增加 Fail-Fast 策略优化服务端对超时请求的处理。另外 SOFABolt 默认实现了连接的心跳机制,以保持系统空闲时连接的可用性,这些都为 SOFABolt 的高性能打下了坚实的基础。 |
|
来自: airen89 > 《sofabolt》