小新 职场新人,存储小白 立志成为职场老鸟,存储专家;
影视迷,东野迷。
前言
对于RGW而言,请求处理的过程是我们最关注的,因此在这一部分主要是归纳整理一下完整的请求处理流程~
在流程中涉及到的需要详细介绍的地方可以参看:《Ceph RGW整体结构,最全干货在这!》的每个组件的介绍。
一、处理流程分解
由于分析的是N版本的Ceph RGW,因此Frontend采用默认的Beast,所以下面的流程是以Beast作为Frontend为前提,如果是Civetweb作为Frontend的情况整体流程类似,请求连接和转发有部分差异,会在后面简单介绍。详细的请求处理整体流程图如下所示:
请求的accept
在RGW启动之后,会在AsioFrontend::init中的l.acceptor.async_accept处等待监听请求连接,当有新请求连接过来之后,会进入到AsioFrontend::accept进行处理,并且接着继续监听新的连接。在accept中,主要进行的操作如下:
1、获取连接的socket和TCP的no_delay参数,并继续监听新链接
2、判断是否使用ssl
3、使用boost::asio::spawn来启动一个新的coroutine
4、使用lambda表达式的方式来在新的coroutine中处理handle_connection
handle_connection
接着来到handle_connection函数中,在改操作中主要进行验证和封装参数,并发送给rgw_process.cc中的process_request,在此函数中主要操作如下:
1、检验header和body是否超出长度限制(header最大4K,body没有限制,因为是分块读取)
2、读取header信息
3、封装RGWRequest、RGWRestfulIO等参数信息
4、将请求转发给process_request
process_request
接下来的处理基本上都是在这个部分完成的,涉及到handler等资源获取,请求执行和请求返回结果处理等是三个大部分,首先获取基本的资源信息,涉及到的如下:
1、RGWRestfulIO::init(): 初始化上下文的环境变量信息,例如:HTTP_AUTHORIZATION、REQUEST_URI等
2、RGWRestfulIO::get_env(): 获取RGWEnv对象资源
3、根据初始化的上下文和RGWEnv对象获取RGWUserInfo和req_state对象资源
4、根据req_state和RGWRados获取RGWObjectCtx对象资源
在获取到上述相应资源之后就进行get_handler操作,如下。
获取Mgr和Handler
接着通过get_handler方法同时获取RGWRESTMgr和RGWHandler_REST对象,因为RGWRESTMgr是通过传引用的方式传递给get_handler,在get_handler中通过RGWRESTMgr::get_manager方法获取到RGWRESTMgr信息,并赋值给传递进来的RGWRESTMgr对象,由于传递的是引用,所以在get_handler方法外部也能获取到改变之后的值,大概调用如下:
RGWRESTMgr *mgr;RGWHandler_REST *handler = rest->get_handler(store, s,auth_registry,frontend_prefix, client_io, &mgr,&init_error);
此时已经可以取到请求相关的参数信息,包括请求方法、请求的uri等,因此此处,可以根据请求参数和fontend_prefix等信息在MGR的资源池中进行过滤和匹配,从而找到具体对应的RGWRESTMgr和RGWHandler_REST,从而可以通过RGWHandler_REST取到对应的RGWOp对象,从而可以执行具体的操作。
请求的调度和校验
该部分大概分为三个步骤:
1、schedule_request:通过scheduler进行请求的调度
2、RGWOp::verify_requester:验证请求的合法性
3、RGWHandler_REST::postauth_init:验证Bucket、Object和Tenant等的名称合法性
哪个过程验证不通过的话将会直接到达RGWRestfulIO::complete_request,并封装出错信息进行返回。
rgw_process_authenticated
这个过程是最后验证和执行的地方,主要分为相关资源初始化、操作或权限验证、预执行、执行和完成几个部分,详细的验证和执行的流程参考上面的请求执行流程图,另外详细的要验证和执行的方法,以及每个方法的作用可以参考上面的rgw_process_authenticated的有关介绍。
至此,就完成了一个完整的请求接收之后的处理流程。
二、List Bucket流程示例
分析
上面详细介绍了请求处理的每个流程,上述的流程是从请求处理的整体上来看的流程,具体到每个具体的请求可能存在部分不同。下面将以List Bucket操作作为例子来看看每个过程具体调用的类和方法等。
根据上面的分析,可以知道,新的请求到来之后会进入rgw_process.cc中的preocess_request中,而且在该方法中的前面一部分基本上都是整合参数的信息。
而且前面分析中也知道,实际上每种操作对应一个Mgr,然后该Mgr中又会针对该具体请求对应一个Handler,然后每个Handler根据每个具体操作调用相应的方法执行。因此区分每个请求的地方主要就是process_request中的get_handler()操作,下面就重点分析在进行List Bucket操作的时候,是如何获取到相应的操作Handler。
上述流程图最左边的是主流程图,右边的流程图是主流程图中get_manager和get_handler的分支。
流程分析如下:
1、首先,主流程的rest是RGWREST类型,在RGWREST中组合了RGWRESTMgr对象,rest参数由Frontend传递过来的,而Frontend中的rest是在rgw_main中初始化的时候通过rest.register_default_mgr或rest.register_resource注册到rest中RGWRESTMgr对象中,并且RGWRESTMgr类是所有Mgr的父类。
2、主流程主要rgw_rest.cc中get_handler方法,该方法主要流程如下:
① get_manager获取请求操作对应的Mgr
② pmgr是从rgw_process中process_request通过指针的方式传递进来的
③*pmgr = m;就是将获取到的mgr赋值给pmgr,从而让process_request可以直接获取到
④ get_handler主要就是根据获取到的mgr和请求的具体操作,获取具体的请求处理handler
⑤ 最后初始化handler
3、来到get_manager的分流程,主要如下:
① 来到rgw_rest.cc中的get_resource_mgr方法中
② 根据现有的resource列表,倒序遍历来与传入请求的uri进行比较(默认S3,因此主要比较有admin、swift和auth三种)
▶匹配成功,表示是admin、swift和auth中的一种,从resource_mgrs中取出相应mgr返回
▶匹配失败,表示是默认的S3,因此返回默认的Mgr即可,此处是S3
▶(此处的默认S3是在rgw_main中register_default_mgr进行的设置)
4、来到get_handler的分流程,主要如下:
①首先根据获取到mgr是RGWRESTMgr_S3,因此调用的是rgw_rest_s3.cc中get_handler
② 然后根据解析出来的url信息判断是否含有Bucket Name,如果没有则返回RGWHandler_REST_Service_S3
③否则判断是否含有Object Name,如果没有则返回RGWHandler_REST_Bucket_S3
④ 否则表示是Object相关操作,则返回RGWHandler_REST_Obj_S3
三、CivetWeb请求流程
CivetWeb和Beast的差别只是在请求的接受和转发到rgw_process.cc/process_request之间的逻辑,下面就简要的分析一下CivetWeb在接收请求到转发之间的流程。
流程说明:
1、首先是在rgw_main中的init和run方式,用来启动frontend,这个对所有frontend都是一样
2、注意CivetWeb中的init方法没有实现内容,为了兼容其他frontend,直接返回的
3、CivetWeb中的run方法主要是通过get_config_map进行配置参数的获取,并封装到options参数中
4、然后设置几个回调函数,其中begin_request就是设置请求处理的回调函数
5、然后通过mg_start启动服务,由相应的回调函数处理相应的请求
6、进入到begin_request的回调函数civetweb_callback中,主要是获取request info,然后执行process
7、由此进入到RGWCivetWebFrontend::process中,主要封装了RGWCivetWeb、RGWRestfulIO和RGWRequest三个参数
8、最后就是调用rgw_process.cc中的process_request,之后的流程就和上面介绍的Beast frontend一样了
四、参考
- [Ceph v14-2-0-nautilus releases](https://docs.ceph.com/docs/master/releases/nautilus/#v14-2-0-nautilus)
- [CivetWeb](http://civetweb.github.io/civetweb/)
- [Background on http frontends(civetweb and beast)](https://www.cnblogs.com/dengchj/p/11436758.html)
客官~点个“在看”嘛