RGW源码框架
流程介绍
rgw支持两大类web引擎
- fastcgi
- civetweb
- loadgen
rgw在main函数开始就会构建web引擎,具体代码如下
if (framework == "fastcgi" || framework == "fcgi") {
RGWProcessEnv fcgi_pe = { store, &rest, olog, 0 };fe = new RGWFCGXFrontend(fcgi_pe, config);
} else if (framework == "civetweb" || framework == "mongoose") {
RGWProcessEnv env = { store, &rest, olog, 0 };fe = new RGWMongooseFrontend(env, config);
} else if (framework == "loadgen") {
int port;
config->get_val("port", 80, &port);RGWProcessEnv env = { store, &rest, olog, port };
fe = new RGWLoadGenFrontend(env, config);
} else {
dout(0) << "WARNING: skipping unknown framework: " << framework << dendl;
continue;
}
由于默认使用civetweb类型,这里就大概分析一下civetweb工作, ciwetweb入口函数为run,也就是创建完引擎对象后直接执行fe->run();该函数启动后会开启一定量的线程,线程分为一个master线程用于监听链接和一堆worker线程负责干活,当请求过来以后由process_new_connection处理,处理完以后调用handle_request,该接口为civetweb引擎重点分析接口,负责分析http请求,并转化成rgw认识的数据结构,之后通过回调函数也就是civetweb_callback送向底层进行处理
static void process_new_connection(struct mg_connection *conn)
{
if (ebuf[0] == '\0') {
handle_request(conn);
if (conn->ctx->callbacks.end_request != NULL) {
conn->ctx->callbacks.end_request(conn, conn->status_code);
}
log_access(conn);
}}
如下代码段是分析结束后往底层送数据的接口process_request,该接口通过RGWRados* store, RGWREST* rest获取RGWRESTMgr对象(该对象维护了RGW处理资源),最后由该对象获取handler,handler知道该操作使用哪个RGWOp对象,然后直接调用其execute接口进行流程处理
框架图
https://www.processon.com/view/link/5bee83cae4b0993bf72ef9e3