使用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