RequestProcessor处理请求源码剖析


RequestProcessor处理请求源码剖析

在上一次分析ZK网络通信源码的时候我们追溯到了ZookeeperServer.processPacket()就没有再深入了。
在这里插入图片描述

本次就要来介绍具体业务处理的流程。入口为ZookeeperServer.processPacket()中的submitRequest(si);
在这里插入图片描述

概览图:
在这里插入图片描述

RequestProcessor结构

概览图:
在这里插入图片描述

客户端请求过来,每次执行不同事务操作的时候,Zookeeper也提供了一套业务处理流程RequestProcessor , RequestProcessor 的处理流程如下图:
在这里插入图片描述
我们来看一下 RequestProcessor 初始化流程【在启动zk服务,也就是在zks.startup();内部进行初始化的】, ZooKeeperServer.setupRequestProcessors()方法源码如下:
在这里插入图片描述
它的创建步骤:

  1. 创建finalProcessor。
  2. 创建syncProcessor,并将finalProcessor作为它的下一个业务链。
  3. 启动syncProcessor。
  4. 创建firstProcessor(PrepRequestProcessor),将syncProcessor作为firstProcessor的下一个业务链。
  5. 启动firstProcessor。

syncProcessor 创建时,将finalProcessor 作为参数传递进来源码如下:
在这里插入图片描述
firstProcessor创建时,将 syncProcessor 作为参数传递进来源码如下:
在这里插入图片描述
PrepRequestProcessorSyncRequestProcessor 的结构一样,都是实现了 Thread 的一个线程,所以在这里初始化时便启动了这两个线程。但是FinalRequestProcessor不是线程。

1、PrepRequestProcessor剖析

PrepRequestProcessor 是请求处理器的第1个处理器,我们把之前的请求业务处理衔接起来,一步一步分析。
ZooKeeperServer.processPacket()>submitRequest()>enqueueRequest()>RequestThrottler.submitRequest(),来看下 RequestThrottler.submitRequest() 源码,它将当前请求添加到submittedRequests 队列中了,源码如下:

在这里插入图片描述
RequestThrottler的继承关系就知道它是个线程,我们看看它的 run 方法做了什么事,源码如下:

在这里插入图片描述

RequestThrottler 调用了 ZooKeeperServer.submitRequestNow()方法,而该方法又调用了firstProcessor 的方法,源码如下:
在这里插入图片描述
从上段源码可以看出三个RequestProecessor 中最先调用的是PrepRequestProcessorPrepRequestProcessor.processRequest() 方法将当前请求添加到了队列 submittedRequests 中,
源码如下:
在这里插入图片描述
上面方法中并未从 submittedRequests队列中获取请求,如何执行请求的呢,因为PrepRequestProcessor 是一个线程,因此会在 run 中执行,我们查看 run 方法源码的时候发现它调用了pRequest()方法, pRequest() 方法源码如下:
在这里插入图片描述
首先先执行pRequestHelper()方法,该方法是PrepRequestProcessor处理核心业务流程,主要是一些过滤操作,操作完成后,会将请求交给下一个业务链,也就是SyncRequestProcessor.processRequest()方法处理请求。

这里可能会好奇pRequestHelper()具体做了什么,看它的源码会发现做事的其实是pRequest2Txn(),而pRequest2Txn()主要做的就是权限校验、快照记录、事务信息记录相关的事,并未涉及到数据处理!!

也就是说 PrepRequestProcessor其实是做了操作前权限校验、快照记录、事务信息记录相关的事。

2、SyncRequestProcessor剖析

该处理器主要是将请求数据高效率存入磁盘,并且请求在写入磁盘之前是不会被转发到下个处理器的。
我们先看请求被添加到队列的方法:
在这里插入图片描述
同样 SyncRequestProcessor 是一个线程,执行队列中的请求也在线程中触发,我们看它的run方法,源码如下:
请添加图片描述
run 方法会从 queuedRequests队列中获取一个请求,如果获取不到就会阻塞等待直到获取到一个请求对象,程序才会继续往下执行,接下来会调用 Snapshot Thread 线程实现将客户端发送的数据以快照的方式写入磁盘,最终调用 flush() 方法实现数据提交,flush()方法源码如下:
在这里插入图片描述
flush() 方法实现了数据提交,并且会将请求交给下一个业务链,下一个业务链为FinalRequestProcessor

3、FinalRequestProcessor剖析

FinalRequestProcessor相对前面两个来说没那么复杂,该业务处理对象主要用于返回Response。
请添加图片描述


文章作者: fFee-ops
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 fFee-ops !
评论
  目录