- Jun 2018
-
blog.csdn.net blog.csdn.net
-
RoutesMiddleware将HTTP的URL请求应声到相应WSGI函数,并且将路由匹配结果存到environ环境变量中去
RoutesMiddleware 主要作用:
- 将HTTP的URL请求映射到相应WSGI函数
- 讲路由匹配结果存到environ环境变量中
-
- May 2018
-
wsfdl.com wsfdl.com
-
Fanout: 相当于广播,producer 可把消息发送给多个 consumer,属于异步调用范畴,如下图
-
Cast: 异步调用,producer 发送消息后继续执行后续步骤,consumer 接收处理消息,如下图。
-
Call: 同步调用,但过程稍微复杂,producer 发送消息后立刻创建一个 direct consumer, 该 direct consumer 阻塞于接收返回值。对端的 consumer 接收并处理 producer 的消息后,创建一个 direct producer,它负责把处理结果发送给 direct consumer
-
AMQP 是应用层协议,它在 client 和 server 端引入了消息中间件,解耦了 client 和 server 端,支持大规模下的消息通信
AMQP 引入了消息中间件
从RPC角度来看,Client端要远程调用Server端的函数
从AMQP角度来看,Client要发起请求,产生请求消息,所以是Producer,Server端需要获取消息消费,才能进行相应的处理,所以是Consumer
-
-
Local file Local file
-
你可以使用传入type=的方式来使用Opt类,或者直接使用其对应类型的子类例如StrOpt类,如果配置项值无法解析成对应类型,将会抛出一个ValueError错误
common_opts = [ cfg.Opt( 'bind_port', type=PortType, default=9292, help='Port number to listen') ] ### 等价于 common_opts = [ cfg.PortOpt( 'bind_port', default=9292, help='Port number to listen') ]
-
-
blog.csdn.net blog.csdn.net
-
最后一种使用插件的方式,相当于Drivers加载和Extensions加载的结合。它允许在给定的entry points组名下有同名的entry point,这样,在给定entry points组名和entry point名的情况下,hook式加载会加载所有找到的插件。
Hook式加载
-
ExtensionManager和DriverManager略有不同,它不需要提前知道要加载哪个插件,它会加载所有找到的插件。 要想调用插件,需要使用map方法,需要传给map一个函数,这里就是format_data函数,针对每个扩展都会调用该函数。format_data函数有两个参数,分别是Extension实例和map的第二个参数da
不需要知道插件的具体名字,指定namespace='xxxx',则会加载xxxx entry point group下的所有插件(扩展)
要调用插件 ==> manager.map(func, args) ==> namespace中的每个插件都会调用该函数func ==> manager.map(func, args) return 一个序列,序列中的每个元素就是每个插件调用回调函数的返回值
-
定义并注册插件
注册插件是通过 setup.py 来注册插件的
from setuptools import setup, find_packages setup( name='test', version='1.0', packages=find_packages(), entry_points={ 'namespace': [ 'name = module:importable' ], }, )
-
在stevedore中,有三种使用插件的方式:Drivers、Hooks、Extensions
Drivers:一个名字对应一个entry point
Hooks:一个名字对应多个entry point
Extensions:多个名字对应多个entry point
Tags
Annotators
URL
-
-
blog.csdn.net blog.csdn.net
-
根据每个插件在entry point中名字和具体实现的数量之间的对应关系不同,stevedore提供了多种不同的类来帮助开发者发现和载入插件,如下图所示:
-
示例中显示了两个不同的entry points的命名空间,“ceilometer.compute.virt"和"ceilometer.hardware.inspectors",分别注册有3个和1个插件.每个插件都符合"名字=模块:可导入对象”的格式,在“ceilometer.compute.virt"命名空间里的libvirt插件,它的具体可载入的实现是ceilometer.compute.virt.libvirt.inspector模块中的LibvirtInspector类.
ceilometer.compute.virt = libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector hyperv = ceilometer.compute.virt.hyperv.inspector:HyperVInspector vsphere = ceilometer.compute.virt.vmware.inspector:VsphereInspector ceilometer.hardware.inspectors = snmp = ceilometer.hardware.inspectors.snmp:SNMPInspector
- ceilometer.compute.virt 和 ceilometer.hardware.inspectors是两个命名空间
- ceilometer.compute.virt 有 libvirt,hyperv,vsphere 三个插件,ceilometer.hardware.inspectors 有 snmp 一个插件
- 插件的具体可载入实现是每个插件等号后面的具体类
-
-
routes.readthedocs.io routes.readthedocs.io
-
Note Due to how Routes matches a list of URL’s, it has no inherent knowledge of a route being a resource. As such, if a route fails to match due to the method requirements not being met, a 404 will return just like any other failure to match a route.
注意:由于路由与URL的列表相匹配,它不具有作为资源的路由的固有知识,因此,如果由于未满足方法要求而导致路由不匹配,则404将像任何其他路由失败一样返回以匹配路由。
Tags
Annotators
URL
-
-
routes.readthedocs.io routes.readthedocs.io
-
A static route is used only for generation – not matching – and it must be named. To define a static route, use the argument _static=True.
静态路由仅用于URL生成,不会用于匹配,并且必须命名。使用参数
_static=True
来定义静态路由 -
However, if the route defines an extra variable with the same name as a path variable, the extra variable is used as the default if that keyword is not specified.
但是,如果路由定义了一个额外变量和 url() 的路径变量名称相同,如果未指定该关键字,那么额外变量将用 作默认值
### id 作为额外参数 m.connect("archives", "/archives/{id}", controller="archives", action="view", id=1) ### id作为路径参数 url("archives", id=123) => "/archives/123" url("archives") => "/archives/1"
-
url("blog", year=2008, month=10, day=2)
如果路由包含path variables(路径变量),则必须使用关键字参数设置这些变量值:
-
url("home") => "/"
要生成一个带名字的路由,指定路由名作为位置参数
Tags
Annotators
URL
-
-
routes.readthedocs.io routes.readthedocs.io
-
If the “path_info” variable is used at the end of the URL, Routes moves everything preceding it into the “SCRIPT_NAME” environment variable. This is useful when delegating to another WSGI application that does its own routing: the subapplication will route on the remainder of the URL rather than the entire URL. You still need the ”:.*” requirement to capture the following URL components into the variable.
如果在URL的末尾使用“path_info”变量,则Routes会将其前面的所有内容移动到“SCRIPT_NAME”环境变量中。
当委派另一个WSGI应用程序执行自己的路由时,这非常有用:子应用程序将路由剩余的URL而不是整个URL。
您仍需要“:.*” requirement 才能将以下URL组件捕获到变量中。
map.connect(None, "/cards/{path_info:.*}", controller="main", action="cards") # Incoming URL "/cards/diamonds/4.png" => {"controller": "main", action: "cards", "path_info": "/diamonds/4.png"} # Second WSGI application sees: # SCRIPT_NAME="/cards" # PATH_INFO="/diamonds/4.png"
-
map.connect(None, "/error/{action}/{id}", controller="error")
Mapper在Web应用程序中处理URL生成和URL识别。
Mapper是建立处理字典的。 假定Web应用程序将处理返回由URL识别并正确分派的字典。
通过将关键字参数传递到生成函数来完成URL生成,然后返回一个URL。
class Mapper(SubMapperParent): def __init__(self, controller_scan=controller_scan, directory=None, always_scan=False, register=True, explicit=True): ### Create and connect a new ### Route to the Mapper def connect(self, routename, path=None, **kwargs): ........
Tags
Annotators
URL
-
-
www.nfvschool.cn www.nfvschool.cn
-
app_iter = myfunc(environ, start_response) resp = myfunc(req)
With that myfunc will be a WSGI application, callable like
app_iter = myfunc(environ, start_response).
You can also call it like normal
resp = myfunc(req)
You can also wrap methods
def myfunc(self, req).)
-
@wsgify def myfunc(req): return webob.Response('hey there')
不添加装饰器,打印type(myfunc)
<type 'function'>
添加装饰器之后,打印type(myfunc)
<class 'webob.dec.wsgify'>
-
>>> from webob import Request >>> environ = {'wsgi.url_scheme': 'http', ...} >>> req = Request(environ)
### environ 是 WSGI环境变量 req = Request(environ) 把 environ 字典 转换成 <class 'webob.request.Request'> Request对象 所以 webob.Request是对WSGI环境变量的一个封装
-
-
wsfdl.com wsfdl.com
-
@classmethod def factory(cls, global_conf, **kwargs): return cls()
class AnimalApplication(object): @classmethod def factory(cls, global_conf, **kwargs): print cls return cls() <class '__main__.AnimalApplication'> ==> cls 指的是类本身
-
eventlet: python 的高并发网络库 paste.deploy: 用于发现和配置 WSGI application 和 server 的库 routes: 处理 http url mapping 的库
WSGI框架下一些常用的 python module
- eventlet
- paste.deploy
- routes
-
-
wsfdl.com wsfdl.com
-
Middleware 处于 server/gateway 和 application/framework 之间,对 server/gateway 来说,它相当于 application/framework;对 application/framework 来说,它相当于 server/gateway。每个 middleware 实现不同的功能,我们通常根据需求选择相应的 middleware 并组合起来,实现所需的功能
比如,可在 middleware 中实现以下功能:
- 根据 url 把用户请求调度到不同的 application 中。
- 负载均衡,转发用户请求
- 预处理 XSL 等相关数据
- 限制请求速率,设置白名单
middleware 介于 sever/gateway 和 application/framework 之间 该怎么理解
- 简单考虑,没有middleware时,创建server时指定application,请求发生时,调用application
- 那么有middleware是什么情况呢?middleware接收application作为入参,这样就把middleware和application这一端连接起来,对于application来说,middleware就像server一样,middleware把application执行结果返回给server,对于server来说,middleware就像application一样
-
Callable object 必须满足以下两个条件:
- 接受两个参数:字典dict (environ),回调函数(start_response,返回 HTTP status, headers 给 web server)
- 返回一个可以迭代的值
-
PEP 0333 – Python Web Server Gateway Interface 是一种 web server or gateway 和 python web application or framework 之间简单通用的接口,符合这种接口的 application 可运行在所有符合该接口的 server 上
WSGI -- web server gateway interface
是一种 web server/gateway 和 python web application/framework 之间的通用接口
符合这种接口的application,都可以运行在符合该接口的server上
application <==> web server gateway interface <==> server
-
a proposed standard interface between web servers and Python web applications or frameworks
WSGI -- a interface of python web applications or frameworks
Tags
Annotators
URL
-