使用 CherryPy/Cherryd 启动多个 Flask 实例
根据 SO/SF 和其他网站上的建议,我使用 CherryPy 作为 WSGI 服务器来启动我用 Flask 构建的 Python Web 服务器的多个实例。每个实例都在自己的端口上运行并位于 Nginx 后面。我应该指出,下面的内容确实对我有用,但我很困扰,因为我以错误的方式处理事情,而且它“偶然”起作用。
这是我当前的cherrypy.conf 文件:
[global]
server.socket_host = '0.0.0.0'
server.socket_port = 8891
request.dispatch: cherrypy.dispatch.MethodDispatcher()
tree.mount = {'/':my_flask_server.app}
无需深入了解我的 Flask 服务器,以下是它的启动方式:
import flask
app = flask.Flask(__name__)
@app.route('/')
def hello_world():
return "hello"
这是我在命令行上发出的使用 Cherryd 启动的命令:
cherryd -c cherrypy.conf -i my_flask_server
问题是:
- < p>将 Flask 包装在 CherryPy 中仍然是在生产中使用 Flask 的首选方法吗? https://stackoverflow.com/questions/4884541/cherrypy-vs-flask-werkzeug< /p>
- < p>这是使用 .conf 文件启动 CherryPy 并导入 Flask 应用程序的正确方法吗?我已经搜索了 CherryPy 文档,但找不到任何与我在此处具体尝试执行的操作相匹配的用例。
在单台计算机上启动多个 CherryPy/Flask 实例以执行多个cherryd 命令(使用 -d 等进行守护进程)以及每个要使用的端口(8891、8892 等)的唯一 .conf 文件的正确方法是吗?或者是否有更好的“CherryPy”方法来实现此目的?
感谢您的任何帮助和见解。
Per suggestions on SO/SF and other sites, I am using CherryPy as the WSGI server to launch multiple instances of a Python web server I built with Flask. Each instance runs on its own port and sits behind Nginx. I should note that the below does work for me, but I'm troubled that I have gone about things the wrong way and it works "by accident".
Here is my current cherrypy.conf file:
[global]
server.socket_host = '0.0.0.0'
server.socket_port = 8891
request.dispatch: cherrypy.dispatch.MethodDispatcher()
tree.mount = {'/':my_flask_server.app}
Without diving too far into my Flask server, here's how it starts:
import flask
app = flask.Flask(__name__)
@app.route('/')
def hello_world():
return "hello"
And here is the command I issue on the command line to launch with Cherryd:
cherryd -c cherrypy.conf -i my_flask_server
Questions are:
Is wrapping Flask inside CherryPy still the preferred method of using Flask in production? https://stackoverflow.com/questions/4884541/cherrypy-vs-flask-werkzeug
Is this the proper way to use a .conf file to launch CherryPy and import the Flask app? I have scoured the CherryPy documentation, but I cannot find any use cases that match what I am trying to do here specifically.
Is the proper way to launch multiple CherryPy/Flask instances on a single machine to execute multiple cherryd commands (daemonizing with -d, etc) with unique .conf files for each port to be used (8891, 8892, etc)? Or is there a better "CherryPy" way to accomplish this?
Thanks for any help and insight.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不能代表 Flask,但我可以代表 CherryPy。这看起来像是“正确的方式”......大多数情况下。关于 MethodDispatcher 的那一行是无操作的,因为它只影响 CherryPy 应用程序,并且您似乎没有安装任何应用程序(只是一个 Flask 应用程序)。
关于第3点,你说得对。 CherryPy 允许您在同一进程中运行多个 Server 对象,以便侦听多个端口(或协议),但它没有任何用于启动多个进程的糖。正如您所说,具有不同配置文件的多个cherryd命令是如何做到这一点的(除非您想使用更集成的集群/配置管理工具,例如 蛋怪)。
I can't speak for Flask, but I can for CherryPy. That looks like the "proper way"...mostly. That line about a MethodDispatcher is a no-op since it only affects CherryPy Applications, and you don't appear to have mounted any (just a single Flask app instead).
Regarding point 3, you have it right. CherryPy allows you to run multiple Server objects in the same process in order to listen on multiple ports (or protocols), but it doesn't have any sugar for starting up multiple processes. As you say, multiple cherryd commands with varying config files is how to do it (unless you want to use a more integrated cluster/config management tool like eggmonster).
术语:安装与嫁接
原则上,这是通过cherrypy提供烧瓶应用程序的正确方法,只是对您的命名进行快速说明:
这里值得注意的是,
tree.mount
不是配置键本身 -tree
将导致使用参数'mount', {'/': my_flask_server.app 调用
。cherrypy._cpconfig._tree_config_handler(k, v)
}_tree_config_handler
根本不使用 key 参数,因此在您的配置中,“mount”只是路径映射的特定字典的任意标签。它也不会“挂载”应用程序(毕竟它不是 CherryPy 应用程序)。我的意思是,它不是cherrypy.tree.mount(…)
,而是cherrypy.tree.graft
是一个任意 WSGI 处理程序到您的“脚本名称”上(路径,但使用 CherryPy 术语)名称空间。Cherrypy 的日志消息有点误导性地说“Mountedon /”]
这是一个很重要的一点,因为与 mount 不同,使用移植时,您无法指定更多选项,例如应用程序的静态文件服务或该路径上的流响应。
因此,我建议将
tree.mount
配置键更改为描述性的内容,这样就不会导致阅读太多有关 CherryPy 中发生的情况的语义(因为cherrypy 中存在 .tree.mount
方法)由于该配置。例如,如果您只是在该字典中映射一个应用程序,则为tree.flask_app_name(可以有许多tree指令,所有这些指令都被合并到路径命名空间中)或tree.wsgi_delegates
如果您在该字典中映射了许多应用程序。使用 CherryPy 提供附加内容而不制作应用程序
另外,如果您希望cherrypy 为您的应用程序提供静态文件服务,则无需创建样板cherrypy 应用程序来保存该配置。您只需使用适当的附加配置安装
None
即可。如果将以下文件放入启动cherryd以提供静态内容的目录中,则足以让CherryPy从子目录“static”提供静态内容(将cherryd调用为cherryd -ccherrypy.conf -i my_flask_server -我静态:static.py
static.conf
Terminology: Mounting vs Grafting
In principle this is a proper way to serve a flask app through cherrypy, just a quick note on your naming:
It is worth noting here that
tree.mount
is not a configuration key by itself -tree
will lead tocherrypy._cpconfig._tree_config_handler(k, v)
being called with the arguments'mount', {'/': my_flask_server.app}
.The key parameter is not used at all by the
_tree_config_handler
so in your config "mount" is just an arbitrary label for that specific dict of path mappings. It also does not "mount" the application (it's not a CherryPy app after all). By that I mean, it does notcherrypy.tree.mount(…)
it but rathercherrypy.tree.graft
s an arbitrary WSGI handler onto your "script-name" (paths, but in CherryPy terminology) namespace.Cherrypy's log message somewhat misleadingly says "Mounted <app as string> on /"]
This is a somewhat important point since with graft, unlike mount, you cannot specify further options such as static file service for your app or streaming responses on that path.
So I would recommend changing the
tree.mount
config key to something descriptive that does not invite reading too much semantics about what happens within CherryPy (since there is thecherrypy.tree.mount
method) due to that config. E.g.,tree.flask_app_name
if you're just mapping that one app in that dict (there can be manytree
directives, all of them just getting merged into the paths namespace) ortree.wsgi_delegates
if you map many apps in that dict.Using CherryPy to serve additional content without making an app of it
Another side note, if you want cherrypy to e.g. provide static file service for your app, you don't have to create a boilerplate cherrypy app to hold that configuration. You just have to mount
None
with the appropriate additional config. The following files would suffice to have CherryPy to serve static content from the subdirectory 'static' if they are put into the directory where you launch cherryd to serve static content (invoke cherryd ascherryd -c cherrypy.conf -i my_flask_server -i static
:static.py
static.conf