nova创建虚拟机源码分析系列之三 PasteDeploy
上一篇博文介绍WSGI在nova创建虚拟机过程的作用是解析URL,是以一个最简单的例子去给读者有一个印象。在openstack中URL复杂程度也大大超过上一个例子。所以openstack使用了PasteDeploy模块去解析复杂的URL。
首先看“笨办法”是如何处理不同的URL。
在WSGI简单的模型中,如果有多个URL,可以判断请求方和请求路径的然后分别处理不同的URL。
处理函数 app.py
服务器函数 server.py
这种方法是简单,直接的,但也是可重复性差,不可维护的。一个restful中有可能50个以上的URL路径,如果这么写下去,那维护的人要抓狂。
所以要以一种简单清晰,可维护性好的方式去解析URL,这种方式便是使用PasteDeploy模型。
PasteDeploy的工作模式是使用一个配置文件configure.ini去解析URL。借鉴一个例子来讲解,原文 http://blog.csdn.net/li_101357/article/details/52755367
在家里水系统的模型大概如下图,以及对应的模拟路径:
PasteDeploy模型中有4中部件,分别是:
对应到上例:
- app 水龙头 淋浴器
- filter 热水器
- pipeline 热水器 + 淋浴器
- composite 总开关
确定了对应的URL之后,使用PasteDeploy组件来构造解析文件configure.ini。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [composite:main] use = egg:Paste#urlmap /main/tap = tap /main/boil/shower = pip_to_shower [app:tap] paste.app_factory = tap:app_factory in_arg = water [pipeline:pip_to_shower] pipeline = boiler shower [filter:boiler] paste.filter_app_factory = boiler:filter_app_factory in_arg = water [app:shower] paste.app_factory = shower:app_factory in_arg = hot_water |
[composite:main]
use = egg:Paste#urlmap
/main/tap = tap
/main/boil/shower = pip_to_shower
Paste#urlmap 表示,默认使用Paste.urlmap。
use = egg:Paste#urlmap 意味着直接使用来自于Paste包的urlmap的composite应用。 urlmap是特别常
见的composite应用——它使用路径前缀来映射将你的请求与其他应用对应起来。
基本含义就是说,这是Paste已经提供好的一个composite,如果你想自定义就需要另外写一个composite_factory了。
[app:tap]
paste.app_factory = tap:app_factory
in_arg = water
表示路径"/tap"的处理方法paste.app_factory存在于tap.py文件的的app_factory中,这是一个方法。
[pipeline:pip_to_shower]
pipeline = boiler shower
pipeline 主要起到组合的作用,将filter(过滤器)和app(应用)组合起来,形成一条管道。
[filter:boiler]
paste.filter_app_factory = boiler:filter_app_factory
in_arg = water
filter类似app,只不过换成了paste.filter_app_factory,filter首先执行过滤功能,然后执行app。
配置文件中将路径的处理都配置好:
/main/tap 路径对应的处理函数 tap ,tap是文件tap.py的app_factory方法。
/main/boil/shower 路径对应的处理函数是管道 pip_to_shower 。管道由过滤器 boiler和应用shower组成。首次经过boiler的过滤,然后调用shower函数处理。
下面完成tap、shower和filter文件。
tap.py
1 2 3 4 5 6 7 8 9 10 11 | class Tap( object ): def __init__(self, in_arg): self.in_arg = in_arg def __call__(self, environ, start_response): print 'Tap' start_response( '200 ok' , [( 'Content-Type' , 'text/html' )]) return "<h1> Tap! </h1>" def app_factory(global_config, in_arg): return Tap(in_arg) |
app_factory是tap对应的处理方法,返回时调用了Tap方法,Tap对应的是类Tap的__call__方法,在该方法中打印一个"Tap",然后发送报文头,最后返回一个字符串。
shower.py
1 2 3 4 5 6 7 8 9 10 11 | class Shower( object ): def __init__(self, in_arg): self.in_arg = in_arg def __call__(self, environ, start_response): print 'Shower' start_response( '200 ok' , [( 'Content Type' , 'text/html' )]) return "<h1> Shower! </h1>" def app_factory(global_config, in_arg): return Shower(in_arg) |
shower的分析同上
boiler.py
1 2 3 4 5 6 7 8 9 | class Boiler( object ): def __init__(self, app, in_arg): self.app = app self.in_arg = in_arg def __call__(self, environ, start_response): print 'Boiler' return self.app(environ, start_response) def filter_app_factory(app, global_config, in_arg): return Boiler(app, in_arg) |
filter_app_factory是boiler对应的处理方法,其中传入的参数中有一个app,返回时调用了Boiler,并传入参数app。
Boiler是类Boiler的__call__方法,首先打印了字符串"Boiler",然后返回时调用了函数app。这个app具体到本例就是调用了shower
所有的文件都准备齐全了,接下来开启WSGI服务,让程序跑起来。
server.py
1 2 3 4 5 6 7 8 9 10 11 12 | from wsgiref.simple_server import make_server from paste import httpserver from paste.deploy import loadapp import os if __name__ == '__main__' : configfile = 'configure.ini' #定义配置文件 appname = 'main' #composite的名称 wsgi_app = loadapp( 'config:%s' % os.path.abspath(configfile), appname) #载入配置文件 print "start the server listening on 8080" server = make_server( '0.0.0.0' , 8080, wsgi_app) server.serve_forever() |
运行server程序。
在浏览器中请求URL http://[ip ]:8080/main/tap
在浏览器中请求URL http://[ip ]:8080/main/boiler/shower
小结:
使用PasteDeploy模块将URL解析从判断的方式转变到文件配置的方式。
使用configuer.ini文件配置了URL /main/tap 对应处理函数 app_factory和/main/boiler/shower 对应处理函数 shower.py中的app_factory。
本篇主要讲的是使用PasteDeploy模块去配置WSGI解析URL。在openstack源码中就是基于这样的模型去完成restful 的解析,处理等。当一条restful的请求如:http://192.168.252.177:5000/v2.0/token
到达服务器时,服务器处理的流程就是如上,通过配置文件查找URL处理函数,然后调用处理函数返回处理结果。
通过对简单模型的掌握,便于理解后续的复杂的内容。
本篇博文参考:http://blog.csdn.net/li_101357/article/details/52755367
__EOF__

本文链接:https://www.cnblogs.com/goldsunshine/p/7756153.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理