前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >S3请求来了,该怎么处理?

S3请求来了,该怎么处理?

作者头像
腾讯云TStack
发布2020-06-22 10:40:54
1.6K0
发布2020-06-22 10:40:54
举报

小新 职场新人,存储小白 立志成为职场老鸟,存储专家;

影视迷,东野迷。

前言

对于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方法外部也能获取到改变之后的值,大概调用如下:

代码语言:javascript
复制
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)

● Ceph RGW整体结构,最全干货在这!

● 还在为容器时区困扰?送你一剂良药!

● 学会这3招,分分钟迁移业务繁忙虚拟机!

客官~点个“在看”嘛

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云TStack 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档