uwsgi 到底是个啥东西

2020-05-11 20:01:15 +08:00
 lttzzlll
uwsgi 作为一个 web server, 可以用来部署符合 WSGI 规范的客户端代码。
我想知道, uwsgi 是 c 写的, 而业务代码是 python,它是怎么调用|执行 python 代码的?
uwsgi 到底是如何干这件事情的?

1.如果 uwsgi 可以直接执行 python 的代码,那么他不就是一个 python 的解释器了吗?
2.如果 uwsig 通过(python)插件机制,将 python"嵌"入自己的内部,来间接执行 python 的代码? 如果是这种情况, 他嵌入的"python 插件"还是一个完整意义上的 python 程序吗? 或者是说,它是怎么"嵌入的"?
另外,这种方式是否把 uwsgi+python 插件+ 业务端的 python 代码的 python 版本绑定了呢? 即一个旧版本的 uwsgi 是如何执行业务端最新版本的 python 代码呢?


大家谁比较懂 uwsgi,可以解惑一下呢.
4115 次点击
所在节点    Python
16 条回复
tempdban
2020-05-11 21:28:53 +08:00
此时是不是应该去看看 wsgi 规范
kwoktung
2020-05-11 21:37:03 +08:00
我也好奇。蹲个答案。
fgwmlhdkkkw
2020-05-11 21:59:46 +08:00
实现了 uwsgi 协议的 nginx 。
fgwmlhdkkkw
2020-05-11 22:01:21 +08:00
@fgwmlhdkkkw uwsgi 将 http 协议转换为 uwsgi 协议,然后转发给 wsgi 程序。
WispZhan
2020-05-11 22:05:12 +08:00
几周、几个月或多年后,你回过头来,再来看这个帖子,会发现“原来当年我问过这么蠢的问题”。
jimmyismagic
2020-05-11 22:18:40 +08:00
关注这个问题,我想听到最准确的答案,像 java,tomcat 都是 java 程序,为什么 uwsgi 不是呢?
bwangel
2020-05-11 22:40:02 +08:00
Python 有个东西叫做 C-API,https://docs.python.org/3/c-api/index.html,让开发者可以用 C 代码来访问 Python 解释器内部,这样就可以用 C 来获取 Python 中的对象,执行 Python 中定义的函数函数等。


1. uwsgi 中并没有集成一个 Python 虚拟机,它只是调用了 Python 提供的 C 接口,启动后在内存中创建了 Python 虚拟机实例。

# 初始化 Python 实例的位置

https://github.com/unbit/uwsgi/blob/11ca00432176f4246881870ea6c7c4ea5a26481f/plugins/python/python_plugin.c#L302

分析 uwsgi 依赖的动态库,可以看到它是依赖 Python 的。

ø> otool -L `which uwsgi` 22:29:40 (05-11)
/usr/local/bin/uwsgi:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.50.2)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
/usr/local/opt/pcre/lib/libpcre.1.dylib (compatibility version 4.0.0, current version 4.8.0)
/usr/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.9.0)
/usr/lib/libicucore.A.dylib (compatibility version 1.0.0, current version 57.1.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1349.8.0)
/usr/local/opt/python3/Frameworks/Python.framework/Versions/3.6/Python (compatibility version 3.6.0, current version 3.6.0)


2. uwsgi 启动后会将 wsgi App 对象(例如 flask 的 app 对象)加载到内存中。然后每次请求到来后,调用 wsgi App 对象来处理请求。

# 加载 wsgi app 对象的位置

https://github.com/unbit/uwsgi/blob/58c920bf96b86450f88d02a1df9043e754550483/plugins/python/pyloader.c#L194
bwangel
2020-05-11 22:41:41 +08:00
搜一下 “uwsgi 源码分析”,有挺多讲 uwsgi 实现的文章的。
youngce
2020-05-11 22:49:19 +08:00
uwsgi 甚至提供了对遵守 WSGI 协议的其它语言的 web 支持。。。虽然我觉得应该没人用:)
crella
2020-05-11 23:28:42 +08:00
官网文档:
Request plugins (implement application server interfaces for various languages and platforms: WSGI, PSGI, Rack, Lua WSAPI, CGI, PHP, Go …)
crella
2020-05-12 00:00:02 +08:00
哈哈,作为一个完全没用过 flask 或 django 的菜鸟,我说一下我的看法。

首先,文档提到 uWSGI 用插件来支持多种语言。这样的话,要么用本机 socket 与各个语言的运行时通信,要么把那个语言的运行时嵌入到自己的运行空间中。

第二,参考 uWSGI 的启动命令,发现仅需指定插件编号,而不用指定对应语言运行时的 socket,所以应该不是通过 socket 通信


第三,uWSGI 的 perl 与 ruby 文档都提到要用到 c 编译器和 libperl-dev 或者 ruby-dev 。在 linux 上编译过一些小型软件的就知道这是什么回事了。
lis66951735
2020-05-12 00:11:37 +08:00
wsgi 类比 servlet,uwsgi 类比 tomcat
CzaOrz
2020-05-12 08:44:13 +08:00
个人理解:

flask 和 django 都是基于 WSGI 标准搭建的 web 应用框架。
可把整个服务端响应流程分为:
>>> socket 监听端口
>>> 接收 http 请求报文
>>> 解析请求报文并将其打包为 wsgi 标准,从代码层面看,就是整理出了两个参数,分别为 environ 和 start_response
>>> web 应用层调用 environ 和 start_response 实现业务逻辑和响应报文

uwsgi 本质不是为了执行 python,他是配合了 nginx,python 来实现了上述流程,提高吞吐量。
nginx 监听并转发请求 -> uwsgi 将请求打包 -> python 实现业务逻辑
luobo
2020-05-12 09:15:05 +08:00
#!/usr/bin/python

print("hello,world!")
smallpython
2020-05-13 14:01:45 +08:00
就好像 python 也可以调用 c 代码中的函数一样, 应该是可以互相调用的吧.

wsgi 是一个协议, 如果都遵守这个协议, 无论版本新旧都没关系吧
smallpython
2020-05-13 14:03:41 +08:00
不过还是推荐用 gunicorn, 纯 python 的更好理解, 万一有什么不符合系统要求的地方还能直接改里面的代码

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/670687

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX