perl - 为什么带有 uwsgi_psgi 的 Perlbrew PSGI 应用程序会导致 "wrong"Perl 包含路径?

标签 perl uwsgi dancer perlbrew psgi

我想使用 uWSGI 网关接口(interface)部署基于 PSGI 的 Web 应用程序。

为了实现此目的,我在没有 root 访问权限的 Debian 服务器上本地安装了 Perlbrew。

perlbrew init
# close shell and reopen new shell
perlbrew self-install
# close shell and reopen new shell
perlbrew self-upgrade
# close shell and reopen new shell
perlbrew install-patchperl
perlbrew install-cpanm
# close shell and reopen new shell
perlbrew install -j 10 perl-5.26.1
perlbrew lib create perl-5.26.1@main
perlbrew switch perl-5.26.1@main
# close shell and reopen new shell

然后我使用 cpanm -V 检查了 Perl 环境:

cpanm (App::cpanminus) version 1.7043 (/home/soeren/perl5/perlbrew/bin/cpanm)
perl version 5.026001 (/home/soeren/perl5/perlbrew/perls/perl-5.26.1/bin/perl)

  %Config:
    archname=x86_64-linux
    installsitelib=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1
    installsitebin=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/bin
    installman1dir=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/man/man1
    installman3dir=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/man/man3
    sitearchexp=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1/x86_64-linux
    sitelibexp=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1
    archlibexp=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/5.26.1/x86_64-linux
    privlibexp=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/5.26.1
  %ENV:
    PERL5LIB=/home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5
    PERLBREW_HOME=/home/soeren/.perlbrew
    PERLBREW_LIB=main
    PERLBREW_MANPATH=/home/soeren/.perlbrew/libs/perl-5.26.1@main/man:/home/soeren/perl5/perlbrew/perls/perl-5.26.1/man
    PERLBREW_PATH=/home/soeren/.perlbrew/libs/perl-5.26.1@main/bin:/home/soeren/perl5/perlbrew/bin:/home/soeren/perl5/perlbrew/perls/perl-5.26.1/bin
    PERLBREW_PERL=perl-5.26.1
    PERLBREW_ROOT=/home/soeren/perl5/perlbrew
    PERLBREW_SHELLRC_VERSION=0.82
    PERLBREW_VERSION=0.82
    PERL_LOCAL_LIB_ROOT=/home/soeren/.perlbrew/libs/perl-5.26.1@main
    PERL_MB_OPT=--install_base /home/soeren/.perlbrew/libs/perl-5.26.1@main
    PERL_MM_OPT=INSTALL_BASE=/home/soeren/.perlbrew/libs/perl-5.26.1@main
  @INC:
    FatPacked::93953009226544=HASH(0x557323bd9330)
    /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux
    /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5
    /home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1/x86_64-linux
    /home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1
    /home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/5.26.1/x86_64-linux
    /home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/5.26.1

一切看起来都不错,因此我安装了 Dancer2 作为选择的 Web 框架,并成功启动了框架测试应用程序:

dancer2 gen --application DemoApp
cd ./DemoApp
plackup ./bin/app.psgi

Plack 内部 HTTP Web 服务器已启动并准备好为应用程序提供服务。

再说一次,到目前为止一切都很好。但我想使用 uWSGI,而不是在服务链中拥有另一个成熟的 Web 服务器。

所以我安装了uwsgi-plugin-psgi,它自动随uwsgi-core一起提供:

apt install uwsgi-plugin-psgi

现在我想启动uWSGI网关接口(interface)...:

uwsgi_psgi --uwsgi-socket 127.0.0.1:5999 --psgi /home/soeren/DemoApp/bin/app.psgi

...应用程序崩溃了:

