Swift源码分析----swift-proxy实现请求req的转发

感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!

如果转载,请保留作者信息。
博客地址:http://blog.csdn.net/gaoxingnengjisuan
邮箱地址:dong.liu@siat.ac.cn

PS:最近没有登录博客,很多朋友的留言没有看见,这里道歉!还有就是本人较少上QQ,可以邮件交流。


概述:

这篇博客关注的问题就是:

请求信息如何通过swift-proxy服务实现转发;


这里应用网上找到的一幅图片来看看swift-proxy服务在swift系统中的作用(多谢作者);


    简单说,请求过来之后,通过swift-proxy服务的服务入口点,调用swift-proxy服务上的相关方法,实现通过给定的请求来确定具体要获取的控制器(ObjectController、ContainerController、AccountController),并进一步调用控制器下的具体方法,实现到相应存储服务(Object-server、Container-server、Account-server)的连接,并具体调用相应的方法来实现请求;

下面来看看代码的实现:

  1. def __call__(self, env, start_response):  
  2.     """ 
  3.     调用WSGI服务的入口点; 
  4.     """  
  5.     try:  
  6.         # 获取缓存信息;  
  7.         # 在env中获取'swift.cache'的值,如果为none,则报错误提示;  
  8.         # 注:env:表示wsgi环境的字典;  
  9.               
  10.         if self.memcache is None:  
  11.             self.memcache = cache_from_env(env)  
  12.               
  13.         req = self.update_request(Request(env))  
  14.   
  15.         return self.handle_request(req)(env, start_response)  
  16.     except UnicodeError:  
  17.         err = HTTPPreconditionFailed(request=req, body='Invalid UTF8 or contains NULL')  
  18.         return err(env, start_response)  
  19.     except (Exception, Timeout):  
  20.         start_response('500 Server Error',[('Content-Type''text/plain')])  
  21.         return ['Internal server error.\n']  
方法handle_request实现了对HTTP传递过来的请求进行具体的处理和执行,来看方法handle_request的实现:


  1. def handle_request(self, req):  
  2.     """ 
  3.     代理服务的入口点; 
  4.     对HTTP请求进行具体的处理和执行等操作; 
  5.     """  
  6.     try:  
  7.         self.logger.set_statsd_prefix('proxy-server')  
  8.         if req.content_length and req.content_length < 0:  
  9.             self.logger.increment('errors')  
  10.             return HTTPBadRequest(request=req, body='Invalid Content-Length')  
  11.   
  12.         try:  
  13.             if not check_utf8(req.path_info):  
  14.                 self.logger.increment('errors')  
  15.                 return HTTPPreconditionFailed(request=req, body='Invalid UTF8 or contains NULL')  
  16.         except UnicodeError:  
  17.             self.logger.increment('errors')  
  18.             return HTTPPreconditionFailed(request=req, body='Invalid UTF8 or contains NULL')  
  19.   
  20.         try:  
  21.             # 根据给定的HTTP的请求路径path获取控制器来处理请求;  
  22.             # 如果account, container, object都存在,则获取ObjectController控制器;  
  23.             # 如果account, container存在,object不存在,则获取ContainerController控制器;  
  24.             # 如果account存在,container, object不存在,则获取AccountController控制器;  
  25.             # 返回值:  
  26.             # path_parts:version, account, container, object等值的字典;  
  27.             # controller:具体的控制器类实例化对象;  
  28.             controller, path_parts = self.get_controller(req.path)  
  29.             # req.path = /v1/AUTH_2a8cbfbb8ad7411c8465f57311527937/testcontainer2/ceph9  
  30.             # controller = <class 'swift.proxy.controllers.obj.ObjectController'>  
  31.             # path_parts = {'object_name': 'ceph9', 'version': 'v1',   
  32.             #               'account_name': 'AUTH_2a8cbfbb8ad7411c8465f57311527937',   
  33.             #               'container_name': 'testcontainer2'}  
  34.                   
  35.             p = req.path_info  
  36.             if isinstance(p, unicode):  
  37.                 p = p.encode('utf-8')  
  38.         except ValueError:  
  39.             self.logger.increment('errors')  
  40.             return HTTPNotFound(request=req)  
  41.               
  42.         if not controller:  
  43.             self.logger.increment('errors')  
  44.             return HTTPPreconditionFailed(request=req, body='Bad URL')  
  45.               
  46.         if self.deny_host_headers and req.host.split(':')[0in self.deny_host_headers:  
  47.             return HTTPForbidden(request=req, body='Invalid host header')  
  48.   
  49.             # server_type:不同的类定义了不同的server_type;  
  50.             # server_type = 'Object';  
  51.             # server_type = 'Account';  
  52.             # server_type = 'Base';  
  53.             # server_type = 'Container';            
  54.             self.logger.set_statsd_prefix('proxy-server.' + controller.server_type.lower())  
  55.               
  56.         # 获取控制器类的实例化对象;  
  57.         controller = controller(self, **path_parts)  
  58.               
  59.         if 'swift.trans_id' not in req.environ:  
  60.             # if this wasn't set by an earlier middleware, set it now  
  61.             trans_id = generate_trans_id(self.trans_id_suffix)  
  62.             req.environ['swift.trans_id'] = trans_id  
  63.             self.logger.txn_id = trans_id  
  64.         req.headers['x-trans-id'] = req.environ['swift.trans_id']  
  65.         controller.trans_id = req.environ['swift.trans_id']  
  66.         self.logger.client_ip = get_remote_client(req)  
  67.               
  68.         try:  
  69.             # 执行具体控制器类中的指定方法;  
  70.             handler = getattr(controller, req.method)  
  71.             # req.method = DELETE  
  72.             # controller = <swift.proxy.controllers.obj.ObjectController object at 0x2acc110>  
  73.             # handler = <bound method ObjectController.DELETE of <swift.proxy.controllers.obj.ObjectController object at 0x2acc110>>               
  74.             getattr(handler, 'publicly_accessible')  
  75.         except AttributeError:  
  76.             allowed_methods = getattr(controller, 'allowed_methods', set())  
  77.             return HTTPMethodNotAllowed(request=req, headers={'Allow'', '.join(allowed_methods)})  
  78.               
  79.         if 'swift.authorize' in req.environ:  
  80.             resp = req.environ['swift.authorize'](req)  
  81.             if not resp:  
  82.                 del req.environ['swift.authorize']  
  83.             else:  
  84.                 if not getattr(handler, 'delay_denial'None):  
  85.                     return resp  
  86.   
  87.         req.environ['swift.orig_req_method'] = req.method  
  88.               
  89.         # handler = <bound method ObjectController.DELETE of <swift.proxy.controllers.obj.ObjectController object at 0x2acc110>>  
  90.         return handler(req)  
  91.   
  92.     except HTTPException as error_response:  
  93.         return error_response  
  94.     except (Exception, Timeout):  
  95.         self.logger.exception(_('ERROR Unhandled exception in request'))  
  96.         return HTTPServerError(request=req)  
1.controller, path_parts = self.get_controller(req.path)
   根据给定的HTTP的请求路径path获取控制器(ObjectController、ContainerController、AccountController)来处理请求;
2.controller = controller(self, **path_parts)
   获取控制器类的实例化对象;
3.handler = getattr(controller, req.method)
   执行具体控制器类中的指定方法;
4.return handler(req)
   调用相应控制器中具体的方法来对req进行处理;

   接下来将要调用的就是/swift/proxy/controllers/account.py或/swift/proxy/controllers/container.py或/swift/proxy/controllers/obj.py下面的PUT,POST,DELETE,GET,HEAD等方法;然后再在具体的方法中实现到具体存储服务(Object-serverContainer-server、Account-server)的连接,继而调用其下具体的PUT,POST,DELETE,GET,HEAD等方法来进行请求req的实现;




该请求的转发过程是这样的:

首先根据请求组成一个字符串    PREFIX+account+container+object+POPFREIX进行MD5值的运算,然后根据计算结果进行移位获得key,而该key值就是我们需要的虚节点的数值,然后根据获得的虚节点的值,进行对应表的查找,获得虚节点和节点的对应值,然后依次在这些节点中进行数据的查找,如果找到了,则重新新建请求向指定的存储节点发送请求,进行分发,最后将返回的内容返回给客户端即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值