问题:.so(共享对象)作为python中的库,当python
调用它时运行良好,并且在运行uWSGI的python(Django)应用程序中失败。
更多信息:我用go build -buildmode=c-shared -o output.so input.go
构建Go模块,用Python调用它
from ctypes import cdll
lib = cdll.LoadLibrary('path_to_library/output.so')
当通过uWSGI提供django项目时,调用Go库的请求处理程序冻结,导致Nginx中的未来504。在进入“所谓的冻结”之后,uWSGI被锁定在那里,只有重新启动才能使应用程序活跃起来。没有记录全部!它冻结了。
当我在同一台机器上运行python解释器时,一切正常。
我的想法:我已经尝试调试这个并在库中放入了很多日志消息,但它不会提供太多信息,因为一切都很好用于库(因为它在解释器中工作)。库正确加载,因为我在库中放置了一些日志消息。我认为这是某种uWSGI限制。我不认为把uwsgi.ini文件放在某种程度上有帮助。
fmt
github.com/360EntSecGroup-Skylar/excelize
log
encoding/json
uWSGI在这种类型的共享对象工作中有什么限制,有没有办法克服它们?
首先,你是否绝对肯定你需要从UWSGI流程调用Go作为库?
uWSGI通常用于解释语言,如PHP,Python,Ruby等。它引导解释器并管理主/工作进程以处理请求。在Go库上使用它似乎很奇怪。
您提到将nginx作为您的网络服务器,为什么不直接使用您的Go程序作为http服务器(它做得很好)并使用它的URL直接从nginx调用它:
location /name/ {
proxy_pass http://127.0.0.1/go_url/;
}
如果你真的想通过.so模块使用Go作为python导入的库,你必须要知道Go有自己的运行时,线程管理,并且可能不能很好地处理以不同方式处理线程/进程的uWSGI。在这种情况下,我无法帮助你,因为我从未尝试过这个。
如果你能用你真正想要做的事情澄清你的问题,我们可以帮助你更有帮助。
我试图避免将共享库与我的python代码分离,因为它需要至少一个进程的支持,我将不得不重写一些库来创建新的api。
正如@Lu.nemec所指出:
Go有自己的运行时,线程管理,可能不适用于以不同方式处理线程/进程的uWSGI
由于uWSGI是问题,我开始寻求解决方案。其中一个希望是安装GCCGO uWSGI plugin以某种方式解决这个问题。但即使很难安装在旧操作系统上,因为它缺乏预先构建的插件,手动编译也不是很好,它没有帮助,没有任何改变,它仍然冻结。
然后我想我不会禁用协同程序和那种与uWSGI不同的东西,我能做的其中一个变化是设置GOMAXPROCS
GOMAXPROCS
设置可以同时执行的最大CPU数并返回先前的设置。如果n <1,则不会更改当前设置。可以使用NumCPU查询本地计算机上的逻辑CPU数。当调度程序改进时,此调用将消失。
它就像一个魅力!
import (
...
"runtime"
)
...
//export yourFunc
func yourFunc(yourArgs argType) {
runtime.GOMAXPROCS(1)
...
}
我的previous answer在某些情况下有效。但是,当我试图在具有相同操作系统,相同Python,相同uWSGI(版本,插件,配置文件),相同要求,相同.so文件的另一台服务器上运行相同项目时,它冻结了我在回答中描述的保存方式。
我个人不希望将其作为单独的进程运行并将其绑定到套接字/端口并创建用于与共享库通信的API。
只需要单独的过程。与celery
一起运行。
1.你不能用task.apply()
运行任务,因为它将在主应用程序中运行,而不是在celery
中运行:
result = task.apply_async()
while result.ready():
time.wait(5)
你需要用celery
执行池运行solo
celery -A app worker -P solo