[uwsgi] implicit plugin requested psgi
*** Starting uWSGI 2.0.14-debian (64bit) on [Fri Feb  9 10:41:20 2018] ***
compiled with version: 6.2.1 20161124 on 07 December 2016 16:14:59
os: Linux-4.9.0-5-amd64 #1 SMP Debian 4.9.65-3+deb9u2 (2018-01-04)
nodename: skde-deu-02.sklink.de
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 8
current working directory: /home/soeren/DemoApp
detected binary path: /usr/bin/uwsgi-core
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 256817
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address 127.0.0.1:5999 fd 3
initialized Perl 5.24.1 main interpreter at 0x557337c6fd40
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 72768 bytes (71 KB) for 1 cores
*** Operational MODE: single process ***
Error while loading /home/soeren/DemoApp/bin/app.psgi: Can't locate WWW/Form/UrlEncoded.pm in @INC (you may need to install the WWW::Form::UrlEncoded module) (@INC contains: /home/soeren/DemoApp/bin/../lib /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/5.24.1/x86_64-linux-gnu-thread-multi /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/5.24.1 /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux-gnu-thread-multi /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5 /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.24.1 /usr/local/share/perl/5.24.1 /usr/lib/x86_64-linux-gnu/perl5/5.24 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.24 /usr/share/perl/5.24 /usr/local/lib/site_perl) at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/HTTP/Entity/Parser/UrlEncoded.pm line 5.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/HTTP/Entity/Parser/UrlEncoded.pm line 5.
Compilation failed in require at /usr/share/perl/5.24/Module/Load.pm line 77.
Can't locate HTTP/Entity/Parser/UrlEncoded in @INC (@INC contains: /home/soeren/DemoApp/bin/../lib /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/5.24.1/x86_64-linux-gnu-thread-multi /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/5.24.1 /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux-gnu-thread-multi /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5 /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.24.1 /usr/local/share/perl/5.24.1 /usr/lib/x86_64-linux-gnu/perl5/5.24 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.24 /usr/share/perl/5.24 /usr/local/lib/site_perl) at /usr/share/perl/5.24/Module/Load.pm line 77.
Compilation failed in require at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Plack/Request.pm line 17.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Plack/Request.pm line 17.
Compilation failed in require at /usr/share/perl/5.24/parent.pm line 16.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2/Core/Request.pm line 6.
Compilation failed in require at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2/Core/App.pm line 29.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2/Core/App.pm line 29.
Compilation failed in require at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2.pm line 11.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2.pm line 11.
Compilation failed in require at /home/soeren/DemoApp/bin/../lib/DemoApp.pm line 2.
BEGIN failed--compilation aborted at /home/soeren/DemoApp/bin/../lib/DemoApp.pm line 2.
Compilation failed in require at /home/soeren/DemoApp/bin/app.psgi line 10.
BEGIN failed--compilation aborted at /home/soeren/DemoApp/bin/app.psgi line 10.
unable to find PSGI function entry point.
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (and the only) (pid: 9769, cores: 1)

我首先看到的是架构。虽然其他(cpnamplackup)程序使用“x86_64-linux”架构,但只有 uWSGI 使用“x86_64-linux-gnu-thread-multi”。

“x86_64-linux-gnu-thread-multi”的 Perl 架构文件夹可用,但不包含任何模块。大多数模块安装在“根库路径”和“x86_64-linux”架构文件夹中。

/home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5
/home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux

我尝试使用 uwsgi_psgi 命令行开关 --perl-local-lib 来解决这个问题,但没有成功:

uwsgi_psgi --uwsgi-socket 127.0.0.1:5999 --psgi /home/soeren/DemoApp/bin/app.psgi --perl-local-lib /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5
uwsgi_psgi --uwsgi-socket 127.0.0.1:5999 --psgi /home/soeren/DemoApp/bin/app.psgi --perl-local-lib /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux

我也尝试过不同的uWSGI操作模式(单进程、预 fork 、线程),但也没有运气。

为什么 uWSGI 修改包含路径以及如何启动 uWSGI 以便它像其他程序一样工作或另外安装该架构的模块?

最佳答案

感谢@simbabque,我找到了解决方案。

我的问题是我使用的是系统 native uwsgi_psgi,它是与系统 Perl 安装一起编译的,与我本地的 Perlbrew 安装不兼容。

这个mailing list thread建议在 Perlbrew 范围内重新编译 uwsgi 以便能够(仅)与本地 Perlbrew 安装一起使用。

因此,通过执行以下编译,我可以启动 Perl 应用程序:

curl http://uwsgi.it/install | bash -s psgi /home/soeren/perl5/perlbrew/bin/uwsgi

但是上面显示的命令不是最好的方法,因为它缺少所有进一步重要的编译开关(例如 pcre、jit)。

随着时间的推移,我将通过进一步的编译开关改进这个答案。

关于perl - 为什么带有 uwsgi_psgi 的 Perlbrew PSGI 应用程序会导致 "wrong"Perl 包含路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48703042/

相关文章:

linux - 使用正则表达式对文件运行 awk

bash - Exec没有替换Docker入口点脚本中的bash shell

python - 将信息从一个 uwsgi 请求传递到另一个请求?

Python CGI 脚本在 uWSGI 试图读取 sys.stdin 时挂起

template-toolkit - 有没有办法将变量绑定(bind)到模板工具包模板?

Perl One-liner if else逻辑

perl - Mojolicious 响应缓存?

regex - Perl:显示正则表达式,不匹配

html - Perl 中可扩展的类似 Markdown 的模块?

mysql - DBIx::新建和创建类错误