使用mod_wsgi(三)


昨天使用mod_wsgi新增一个web项目,因此想在conf中新增虚拟环境解释器、路由等配置,结论是在一个conf中增加多个Python虚拟环境是无法成功的。

原因是一个服务一个时间只能运行一个Python解释器,numpy等三方库是C语言编写的,基于Cpython,受限于GIL必须等待。而另一个服务一直在运行,所以它将永远等待。

也可能numpy是这个项目独有的,其他包实际引用了前一个项目的site-packages;服务永远在等待引用这个项目的的numpy;因此即便成功也是虚幻的。

解决方案是建立两个服务,这样必须让Apache监听另一个端口。显然两个服务不能监听一个端口,这和Nginx依靠路由分发差别很大。

进入D:\Apache24\bin>, 执行命令:httpd.exe -k install -n "Apache2.4_port8888" -f "F:\fr_dms\httpd_port8888.conf",使用指定的配置文件,新增了一个服务副本Apache2.4_port8888。

这个指定的配置文件根据需要更改即可,端口号不能和其他项目冲突。

核心示例:


    Require all granted


LoadFile "D:/Python38/python38.dll"
LoadModule wsgi_module "F:/fr_dms/env/lib/site-packages/mod_wsgi/server/mod_wsgi.cp38-win_amd64.pyd"
WSGIPythonHome "F:/fr_dms/env"

WSGIScriptAlias /dms F:/fr_dms/fr_dms.wsgi

说明最后一行:

WSGIScriptAlias /dms F:/fr_dms/fr_dms.wsgi

关于路由配置,前一个路径是根路由,这个简直了,平常我们都以为根就是/,没想到Apache不这样理解,它让用户设置根。比如上面的/dms,当访问 域名:端口/dms域名:端口/dms/other 时,等同于调用wsgi文件 F:/fr_dms/fr_dms.wsgi,这就是/dms变成了根路由;当访问 域名:端口/other 的时候,会失败。这种情况下,如果使用Flask,标记路由则需要用@app.route('/other'),而不是@app.route('/dms/other'),因为/dms是根。

因为没get到Apache/mod_wsgi的这一设计,白白耗费很多脑细胞。

当然,Apache的设计肯定是源于他们团队聪明的考虑,我们必须好好学习和理解;比如服务副本,可以让新项目的启/停完全不影响其他项目。

此外,可以确定的是:WSGIPythonHome "F:/fr_dms/env",将在sys.path中新增路径:F:\fr_dms\env\Lib\site-packages

如果在一个conf文件中写了两个,虚拟环境之间必然会互相影响。

 --------------------------

13:00

上面的努力没有解决问题,之前以为是成功的,是因为另一个奇怪的事情:我没有更新为8888端口访问,而是用默认的80端口,成功了;发现了之后改为8888失败,接着80也失败。

在 F:\fr_dms\httpd_port8888.conf 中加上指令 WSGIApplicationGroup %{GLOBAL},解决了问题。

可以参阅这三个链接:

https://blog.csdn.net/zizle_lin/article/details/105686786

https://blog.csdn.net/weixin_43323146/article/details/115001483

https://modwsgi.readthedocs.io/en/master/configuration-directives/WSGIApplicationGroup.html?highlight=wsgiapplicationgroup#wsgiapplicationgroup

这个指令在单独的服务副本中,希望不会对别的项目有影响;如果不行,按上面的链接,可以将 import numpy as np 放在需要 np 的函数中。我不想再继续研究了,需要linux/nginx