CEPH RGW处理请求过程

本文介绍了Rgw通过Civetweb处理HTTP请求的具体流程,包括回调函数注册、请求解析、权限验证等多个步骤,并深入探讨了关键组件如RGWRequest、RGWOp等的作用。

Rgw处理请求过程

Rest api:
Put  /{bucket}  HTTP/1.1
x-amz-acl: public-read-write
Authorization: AWS {access}:{hash-of-header-and-secret}

这里依civetweb来提供rest服务来介绍,一个请求的处理过程。
回调函数的注册:
在civetweb中注册了用于处理请求的回调函数,在文件/rgw/rgw_main.cc中:

Class RGWMongooseFrontend::run(){
。。。
struct mg_callbacks cb;
    memset((void *)&cb, 0, sizeof(cb));
    cb.begin_request = civetweb_callback;
    cb.log_message = rgw_civetweb_log_callback;
    cb.log_access = rgw_civetweb_log_access_callback;
    ctx = mg_start(&cb, &env, (const char **)&options);
。。。
}

回调函数civetweb_callback()也定义在rgw_main.cc文件中:

static int civetweb_callback(struct mg_connection *conn) {
//提取request信息
  struct mg_request_info *req_info = mg_get_request_info(conn);
  RGWProcessEnv *pe = static_cast<RGWProcessEnv *>(req_info->user_data);
  RGWRados *store = pe->store;
  RGWREST *rest = pe->rest;
  OpsLogSocket *olog = pe->olog;
//构建rgw内部表示的request对象,即RGWRequest。
  RGWRequest *req = new RGWRequest(store->get_new_req_id());
  RGWMongoose client_io(conn, pe->port);
//进入request的处理流程
  int ret = process_request(store, rest, req, &client_io, olog);
  if (ret < 0) {
    /* we don't really care about return code */
    dout(20) << "process_request() returned " << ret << dendl;
  }

  delete req;

// Mark as processed
  return 1;
}

一个请求进入之后主要的处理流程都在process_request中:

static int process_request(RGWRados *store, RGWREST *rest, RGWRequest *req, RGWClientIO *client_io, OpsLogSocket *olog)

{
  int ret = 0;
// 初始化客户端,主要是从request info中取出请求头来,初始化client_io.env(RGWMongoose client_io(conn, pe->port);)
  client_io->init(g_ceph_context);
//初始化请求开始时间,及获取系统时间设置req中的时间变量ts
  req->log_init();

  dout(1) << "====== starting new request req=" << hex << req << dec << " =====" << dendl;
  //更新性能计数器,累加请求一次。
  perfcounter->inc(l_rgw_req);
//初始化执行环境,获取client_io的env来初始化,rgw_env)
  RGWEnv& rgw_env = client_io->get_env();
//存储用于完成完成请求的所有信息(Store all the state necessary to complete and respond to an HTTP request)
  struct req_state rstate(g_ceph_context, &rgw_env);

  struct req_state *s = &rstate;
//初始化rados上下文
  RGWObjectCtx rados_ctx(store, s);//rados_ctx.store=store;rados_ctx.user_ctx=s
  s->obj_ctx = &rados_ctx;
//初始化存储
  s->req_id = store->unique_id(req->id);
  s->trans_id = store->unique_trans_id(req->id);
//记录日志
  req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str());

  //初始化RGWOp *op
  RGWOp *op = NULL;
  int init_error = 0;
  bool should_log = false;
  RGWRESTMgr *mgr; //声明RGWRESTMgr对象

  //根据请求的url来选择对应的manager和该manager中的handler,(具体过程间handler的获取见[RGW处理请求中获取handler过程 ](http://blog.youkuaiyun.com/litianze99/article/details/49892753))
  RGWHandler *handler = rest->get_handler(store, s, client_io, &mgr, &init_error);
  if (init_error != 0) {
    abort_early(s, NULL, init_error);
    goto done;
  }

  should_log = mgr->get_logging();

  req->log(s, "getting op");
  op = handler->get_op(store);
  if (!op) {
    abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED);
    goto done;
  }
  req->op = op;
//检查请求中带的签名与本地服务端计算出的签名是否一致,判断请求是否合法详细过程见[ RGW中的请求的认证过程 ](http://blog.youkuaiyun.com/litianze99/article/details/49892813)
  req->log(s, "authorizing");
  ret = handler->authorize();
  if (ret < 0) {
    dout(10) << "failed to authorize request" << dendl;
    abort_early(s, op, ret);
    goto done;
  }
//判断用户是否被禁用,如果是则退出。
  if (s->user.suspended) {
    dout(10) << "user is suspended, uid=" << s->user.user_id << dendl;
    abort_early(s, op, -ERR_USER_SUSPENDED);
    goto done;
  }
  req->log(s, "reading permissions");
  ret = handler->read_permissions(op);
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "init op");

  ret = op->init_processing();
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "verifying op mask");
//验证op mask
  ret = op->verify_op_mask();
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "verifying op permissions");
  ret = op->verify_permission();
  if (ret < 0) {
    if (s->system_request) {
      dout(2) << "overriding permissions due to system operation" << dendl;
    } else {
      abort_early(s, op, ret);
      goto done;
    }
  }

  req->log(s, "verifying op params");
//验证op params
  ret = op->verify_params();
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "executing");
  op->pre_exec();
  //开始执行具体请求的操作
  op->execute();
  op->complete();
done:
//结束客户端请求
  int r = client_io->complete_request();
  if (r < 0) {
    dout(0) << "ERROR: client_io->complete_request() returned " << r << dendl;
  }
  if (should_log) {
    rgw_log_op(store, s, (op ? op->name() : "unknown"), olog);
  }

  int http_ret = s->err.http_ret;

  req->log_format(s, "http status=%d", http_ret);

  if (handler)
//回收op对象
handler->put_op(op);
  //回收handler对象
  rest->put_handler(handler);

  dout(1) << "====== req done req=" << hex << req << dec << " http_status=" << http_ret << " ======" << dendl;

  return (ret < 0 ? ret : s->err.ret);
}
### Ceph RGW 简介 Ceph RGWCeph Object Gateway)是 Ceph 存储系统中的对象网关服务,它提供了与 Amazon S3 和 OpenStack Swift 兼容的接口,允许用户通过熟悉的 API 来访问 Ceph 存储集群中的对象存储。这使得 Ceph 能够无缝集成到使用 S3 或 Swift 协议的现有应用程序和云环境中。 ### 功能特性 - **多协议支持**:Ceph RGW 支持 S3 和 Swift 两种广泛使用的对象存储协议,为不同需求的用户提供了灵活的选择。例如,使用 Amazon S3 API 的应用程序可以直接与 Ceph RGW 交互,而使用 OpenStack Swift 的云环境也能轻松集成 Ceph 存储。 - **数据冗余与高可用性**:依托 Ceph 存储集群的强大特性,Ceph RGW 能够实现数据的多副本存储和自动数据修复。当某个存储节点出现故障时,系统会自动将数据副本复制到其他可用节点,确保数据的安全性和服务的连续性。 - **用户认证与授权**:支持多种认证方式,如 AWS 风格的访问密钥认证,可对不同用户或用户组进行细粒度的权限控制。管理员可以根据业务需求,为用户分配不同的读写权限,保护数据的安全性。 - **数据版本控制**:允许用户对存储的对象进行版本管理,方便在数据被误删除或修改时进行恢复。每个对象的不同版本都会被保存,用户可以随时访问和恢复到指定版本。 - **多租户支持**:Ceph RGW 可以在一个存储集群中为多个租户提供独立的存储服务,每个租户有自己的命名空间和权限控制,实现资源的隔离和共享。 ### 配置方法 以下是一个简单的 Ceph RGW 配置示例: 1. **安装 Ceph RGW**:在 Ceph 集群节点上安装 Ceph RGW 服务。 ```bash sudo apt-get install radosgw radosgw-agent ``` 2. **配置 Ceph RGW**:编辑 Ceph 配置文件 `/etc/ceph/ceph.conf`,添加以下内容: ```plaintext [client.rgw.gateway] host = <hostname> rgw frontends = civetweb port=8080 rgw zone = <zone-name> rgw realm = <realm-name> ``` 其中,`<hostname>` 是运行 RGW 服务的节点主机名,`port` 是 RGW 服务监听的端口号,`<zone-name>` 和 `<realm-name>` 是 RGW 区域和领域的名称。 3. **创建 RGW 用户**:使用 `radosgw-admin` 工具创建 RGW 用户,并获取访问密钥。 ```bash radosgw-admin user create --uid="testuser" --display-name="Test User" ``` 该命令将创建一个名为 `testuser` 的 RGW 用户,并返回该用户的访问密钥(Access Key 和 Secret Key)。 ### 使用指南 以下是一个使用 s3fs 挂载 Ceph RGW 存储的示例: ```bash s3fs ceph-rgw /home/s3fs -o passwd_file=~/.passwd-s3fs -o use_path_request_style -o url=http://192.168.123.172:7480 ``` 其中,`ceph-rgw` 是存储桶名称,`/home/s3fs` 是挂载点,`~/.passwd-s3fs` 是存储访问密钥的文件,`http://192.168.123.172:7480` 是 Ceph RGW 服务的 URL。 ### 相关技术信息 - **架构设计**:Ceph RGW 基于 Ceph 的 RADOS(Reliable Autonomic Distributed Object Store)层构建,通过中间件层将 S3 和 Swift 协议的请求转换为 RADOS 对象操作。这种架构使得 Ceph RGW 能够充分利用 Ceph 集群的分布式存储能力,同时提供灵活的接口。 - **性能优化**:可以通过调整 Ceph RGW 的配置参数、优化网络环境和存储硬件等方式来提高性能。例如,增加 RGW 前端的并发连接数、使用高速网络和 SSD 存储设备等。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值